talks/crypto.koans/index.html

453 lines
98 KiB
HTML
Raw Normal View History

2019-02-21 07:02:59 +00:00
<!DOCTYPE html><html lang="en-US"><head><title>crypto.tls</title><meta property="og:title" content="crypto.tls"><meta charset="UTF-8"><meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0"><meta name="apple-mobile-web-app-capable" content="yes"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta property="og:type" content="website"><meta name="twitter:card" content="summary"><style>@media screen{body,html{background:#000;height:100%;margin:0;overflow:hidden}.bespoke-marp-osc{display:none;opacity:0}.bespoke-marp-parent{bottom:0;left:0;position:absolute;right:0;top:0}.bespoke-marp-parent>.bespoke-marp-osc{background:rgba(0,0,0,.65);border-radius:7px;bottom:50px;color:#fff;display:block;font-family:Helvetica,Arial,sans-serif;font-size:16px;left:50%;line-height:0;opacity:1;padding:12px;position:absolute;touch-action:manipulation;-webkit-transform:translateX(-50%);transform:translateX(-50%);transition:opacity .2s linear;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;z-index:1}.bespoke-marp-parent>.bespoke-marp-osc>*{margin-left:6px}.bespoke-marp-parent>.bespoke-marp-osc>:first-child{margin-left:0}.bespoke-marp-parent>.bespoke-marp-osc>span{opacity:.8}.bespoke-marp-parent>.bespoke-marp-osc>span[data-bespoke-marp-osc=page]{display:inline-block;min-width:140px;text-align:center}.bespoke-marp-parent>.bespoke-marp-osc>button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0;color:inherit;cursor:pointer;font-size:inherit;opacity:.8;outline:none;padding:0;transition:opacity .2s linear;-webkit-tap-highlight-color:transparent}.bespoke-marp-parent>.bespoke-marp-osc>button:disabled{cursor:not-allowed;opacity:.15!important}.bespoke-marp-parent>.bespoke-marp-osc>button:hover{opacity:1}.bespoke-marp-parent>.bespoke-marp-osc>button:hover:active{opacity:.6}.bespoke-marp-parent>.bespoke-marp-osc>button:hover:not(:disabled){transition:none}.bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=prev]{background-size:contain;background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1IiBkPSJNNjggOTBMMjggNTBsNDAtNDAiLz48L3N2Zz4=") no-repeat 50%;height:32px;overflow:hidden;text-indent:100%;white-space:nowrap;width:32px}.bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=next]{background-size:contain;background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1IiBkPSJNMzIgOTBsNDAtNDAtNDAtNDAiLz48L3N2Zz4=") no-repeat 50%;height:32px;overflow:hidden;text-indent:100%;white-space:nowrap;width:32px}.bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=fullscreen]{background-size:contain;background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZGVmcz48c3R5bGU+LmF7ZmlsbDpub25lO3N0cm9rZTojZmZmO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NXB4fTwvc3R5bGU+PC9kZWZzPjxyZWN0IGNsYXNzPSJhIiB4PSIxMCIgeT0iMjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI2MCIgcng9IjUuNjciLz48cGF0aCBjbGFzcz0iYSIgZD0iTTQwIDcwSDIwVjUwbTIwIDBMMjAgNzBtNDAtNDBoMjB2MjBtLTIwIDBsMjAtMjAiLz48L3N2Zz4=") no-repeat 50%;height:32px;overflow:hidden;text-indent:100%;white-space:nowrap;width:32px}.bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=fullscreen].exit{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZGVmcz48c3R5bGU+LmF7ZmlsbDpub25lO3N0cm9rZTojZmZmO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NXB4fTwvc3R5bGU+PC9kZWZzPjxyZWN0IGNsYXNzPSJhIiB4PSIxMCIgeT0iMjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI2MCI
width: 1280px;
height: 720px;
box-sizing: border-box;
overflow: hidden;
position: relative;
scroll-snap-align: center center;
}article#presentation > svg > foreignObject > section::after {
bottom: 0;
content: attr(data-marpit-pagination);
padding: inherit;
pointer-events: none;
position: absolute;
right: 0;
}article#presentation > svg > foreignObject > section:not([data-marpit-pagination])::after {
display: none;
}/* Normalization */article#presentation > svg > foreignObject > section h1 {
font-size: 2em;
margin: 0.67em 0;
}@page {
size: 1280px 720px;
margin: 0;
}@media print {html, body {
background-color: #fff;
margin: 0;
page-break-inside: avoid;
break-inside: avoid-page;
}
article#presentation > svg > foreignObject > section {
page-break-before: always;
break-before: page;
}
article#presentation > svg > foreignObject > section, article#presentation > svg > foreignObject > section * {
-webkit-print-color-adjust: exact !important;
color-adjust: exact !important;
}
article#presentation > svg[data-marpit-svg] {
display: block;
height: 100vh;
width: 100vw;
}
}article#presentation > svg > foreignObject > section svg[data-marp-fitting=svg]{display:block;height:auto;width:100%}@supports (-ms-ime-align:auto){article#presentation > svg > foreignObject > section svg[data-marp-fitting=svg]{position:static}}article#presentation > svg > foreignObject > section svg[data-marp-fitting=svg].__reflow__{content:""}@supports (-ms-ime-align:auto){article#presentation > svg > foreignObject > section svg[data-marp-fitting=svg].__reflow__{position:relative}}article#presentation > svg > foreignObject > section [data-marp-fitting-svg-content]{display:table;white-space:nowrap}article#presentation > svg > foreignObject > section [data-marp-fitting-svg-content-wrap]{white-space:pre}article#presentation > svg > foreignObject > section img[data-marp-twemoji]{background:transparent;height:1em;margin:0 .05em 0 .1em;vertical-align:-.1em;width:1em}/*!
* Marp default theme.
*
* @theme default
*/@font-face{font-family:octicons-link;src:url(data:font/woff;charset=utf-8;base64,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) format("woff")}article#presentation > svg > foreignObject > section .markdown-body .octicon,article#presentation > svg > foreignObject > section .octicon{display:inline-block;fill:currentColor;vertical-align:text-bottom}article#presentation > svg > foreignObject > section .markdown-body .anchor,article#presentation > svg > foreignObject > section .anchor{float:left;line-height:1;margin-left:-20px;padding-right:4px}article#presentation > svg > foreignObject > section .markdown-body .anchor:focus,article#presentation > svg > foreignObject > section .anchor:focus{outline:none}article#presentation > svg > foreignObject > section .markdown-body h1 .octicon-link,article#presentation > svg > foreignObject > section .markdown-body h2 .octicon-link,article#presentation > svg > foreignObject > section .markdown-body h3 .octicon-link,article#presentation > svg > foreignObject > section .markdown-body h4 .octicon-link,article#presentation > svg > foreignObject > section .markdown-body h5 .octicon-link,article#presentation > svg > foreignObject > section .markdown-body h6 .octicon-link,article#presentation > svg > foreignObject > section h1 .octicon-link,article#presentation > svg > foreignObject > section h2 .octicon-link,article#presentation > svg > foreignObject > section h3 .octicon-link,article#presentation > svg > foreignObject > section h4 .octicon-link,article#presentation > svg > foreignObject > section h5 .octicon-link,article#presentation > svg > foreignObject > section h6 .octicon-link{color:#1b1f23;vertical-align:middle;visibility:hidden}article#presentation > svg > foreignObject > section .markdown-body h1:hover .anchor,article#presentation > svg > foreignObject > section .markdown-body h2:hover .anchor,article#presentation > svg > foreignObject > section .markdown-body h3:hove
padding: 0 !important;
}article#presentation > svg > foreignObject > section[data-marpit-advanced-background="background"]::before,
article#presentation > svg > foreignObject > section[data-marpit-advanced-background="background"]::after,
article#presentation > svg > foreignObject > section[data-marpit-advanced-background="content"]::before,
article#presentation > svg > foreignObject > section[data-marpit-advanced-background="content"]::after {
display: none !important;
}article#presentation > svg > foreignObject > section[data-marpit-advanced-background="background"] > div[data-marpit-advanced-background-container] {
all: initial;
display: flex;
flex-direction: row;
height: 100%;
overflow: hidden;
width: 100%;
}article#presentation > svg > foreignObject > section[data-marpit-advanced-background="background"][data-marpit-advanced-background-split] > div[data-marpit-advanced-background-container] {
width: 50%;
}article#presentation > svg > foreignObject > section[data-marpit-advanced-background="background"][data-marpit-advanced-background-split="right"] > div[data-marpit-advanced-background-container] {
margin-left: 50%;
}article#presentation > svg > foreignObject > section[data-marpit-advanced-background="background"] > div[data-marpit-advanced-background-container] > figure {
all: initial;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
flex: auto;
margin: 0;
}article#presentation > svg > foreignObject > section[data-marpit-advanced-background="content"],
article#presentation > svg > foreignObject > section[data-marpit-advanced-background="pseudo"] {
background: transparent !important;
}article#presentation > svg > foreignObject > section[data-marpit-advanced-background="pseudo"],
article#presentation > svg[data-marpit-svg] > foreignObject[data-marpit-advanced-background="pseudo"] {
pointer-events: none !important;
}article#presentation > svg > foreignObject > section[data-marpit-advanced-background-split] {
width: 100%;
height: 100%;
}</style></head><body><div class="bespoke-marp-osc"><button data-bespoke-marp-osc="prev" tabindex="-1" title="Previous slide">Previous slide</button><span data-bespoke-marp-osc="page"></span><button data-bespoke-marp-osc="next" tabindex="-1" title="Next slide">Next slide</button><button data-bespoke-marp-osc="fullscreen" tabindex="-1" title="Toggle fullscreen (f)">Toggle fullscreen</button></div><article id="presentation"><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="1" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="1" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Practical Cryptography</span></foreignObject></svg></h1>
<h1>Requirements</h1>
<ul>
<li><code>openssl version</code> (1.1.1a)</li>
<li><code>curl --version</code> (7.64.0)</li>
<li><code>php --version</code> (7.3.2)</li>
<li><code>php -m |grep -e openssl -e curl</code></li>
<li><code>composer --version</code> (See <a href="https://getcomposer.org/download/">https://getcomposer.org/download/</a>) (1.8.4)</li>
<li><code>docker --version</code> (18.09.2-ce)</li>
<li><code>libtasn</code> (<code>brew install libtasn1</code>) (4.13)</li>
</ul>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="2" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="2" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Practical PKI</span></foreignObject></svg></h1>
<p><a href="nemo@razorpay.com"><em>nemo</em></a></p>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="3" data-paginate="true" data-footer="Razorpay" data-background-color="rebeccapurple" data-color="white" data-class="lead" data-theme="default" class="lead" data-marpit-pagination="3" style="--paginate:true;--footer:Razorpay;--background-color:rebeccapurple;--color:white;--class:lead;--theme:default;color:white;background-color:rebeccapurple;background-image:none;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Why</span></foreignObject></svg></h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="4" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="4" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Objectives</h1>
<ul>
<li>Get familiar with Crypto primitives</li>
<li>Hands-on with
<ul>
<li>OpenSSL</li>
<li>TLS</li>
<li>Curl</li>
</ul>
</li>
</ul>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="5" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="5" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Non-Goals</h1>
<ul>
<li>Understanding all Crypto-Attacks (we'll discuss a couple)</li>
<li>Elliptic Curve Crypto</li>
<li>crypto-currencies <img class="emoji" draggable="false" alt="🤑" src="https://twemoji.maxcdn.com/2/svg/1f911.svg" data-marp-twemoji=""/></li>
<li>Math</li>
<li>Intermediate Certs</li>
<li>Cert Revocation</li>
</ul>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="6" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="6" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Requirements</h1>
<ul>
<li><code>openssl version</code> (1.1.1a)</li>
<li><code>curl --version</code> (7.64.0)</li>
<li><code>php --version</code> (7.3.2)</li>
<li><code>php -m |grep -e openssl -e curl</code></li>
<li><code>composer --version</code> (See <a href="https://getcomposer.org/download/">https://getcomposer.org/download/</a>) (1.8.4)</li>
<li><code>docker --version</code> (18.09.2-ce)</li>
<li><code>libtasn</code> (<code>brew install libtasn1</code>) (4.13)</li>
</ul>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="7" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="7" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Setup</h1>
<ol>
<li>Have a browser open with Google (Lots of googling needed for this)</li>
<li><code>git clone git@github.com/captn3m0/crypto.koans.git &amp;&amp; cd crypto.koans</code></li>
<li><code>composer install</code></li>
</ol>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="8" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="8" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Koans <img class="emoji" draggable="false" alt="💃" src="https://twemoji.maxcdn.com/2/svg/1f483.svg" data-marp-twemoji=""/></span></foreignObject></svg></h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="9" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="9" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><strong>koan</strong></h1>
<p><em>noun</em>, <strong>plural ko·ans, ko·an.</strong> <em>Zen.</em></p>
<ol>
<li>a nonsensical or paradoxical question to a student for which an answer is demanded, the stress of meditation on the question often being illuminating.</li>
</ol>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="10" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="10" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> What is the colour of wind?</span></foreignObject></svg></h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="11" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="11" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h2>Ruby <img class="emoji" draggable="false" alt="💎" src="https://twemoji.maxcdn.com/2/svg/1f48e.svg" data-marp-twemoji=""/></h2>
<pre><code><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap>ruby path_to_enlightenment.rb
Thinking AboutAsserts
test_assert_truth has damaged your karma.
You have <span class="hljs-keyword">not</span> yet reached enlightenment ...
&lt;<span class="hljs-literal">false</span>&gt; <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">true</span>.
Please meditate <span class="hljs-keyword">on</span> <span class="hljs-keyword">the</span> following code:
./about_asserts.rb:<span class="hljs-number">10</span>:<span class="hljs-keyword">in</span> `test_assert_truth'
path_to_enlightenment.rb:<span class="hljs-number">27</span>
mountains are merely mountains
</span></span></foreignObject></svg></code></pre>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="12" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="12" style="--paginate:true;--footer:Razorpay;--theme:default;">
<pre><code class="language-ruby"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap> <span class="hljs-comment"># We shall contemplate truth by testing reality, via asserts.</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_assert_truth</span></span>
assert <span class="hljs-literal">false</span> <span class="hljs-comment"># This should be true</span>
<span class="hljs-keyword">end</span>
</span></span></foreignObject></svg></code></pre>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="13" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="13" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>tl;dr</h1>
<ol>
<li>Run tests</li>
<li>Why is the test failing? (<code>koans/files</code> directories)</li>
<li>Get it to pass</li>
</ol>
<p><img class="emoji" draggable="false" alt="👌🏼" src="https://twemoji.maxcdn.com/2/svg/1f44c-1f3fc.svg" data-marp-twemoji=""/> Don't Cheat</p>
<ul>
<li><img class="emoji" draggable="false" alt="❗" src="https://twemoji.maxcdn.com/2/svg/2757.svg" data-marp-twemoji=""/> Means you must do something here</li>
<li>Keep a <a href="http://solutions.md">solutions.md</a> file listing down commands as you run them</li>
</ul>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="14" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="14" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Setup</h1>
<ol>
<li>Have a browser open with Google (Lots of googling needed for this)</li>
<li><code>git clone git@github.com/captn3m0/crypto.koans.git &amp;&amp; cd crypto.koans</code></li>
<li><code>composer install</code></li>
<li><code>vendor/bin/phpunit</code></li>
<li><code>man openssl</code>, <code>man curl</code></li>
</ol>
<p><img class="emoji" draggable="false" alt="🧘‍♀️" src="https://twemoji.maxcdn.com/2/svg/1f9d8-200d-2640-fe0f.svg" data-marp-twemoji=""/><img class="emoji" draggable="false" alt="🧘‍♂️" src="https://twemoji.maxcdn.com/2/svg/1f9d8-200d-2642-fe0f.svg" data-marp-twemoji=""/></p>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="15" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="15" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> <code>vendor/bin/phpunit</code></span></foreignObject></svg></h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="16" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="16" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><code>OpensslKeyGenerationKoans.php</code></h1>
<p><code>vendor/bin/phpunit --filter BOpensslKeyGenerationKoans</code></p>
<h2><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Questions<img class="emoji" draggable="false" alt="❓" src="https://twemoji.maxcdn.com/2/svg/2753.svg" data-marp-twemoji=""/></span></foreignObject></svg></h2>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="17" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="17" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><code>FileFormatKoans.php</code></h1>
<p><code>vendor/bin/phpunit --filter CFileFormatKoans</code></p>
<h2><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Questions<img class="emoji" draggable="false" alt="❓" src="https://twemoji.maxcdn.com/2/svg/2753.svg" data-marp-twemoji=""/></span></foreignObject></svg></h2>
<ul>
<li>What is PEM vs DER?</li>
</ul>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="18" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="18" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Theory Break 1</h1>
<ul>
<li>Keys</li>
<li>Certificates</li>
<li>Signatures</li>
</ul>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="19" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="19" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><code>CA Certificates</code></h1>
<p><code>vendor/bin/phpunit --filter DCaCertificateKoans.php</code></p>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="20" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="20" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Generate A CA Certificate</span></foreignObject></svg></h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="21" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="21" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>testCaCertificateExists</h1>
<pre><code class="language-haskell"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-title">openssl</span> req -x509
-newkey rsa:<span class="hljs-number">1024</span>
-keyout files/ca.key
-nodes
-out files/ca.pem
-subj '/<span class="hljs-type">CN</span>=crypto.koans.invalid'
</span></span></foreignObject></svg></code></pre>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="22" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="22" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Generate a Certificate Signing Request</span></foreignObject></svg></h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="23" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="23" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Generate a Certificate Signing Request</span></foreignObject></svg></h1>
<pre><code class="language-haskell"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-title">openssl</span> req -new
-key files/<span class="hljs-number">1.</span>key
-subj '/<span class="hljs-type">CN</span>=server.crypto.koans.invalid'
-out files/<span class="hljs-number">1.</span>csr
</span></span></foreignObject></svg></code></pre>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="24" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="24" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Sign your CSR with your CA</span></foreignObject></svg></h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="25" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="25" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Sign your CSR with your CA</span></foreignObject></svg></h1>
<pre><code class="language-haskell"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-title">openssl</span> x509 -req
-<span class="hljs-keyword">in</span> files/<span class="hljs-number">1.</span>csr
-<span class="hljs-type">CA</span> files/ca.pem
-<span class="hljs-type">CAkey</span> files/ca.key
-<span class="hljs-type">CAcreateserial</span>
-out files/<span class="hljs-number">1.</span>crt
</span></span></foreignObject></svg></code></pre>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="26" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="26" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> What can a Certificate Do?</span></foreignObject></svg></h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="27" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="27" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>What can a Certificate Do?</h1>
<pre><code class="language-perl"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap>openssl x509
-in google.pem
-purpose
-noout <span class="hljs-comment">#Remove this and retry</span>
</span></span></foreignObject></svg></code></pre>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="28" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="28" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> Generate a Client Certificate</span></foreignObject></svg></h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="29" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="29" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Generate a Client Certificate</h1>
<h2>Step 1</h2>
<pre><code class="language-bash"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-built_in">printf</span> <span class="hljs-string">"extendedKeyUsage=clientAuth\nkeyUsage=digitalSignature"</span> &gt; client.cnf
</span></span></foreignObject></svg></code></pre>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="30" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="30" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Generate a Client Certificate</h1>
<h2>Step 2</h2>
<pre><code class="language-bash"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-comment"># As Alice</span>
openssl req -subj <span class="hljs-string">'/CN=alice.crypto.koans'</span>
-key files/client.key
-new
-out files/client.csr
<span class="hljs-comment"># As Bob</span>
openssl x509 -req -<span class="hljs-keyword">in</span> files/alice.csr
-CA files/ca.pem
-CAkey files/ca.key
-CAcreateserial
-extfile client.cnf
-out files/alice.crt
</span></span></foreignObject></svg></code></pre>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="31" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="31" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Generate a Client Certificate</h1>
<h2>Step 3</h2>
<ol>
<li>Save <code>alice.crt</code> as <code>client.crt</code></li>
<li>Save the CA file you received as <code>bob.pem</code></li>
<li>See <code>testClientBundleGenerated</code></li>
</ol>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="32" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="32" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Theory Break 2</h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="33" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="33" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>What Alice Had</h1>
<ol>
<li>Client (<code>client.key</code>, <code>client.csr</code>)</li>
</ol>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="34" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="34" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>What Bob Had</h1>
<ol>
<li>Client CSR (<code>client.csr</code>)</li>
<li>CA (<code>ca.pem</code>, <code>ca.key</code>)</li>
</ol>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="35" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="35" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>What Bob Had</h1>
<ol>
<li>Client CSR (<code>client.csr</code>, <code>alice.crt</code>)</li>
<li>CA (<code>ca.pem</code>, <code>ca.key</code>)</li>
</ol>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="36" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="36" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>What Alice Has</h1>
<ol>
<li>Client (<code>client.key</code>, <code>client.csr</code>, <code>client.crt</code>)</li>
<li>Bob's CA (<code>bob.pem</code>)</li>
</ol>
<h1>What Bob Has</h1>
<ol>
<li>Server (<code>1.key</code>, <code>1.csr</code>, <code>1.crt</code>)</li>
<li>CA (<code>ca.pem</code>, <code>ca.key</code>)</li>
</ol>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="37" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="37" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>What Alice Has</h1>
<ol>
<li>Client (<code>client.key</code>, <code>client.crt</code>)</li>
<li>Bob's CA (<code>bob.pem</code>)</li>
</ol>
<h1>What Bob Has</h1>
<ol>
<li>Server (<code>1.key</code>, <code>1.crt</code>)</li>
<li>Bob's Own CA (<code>ca.pem</code>)</li>
</ol>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="38" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="38" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Where we're going</h1>
<h1><svg data-marp-fitting="svg"><foreignObject><span data-marp-fitting-svg-content> <img class="emoji" draggable="false" alt="🐳" src="https://twemoji.maxcdn.com/2/svg/1f433.svg" data-marp-twemoji=""/> <img class="emoji" draggable="false" alt="🚀" src="https://twemoji.maxcdn.com/2/svg/1f680.svg" data-marp-twemoji=""/></span></foreignObject></svg></h1>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="39" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="39" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><img class="emoji" draggable="false" alt="🐳" src="https://twemoji.maxcdn.com/2/svg/1f433.svg" data-marp-twemoji=""/> <img class="emoji" draggable="false" alt="1⃣" src="https://twemoji.maxcdn.com/2/svg/31-20e3.svg" data-marp-twemoji=""/> / <img class="emoji" draggable="false" alt="2⃣" src="https://twemoji.maxcdn.com/2/svg/32-20e3.svg" data-marp-twemoji=""/></h1>
<h2>As Bob</h2>
<p>Bring up a server using your key (<code>1.key</code>) and certificate (<code>1.crt</code>) and allow any client signed<br />
by your CA (<code>ca.pem</code>) to talk to you.</p>
<pre><code class="language-bash"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap>docker run --volume `<span class="hljs-built_in">pwd</span>`/files:/etc/koans
--publish 8443:443
captn3m0/crypto.koans
</span></span></foreignObject></svg></code></pre>
<pre><code><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap><span class="hljs-meta"># ssl_certificate /etc/koans/1.crt;</span>
<span class="hljs-meta"># ssl_certificate_key /etc/koans/1.key;</span>
<span class="hljs-meta"># ssl_client_certificate /etc/koans/ca.pem;</span>
<span class="hljs-meta"># Give your WiFi IP to your partner</span>
</span></span></foreignObject></svg></code></pre>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="40" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="40" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1><img class="emoji" draggable="false" alt="🐳" src="https://twemoji.maxcdn.com/2/svg/1f433.svg" data-marp-twemoji=""/> <img class="emoji" draggable="false" alt="2⃣" src="https://twemoji.maxcdn.com/2/svg/32-20e3.svg" data-marp-twemoji=""/> / <img class="emoji" draggable="false" alt="2⃣" src="https://twemoji.maxcdn.com/2/svg/32-20e3.svg" data-marp-twemoji=""/></h1>
<h2>As Alice</h2>
<p>Use the certificate (signed by Bob) and the key<br />
(which only you have) to talk to Bob's server (which<br />
you can verify using the CA given)</p>
<pre><code class="language-bash"><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap>curl https://server.crypto.koans.invalid:8443
--resolve server.crypto.koans.invalid:8443:192.168.1.121
--cert files/client.crt
--key files/client.key
--cacert files/bob.pem
</span></span></foreignObject></svg></code></pre>
<pre><code><svg data-marp-fitting="svg" data-marp-fitting-code><foreignObject><span data-marp-fitting-svg-content><span data-marp-fitting-svg-content-wrap># /etc/hosts
<span class="hljs-number">192.168</span><span class="hljs-number">.1</span><span class="hljs-number">.121</span> server.crypto.koans.invalid
</span></span></foreignObject></svg></code></pre>
<footer>Razorpay</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="41" data-paginate="true" data-footer="Razorpay" data-theme="default" data-marpit-pagination="41" style="--paginate:true;--footer:Razorpay;--theme:default;">
<h1>Browser <img class="emoji" draggable="false" alt="🌍" src="https://twemoji.maxcdn.com/2/svg/1f30d.svg" data-marp-twemoji=""/></h1>
<ol>
<li>Import <code>bundle.pfx</code> in your browser</li>
<li>Enable CA Usage for websites</li>
<li>Open <a href="https://server.crypto.koans.invalid:8443">https://server.crypto.koans.invalid:8443</a></li>
</ol>
<footer>Razorpay</footer>
</section>
</foreignObject></svg></article><script>!function(){"use strict";function e(e){var n=i([["iOS",/iP(hone|od|ad)/],["Android OS",/Android/],["BlackBerry OS",/BlackBerry|BB10/],["Windows Mobile",/IEMobile/],["Amazon OS",/Kindle/],["Windows 3.11",/Win16/],["Windows 95",/(Windows 95)|(Win95)|(Windows_95)/],["Windows 98",/(Windows 98)|(Win98)/],["Windows 2000",/(Windows NT 5.0)|(Windows 2000)/],["Windows XP",/(Windows NT 5.1)|(Windows XP)/],["Windows Server 2003",/(Windows NT 5.2)/],["Windows Vista",/(Windows NT 6.0)/],["Windows 7",/(Windows NT 6.1)/],["Windows 8",/(Windows NT 6.2)/],["Windows 8.1",/(Windows NT 6.3)/],["Windows 10",/(Windows NT 10.0)/],["Windows ME",/Windows ME/],["Open BSD",/OpenBSD/],["Sun OS",/SunOS/],["Linux",/(Linux)|(X11)/],["Mac OS",/(Mac_PowerPC)|(Macintosh)/],["QNX",/QNX/],["BeOS",/BeOS/],["OS/2",/OS\/2/],["Search Bot",/(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves\/Teoma)|(ia_archiver)/]]).filter(function(n){return n.rule&&n.rule.test(e)})[0];return n?n.name:null}function n(){return"undefined"!=typeof process&&process.version&&{name:"node",version:process.version.slice(1),os:process.platform}}function t(n){var t=i([["aol",/AOLShield\/([0-9\._]+)/],["edge",/Edge\/([0-9\._]+)/],["yandexbrowser",/YaBrowser\/([0-9\._]+)/],["vivaldi",/Vivaldi\/([0-9\.]+)/],["kakaotalk",/KAKAOTALK\s([0-9\.]+)/],["samsung",/SamsungBrowser\/([0-9\.]+)/],["chrome",/(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],["phantomjs",/PhantomJS\/([0-9\.]+)(:?\s|$)/],["crios",/CriOS\/([0-9\.]+)(:?\s|$)/],["firefox",/Firefox\/([0-9\.]+)(?:\s|$)/],["fxios",/FxiOS\/([0-9\.]+)/],["opera",/Opera\/([0-9\.]+)(?:\s|$)/],["opera",/OPR\/([0-9\.]+)(:?\s|$)$/],["ie",/Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/],["ie",/MSIE\s([0-9\.]+);.*Trident\/[4-7].0/],["ie",/MSIE\s(7\.0)/],["bb10",/BB10;\sTouch.*Version\/([0-9\.]+)/],["android",/Android\s([0-9\.]+)/],["ios",/Version\/([0-9\._]+).*Mobile.*Safari.*/],["safari",/Version\/([0-9\._]+).*Safari/],["facebook",/FBAV\/([0-9\.]+)/],["instagram",/Instagram\s([0-9\.]+)/],["ios-webview",/AppleWebKit\/([0-9\.]+).*Mobile/]]);if(!n)return null;var o=t.map(function(e){var t=e.rule.exec(n),i=t&&t[1].split(/[._]/).slice(0,3);return i&&i.length<3&&(i=i.concat(1==i.length?[0,0]:[0])),t&&{name:e.name,version:i.join(".")}}).filter(Boolean)[0]||null;return o&&(o.os=e(n)),/alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/i.test(n)&&((o=o||{}).bot=!0),o}function i(e){return e.map(function(e){return{name:e[0],rule:e[1]}})}var o=function(){return"undefined"!=typeof navigator?t(navigator.userAgent):n()},r=o;let s;const a=["android","bb10","crios","facebook","fxios","instagram","ios-webview","ios","phantomjs","safari"];function l(){Array.from(document.getElementsByTagName("svg"),e=>{if(e.hasAttribute("data-marpit-svg")){const{clientHeight:n,clientWidth:t}=e;e.style.transform||(e.style.transform="translateZ(0)");const{width:i,height:o}=e.viewBox.baseVal,r=Math.min(n/o,t/i);Array.from(e.querySelectorAll(":scope > foreignObject"),e=>{const s=e.x.baseVal.value,a=e.y.baseVal.value;Array.from(e.querySelectorAll(":scope > section"),e=>{e.style.transformOrigin||(e.style.transformOrigin="0 0");const l=(t-r*i)/2-s,d=(n-r*o)/2-a;e.style.transform=`translate3d(${l}px,${d}px,0) scale(${r}) translate(${s}px,${a}px)`})})}})}const d="data-marp-fitting",c="data-marp-fitting-code",u="data-marp-fitting-math",f=(e,n,t)=>{if(e.getAttribute(n)!==t)return e.setAttribute(n,t),!0};!function(e=!0){const n=()=>{for(const e of function(){if(!s){s=[];const{name:e}=r()||{};a.includes(e)&&s.push(l)}return s}())e();Array.from(document.querySelectorAll(`svg[${d}="svg"]`),e=>{const n=e.firstChild,t=n.firstChild,{scrollWidth:i,scrollHeight:o}=t;let r,s=1;if(e.hasAttribute(c)&&(r=e.parentElement.parentElement),e.hasAttribute(u)&&(r=e.parentElement),r){const e=getComputedStyle(r),n=Math.ceil(r.clientWidth-parseFloat(e.paddingLeft)-parseFloat(e.paddingRight));n&&(s=n)}const a=Math.max(i,s),l=Math.max(o,1),d=`0 0 ${a} ${l}`;f(n,"width",`${a}`),f(n,"height",`${l}
</script><script>!function(){"use strict";var e={from:function(e,n){var t=1===(e.parent||e).nodeType?e.parent||e:document.querySelector(e.parent||e),r=[].filter.call("string"==typeof e.slides?t.querySelectorAll(e.slides):e.slides||t.children,function(e){return"SCRIPT"!==e.nodeName}),i=r[0],l={},o=function(e,n){r[e]&&(a("deactivate",u(i,n)),i=r[e],a("activate",u(i,n)))},s=function(e,n){var t=r.indexOf(i)+e;a(e>0?"next":"prev",u(i,n))&&o(t,n)},c=function(e,n){l[e]=(l[e]||[]).filter(function(e){return e!==n})},a=function(e,n){return(l[e]||[]).reduce(function(e,t){return e&&!1!==t(n)},!0)},u=function(e,n){return(n=n||{}).index=r.indexOf(e),n.slide=e,n},d={on:function(e,n){return(l[e]||(l[e]=[])).push(n),c.bind(null,e,n)},off:c,fire:a,slide:function(e,n){if(!arguments.length)return r.indexOf(i);a("slide",u(r[e],n))&&o(e,n)},next:s.bind(null,1),prev:s.bind(null,-1),parent:t,slides:r};return(n||[]).forEach(function(e){e(d)}),o(0),d}},n=function(){return function(e){e.slides.forEach(function(e){e.addEventListener("keydown",function(e){(/INPUT|TEXTAREA|SELECT/.test(e.target.nodeName)||"true"===e.target.contentEditable)&&e.stopPropagation()})})}};function t(e){e.parent.classList.add("bespoke-marp-parent"),e.slides.map(e=>e.classList.add("bespoke-marp-slide")),e.on("activate",n=>{e.slides.map(e=>e.classList.remove("bespoke-marp-active")),n.slide.classList.add("bespoke-marp-active")})}function r(e=2e3){return n=>{let t;function r(){t&&clearTimeout(t),t=setTimeout(()=>{n.parent.classList.add("bespoke-marp-inactive")},e),n.parent.classList.remove("bespoke-marp-inactive")}document.addEventListener("mousedown",r),document.addEventListener("mousemove",r),document.addEventListener("touchend",r),setTimeout(r,0)}}var i,l=(function(e){var n,t,r,i,l,o;n="undefined"!=typeof window&&void 0!==window.document?window.document:{},t=e.exports,r="undefined"!=typeof Element&&"ALLOW_KEYBOARD_INPUT"in Element,i=function(){for(var e,t=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],r=0,i=t.length,l={};r<i;r++)if((e=t[r])&&e[1]in n){for(r=0;r<e.length;r++)l[t[0][r]]=e[r];return l}return!1}(),l={change:i.fullscreenchange,error:i.fullscreenerror},o={request:function(e){return new Promise(function(t){var l=i.requestFullscreen,o=function(){this.off("change",o),t()}.bind(this);e=e||n.documentElement,/ Version\/5\.1(?:\.\d+)? Safari\//.test(navigator.userAgent)?e[l]():e[l](r?Element.ALLOW_KEYBOARD_INPUT:{}),this.on("change",o)}.bind(this))},exit:function(){return new Promise(function(e){var t=function(){this.off("change",t),e()}.bind(this);n[i.exitFullscreen](),this.on("change",t)}.bind(this))},toggle:function(e){return this.isFullscreen?this.exit():this.request(e)},onchange:function(e){this.on("change",e)},onerror:function(e){this.on("error",e)},on:function(e,t){var r=l[e];r&&n.addEventListener(r,t,!1)},off:function(e,t){var r=l[e];r&&n.removeEventListener(r,t,!1)},raw:i},i?(Object.defineProperties(o,{isFullscreen:{get:function(){return Boolean(n[i.fullscreenElement])}},element:{enumerable:!0,get:function(){return n[i.fullscreenElement]}},enabled:{enumerable:!0,get:function(){return Boolean(n[i.fullscreenEnabled])}}}),t?e.exports=o:window.screenfull=o):t?e.exports=!1:window.screenfull=!1}(i={exports:{}},i.exports),i.exports);function o(e){e.fullscreen=(()=>l.toggle(document.body)),document.addEventListener("keydown",n=>{70!==n.which&&122!==n.which||n.altKey||n.ctrlKey||n.metaKey||!l.enabled||(e.fullscreen(),n.preventDefault()
</script></body></html>