Jekyll2020-11-15T00:11:43-05:00https://mrosenberg.pub/feed.xmlrosenblogA collection of thoughts on privacy and cryptographyMichael RosenbergMulan (2020): An Embarrassment to the Genre2020-09-16T00:00:00-04:002020-09-16T00:00:00-04:00https://mrosenberg.pub/2020/09/16/mulan<p>Welp, Disney did it again. Exhibiting zero comprehension of the basics of filmmaking, Mulan (2020) is a masterpiece in how to mis-structure a movie, mis-time its pacing, and mis-write the whole plot. It should be no surprise, then, that the movie fell flat at its release, although Disney is probably going to blame it on the pandemic like they did for the many out-of-touch attempts at a Marvel cyber-superhero Snapchat miniseries they’ve made since February. For the unaware, the latest Mulan release is a remake of the beautifully written and animated 1998 Disney film of the same name. Unfortunately, the similarities end there, because this rendition was worse than leaving my TV off for the 3.5 hour runtime. Even if you’re being generous because you’re just looking for a nostalgia kick, you’re still in for a bad time, because this movie bears almost no resemblance to the original. I’m talking songs, dialogue, and even large portions of the story wildly changed, outright removed, or casted to someone with literally zero acting experience. This has been extremely frustrating to review, and it’s burned me out a bit with regard to the pandemic-era Disney content, so consider this my last such breakdown, at least for a while:</p>
<ol>
<li>
<p>My first problem is a more general one: why is it called <em>Mulan</em>? The protagonist of the story, Mulan Ferrera, is exclusively called “Ferrera” for the duration of the movie. I didn’t even realize she was supposed to be Mulan until I watched the credits. It was super disappointing because I was waiting for <em>hours</em> for Mulan to make her grand appearance and lead the army, but it never happened. Totally misleading.</p>
</li>
<li>
<p>Speaking of credits, why is the after-credits scene a Sprint commercial? I truly wasn’t expecting much, but this was really a slap in the face. Plus none of the actors from the movie are even in the commercial. The only person I recognized was Terry Crews, and he didn’t have anything to do with Mulan as far as I can tell.</p>
</li>
<li>
<p>Why did the movie pause periodically to make me do a survey? I hit the play button and 15 minutes later it asks me in the middle of the exposition which character is my favorite so far. It’s super distracting. Also, I don’t want to watch the same scene twice with minor differences and have to pick which one was better. That’s not my job, and I didn’t pay $90 to improve Disney’s product for them. Fix this.</p>
</li>
<li>
<p>Where the hell is Baby Yoda? I am legitimately pissed that Disney had the gall to tease Baby Yoda in the trailers, and then refuse to put him in a single scene. I didn’t link my bank account to Disney+ just to watch Mushu get a stick-and-poke tattoo of the Rebel Alliance logo. I don’t care if they depleted the SFX budget on making it look like a genocide wasn’t happening <a href="https://www.washingtonpost.com/world/asia_pacific/disneys-mulan-faces-criticism-for-filming-in-chinas-xinjiang-region/2020/09/08/c45a80d2-f17d-11ea-8025-5d3489768ac8_story.html">in one of the background shots</a>, I want to see a goddamn force choke.</p>
</li>
<li>
<p>Someone has got to address the homeless guy. For the love of god, why is there a homeless dude in every single CGI shot in the movie? He asks Ferrera repeatedly for a few dollars or some food and she just does the scene like he’s not there. Is this some sort of social commentary or did they actually just have a homeless guy in front of the green screen that they didn’t want to kick out? Of course it’s uncomfortable, but come on.</p>
</li>
</ol>
<p>So yeah, this movie has some serious issues. More likely than not, Disney will turn this into a chance to double-dip and do a re-release in a few years where they’ve fixed all the issues but accidentally dubbed the entire thing into Portuguese (I still can’t let this go; I can’t appreciate Iron Giant if I can’t fucking understand what the gigante is saying). I give this a 4/10: probably not worth your time, but at least it wasn’t <a href="https://www.washingtonpost.com/world/2020/09/05/mulan-disney-china-hongkong-boycott/">pro-CCP</a>.<br /><br /></p>
<p><em>Join me next week, where I HBO Max Out my credit card and teach you how to get a home equity line of credit using your neighbor’s house as collateral.</em></p>Michael RosenbergWelp, Disney did it again. Exhibiting zero comprehension of the basics of filmmaking, Mulan (2020) is a masterpiece in how to mis-structure a movie, mis-time its pacing, and mis-write the whole plot. It should be no surprise, then, that the movie fell flat at its release, although Disney is probably going to blame it on the pandemic like they did for the many out-of-touch attempts at a Marvel cyber-superhero Snapchat miniseries they’ve made since February. For the unaware, the latest Mulan release is a remake of the beautifully written and animated 1998 Disney film of the same name. Unfortunately, the similarities end there, because this rendition was worse than leaving my TV off for the 3.5 hour runtime. Even if you’re being generous because you’re just looking for a nostalgia kick, you’re still in for a bad time, because this movie bears almost no resemblance to the original. I’m talking songs, dialogue, and even large portions of the story wildly changed, outright removed, or casted to someone with literally zero acting experience. This has been extremely frustrating to review, and it’s burned me out a bit with regard to the pandemic-era Disney content, so consider this my last such breakdown, at least for a while:A Bookmarklet to Download Zoom Recordings2020-09-15T00:00:00-04:002020-09-15T00:00:00-04:00https://mrosenberg.pub/programming/2020/09/15/zoomdl<p><strong>Update (Sep. 23, 2020):</strong> Zoom disabled right-click on their video sites. I’ve updated the script to re-enable right-click :)</p>
<h1 id="overview">Overview</h1>
<p>This is a <em>bookmarklet</em> (that is, a bookmark with script inside) that lets you download recorded Zoom calls from the Zoom cloud, regardless of whether the owner has downloads enabled. If it’s visible to you, you can download it.</p>
<h1 id="why">Why</h1>
<p>I like to watch lectures in the park, where there is no WiFi. So now I download the lectures in advance and take them wherever I go.</p>
<h1 id="installation">Installation</h1>
<p>Right click the link below and select “Bookmark This Link”. Put the bookmark wherever you want.<br /><br /></p>
<div><a href="
javascript:(function(){
const download_link_id = "__zoomdl_link";
if (!window.location.hostname.endsWith("zoom.us")
|| document.getElementById(download_link_id)) {
return;
}
const video_url = document.getElementById("vjs_video_3_html5_api").src;
var download_link = document.createElement("a");
download_link.id = download_link_id;
download_link.href = video_url;
download_link.innerHTML = "Download Video (right click → Save Link As)";
download_link.style = "font-weight: bold";
download_link.onclick = function() { return false; };
var container = document.getElementsByClassName("main")[0];
container.prepend(download_link);
function enableContextMenu(aggressive = false) {
void(document.ondragstart = null);
void(document.onselectstart = null);
void(document.onclick = null);
void(document.onmousedown = null);
void(document.onmouseup = null);
void(document.body.oncontextmenu = null);
enableRightClickLight(document);
if (aggressive) {
enableRightClick(document);
removeContextMenuOnAll("body");
removeContextMenuOnAll("img");
removeContextMenuOnAll("td");
}
}
function removeContextMenuOnAll(tagName) {
var elements = document.getElementsByTagName(tagName);
for (var i = 0; i < elements.length; i++) {
enableRightClick(elements[i]);
}
}
function enableRightClickLight(el) {
el || (el = document);
el.addEventListener("contextmenu", bringBackDefault, true);
}
function enableRightClick(el) {
el || (el = document);
el.addEventListener("contextmenu", bringBackDefault, true);
el.addEventListener("dragstart", bringBackDefault, true);
el.addEventListener("selectstart", bringBackDefault, true);
el.addEventListener("click", bringBackDefault, true);
el.addEventListener("mousedown", bringBackDefault, true);
el.addEventListener("mouseup", bringBackDefault, true);
}
function restoreRightClick(el) {
el || (el = document);
el.removeEventListener("contextmenu", bringBackDefault, true);
el.removeEventListener("dragstart", bringBackDefault, true);
el.removeEventListener("selectstart", bringBackDefault, true);
el.removeEventListener("click", bringBackDefault, true);
el.removeEventListener("mousedown", bringBackDefault, true);
el.removeEventListener("mouseup", bringBackDefault, true);
}
function bringBackDefault(event) {
event.returnValue = true;
(typeof event.stopPropagation === "function") && event.stopPropagation();
(typeof event.cancelBubble === "function") && event.cancelBubble();
}
enableContextMenu();
})();
">
Zoom Rec. ⬇️
</a></div>
<h1 id="how-to-use">How to Use</h1>
<ol>
<li>When you’re on the Zoom website, watching a recorded Zoom call, click the Zoom Rec. ⬇️ bookmarklet</li>
<li>A link will appear at the top of the page telling you to right click it</li>
<li>Right click the link, select “Save Link As”, and save the video file onto your computer</li>
</ol>
<h1 id="source-code-and-license">Source Code and License</h1>
<p>Source code and license are available on the <a href="https://github.com/rozbb/zoomdl-bookmarklet">Github page</a>.</p>Michael RosenbergUpdate (Sep. 23, 2020): Zoom disabled right-click on their video sites. I’ve updated the script to re-enable right-click :)Bureau Summer 2020 Audio Sketch Show2020-08-19T00:00:00-04:002020-08-19T00:00:00-04:00https://mrosenberg.pub/2020/08/19/bureau_show<h2 id="the-show">The show</h2>
<p>In spring and summer of 2020, <a href="https://thebureaumembers.wixsite.com/umdthebureau">The Bureau</a> sketch comedy/improv club at UMD recorded an audio sketch/music show.</p>
<p><a href="/assets/audio/bureau_show_summer20.mp3"><strong>Listen to the show (MP3)</strong></a></p>
<h2 id="credits">Credits</h2>
<p>Actors (order of appearance)</p>
<ul>
<li>Dagm Sirak</li>
<li>Michael Rosenberg</li>
<li>Devon Slattery</li>
<li>Koki Belikow</li>
<li>Sara Nahusenay</li>
<li>Alex Parsky</li>
</ul>
<p>Written, directed, and edited by Michael Rosenberg</p>
<p>Scored by Gabe Zimbler a.k.a. <a href="https://open.spotify.com/artist/42SLER01yGgJJygeuMWPgs">MAD PLEASANT</a></p>
<p>Phone ringing sound by Mike Koenig. Licensed under <a href="https://creativecommons.org/licenses/by/3.0/legalcode">CC BY 3.0</a></p>
<p>Pushbar Door sound by <a href="https://www.youtube.com/channel/UCkq5JZ2yOF7b0rkMQMgdAIA">YouTube Audio Library</a></p>
<p>All heretofore unattributed sound effects obtained from <a href="https://www.zapsplat.com">Zapsplat</a></p>Michael RosenbergThe showA Love Letter to Cirrus Cinema’s Row M½2020-07-05T00:00:00-04:002020-07-05T00:00:00-04:00https://mrosenberg.pub/2020/07/05/row_m12<p>Before the pandemic, the local cinema was my favorite place to be. On any given weekend, and even most weekdays, I could be found watching or rewatching a film, sitting in the backmost half row of the cinema’s primary theater—a row I called Row M½. And although Row M½’s importance to me has not changed in the months since I last saw it, the emotions that surround it have. Trailers that used to spark anticipation for an upcoming box office release now spark nostalgia for a night that I could have been more appreciative for. The smell of microwave popcorn that I knew didn’t compare to the theater’s recipe now reminds me that this facsimile is the closest I’ll get to the real thing. The act of turning down the TV volume late at night out of neighborly consideration now gives me pangs of longing for the boom of two toddler-sized subwoofers built into the walls. All these aches, all these needling desires, I have bottled up until a terminus that lies nowhere on the horizon, at least not as far as anyone can tell. The purpose of this piece is to dissect some of my own feelings about the movies, and to hopefully stir up a feeling in the reader about their own local theater. I don’t have any answers, and I don’t have any replacements, but I do like to note that, while we can’t exactly share movies with each other right now, we can at least still share stories.</p>
<p>I started masturbating while bootlegging films in early or mid 2008 after being laid off from my job at a local bookstore. The habit arose mostly from a desire for cheap escapism, caused and perpetuated in no small part by a declining economy and a job market that was growing sparser by the week. I acknowledge that some might find it inappropriate—the masturbating part—and I offer that I actually used to be a repeat patron at more sex-positive establishments like peep shows and drive-in cinemas. But these alternatives had already all but disappeared by the end of the 90s, and were entirely gone from my town by 2008. Given my financial situation and the dearth of alternatives, the value proposition of masturbooting (bootsturbating?) at Cirrus Cinema was clear enough: I could achieve one of several quotidian releases and simultaneously make a decent amount of money selling the bootlegs, with the only proviso being that I keep my involvement in the production down to the occasional grunt or two, preferably released during a loud scene. It was thus that I decided to head to Cirrus for the first time to see if the idea was feasible. While I was just looking for a place to hang my hog at the time, what I ended up finding was an unexpected home at the back of the theater, in Row M½.</p>
<p>The first detail that I noticed about Cirrus Cinemas was that it was a shithole. The lobby and exterior were, as a whole, a ratty, nauseating masterpiece of 80s suburban cultural sterility. The floors were immaculately evenly coated with what I deduced by smell was a Pinesol-melted-Raisinette solution, the seats were well-worn in the same way that a motorcycle crash victim’s knee skin is well-worn, and the demeanor of the employees always lay somewhere between the anarchistic “the customer is never right” to the avant-garde “fuck the customer.” But, once I had entered the lobby, I had no intention of stopping the search for my spot. I pressed on, past the dirty ticket counters, past the highway-robbing concession stands, past the eye-catching and not-unarousing massive cartoon chipmunk cutouts. I was determined to find what I was looking for.</p>
<p>As I was surveying the main theater for conditions that would be conducive to maintaining hand-eye-hand coordination for the length of a feature film, it became obvious to me that Row M½ was undervalued real estate. Not only was it the smallest and furthest-back row, it also happened to be the darkest. The size and location made it unlikely for me to get caught, and the darkness eliminated glare while conferring some amount of privacy and hopefully plausible deniability. I unfortunately cannot rigorously explain the features of Row M½ that made it so special, as the number of pros necessary to outweigh the con of needing to visually inspect the soda machine nozzle for lice is far too large to be expanded here. So instead I would like to skip ahead and share one of my favorite and most endearing stories in detail. This story is about the discovery of the tiny locker hidden away somewhere inside Row M½.</p>
<p>I found the locker by pure coincidence. Some time in July of 2008, I had decided to go masturbate to <em>Mamma Mia!</em> in theaters. I had chosen to go on a Wednesday night, when attendance would be perfectly sparse. By that time, I had already upgraded my setup to a proper digital camera instead of a cassette-based handycam, a boom mic instead of a tiny built-in camera mic, an adjustable tripod instead of a propped-up elbow, and an oil-based lubricant instead of butter. However, as it was a beautiful summer evening, and I had no excuse to be wearing a ski coat or large opaque poncho, I was only able to sneak in the camera. The previews began to play just as I took my seat in the empty row. I quickly got out my grumbles and coughs, stabilized my camera arm on the armrest, and hit record with my slicked right index finger.</p>
<p>I recall at some point during the “SOS” number in the movie where Pierce Brosnan tries to win back the affection of Meryl Streep and I was close to climaxing that I saw a silhouette appear just within my periphery. I squinted to see it was the usher, walking into the theater, presumably to swiftly complete his appointed rounds of ensuring that people aren’t throwing drinks or fucking the seat cushions. I reacted almost instantly, tilting my head to the side, making it appear as if I were leaning on my camera hand, and rearranging my face to look like I was shocked and baffled by the choice to cast Brosnan as Sam, which, to be fair, I was. The grab-ass gestapo walked by me, barely looking in my direction, walked around Row M½, and went back out of the theater. I distinctly remember, as Meryl stared at Pierce inexplicably putting ornaments on a tree that had appeared outdoors, thinking to myself how lucky I was to spot the usher in time. But the thought gave me pause, and the realization hit: it was the shadows cast by lights in the theater’s narrow hallway entrance that gave away the cum cop’s presence, and it was my specific viewing angle that allowed me to see him! In other words, Row M½ had, again, saved my skin! This overwhelming sense of gratitude coupled with the visual teasing of Meryl and Pierce pressing themselves against a rustic brick wall, so nearly back to back, was too much for my body to hold in. I shot into my cup of Fanta with a velocity I was certain would cause a moan throaty and loud enough to ruin my film. But, to my surprise, I heard a crashing sound instead. For a moment I thought perhaps it was a deus ex ventana, come to rapture my spirit from its shitty Earthly bonds, or at least give me a job, but when my eyes rolled back down I saw that the crashing sound was not the shattering of a glass window, but the breaking of wood, and it came from below my chair.</p>
<p>While I was blacked out and convulsing in a violent full-body meditation on cinematographic critique, I had apparently kicked the floor so hard that a board cracked and revealed a narrow opening. I put down the Fanta au lait and peered into the space beneath the floor. What may have appeared to the average person as a small hole I saw as an opportunity. Not in the gross way in which an uncharitable reader might interpret that statement, but as a solution to my equipment problem and a viable way to convert my hobby into a career. Since that balmy summer night, I have been using the floor space beneath Row M½ to store my tripod, boom, change of clothes, misc. cables, and more. And, for matter of record, I would never have sex with a floorboard. Not when the seat cushions are right there.</p>
<p>It my sincerest hope that, in this winding, love-drunk story about a lovely light in a dark, revolting rathole of a venue whose closest thing to a redeeming quality is the occasional genuine smile on the HSV-1-ridden face of a teenaged ticket-taker who earnestly but tastelessly masturbates in the theater as well, I’ve at least conveyed the sense of hominess that I get when I take my seat in a row that truly is my own. Of course, theaters will be closed for quite some time yet, but I hope I have convinced you, dear reader, to grab a ticket at your local theater when the chance arises in a week, a month, or even a year from now. Perhaps some day I’ll even see you as I take my seat in Row M½ and look around the theater. And if you do happen to catch my eye, and I yours, please don’t take offense if I don’t say hi. My hands are most likely full.</p>Michael RosenbergBefore the pandemic, the local cinema was my favorite place to be. On any given weekend, and even most weekdays, I could be found watching or rewatching a film, sitting in the backmost half row of the cinema’s primary theater—a row I called Row M½. And although Row M½’s importance to me has not changed in the months since I last saw it, the emotions that surround it have. Trailers that used to spark anticipation for an upcoming box office release now spark nostalgia for a night that I could have been more appreciative for. The smell of microwave popcorn that I knew didn’t compare to the theater’s recipe now reminds me that this facsimile is the closest I’ll get to the real thing. The act of turning down the TV volume late at night out of neighborly consideration now gives me pangs of longing for the boom of two toddler-sized subwoofers built into the walls. All these aches, all these needling desires, I have bottled up until a terminus that lies nowhere on the horizon, at least not as far as anyone can tell. The purpose of this piece is to dissect some of my own feelings about the movies, and to hopefully stir up a feeling in the reader about their own local theater. I don’t have any answers, and I don’t have any replacements, but I do like to note that, while we can’t exactly share movies with each other right now, we can at least still share stories.My Guilty Pleasure is Fudging Measurements on the Amount of Chemical Waste that the Factory I Work at Releases into Local Waterways2020-06-04T00:00:00-04:002020-06-04T00:00:00-04:00https://mrosenberg.pub/2020/06/04/guilty_pleasure<p>Yes, you read that right. Let me explain. For 17 years, I have been working as an environmental policy compliance officer at Dow Chemical in Midland, MI, and, frankly, I love everything about my job. I love being able to work with my hands. I love the comprehensive dental plan. I love the hands-off management style. And I love exploiting the hands-off management style to under-report the amount of polychlorinated dibenzodioxin-based chemical waste that <a href="https://www.nytimes.com/2007/07/04/us/04dioxin.html">we leak</a> into the Tittabawassee river. I’ll say it loud and I’ll say it with conviction: My name is Daniel Arkos, and I am no longer scared to be myself.</p>
<p>Today, I own up to my guilty pleasure and let my freak flag fly. Just like the person who finds themselves addicted to trashy reality TV, the person who indulges in the scent of their own flatulence, or the person who prefers to eat their ice cream behind closed doors, I too partake in premeditated acts of fraud that have directly caused <a href="https://www.nrdc.org/sites/default/files/michigan_diseaseclusters.pdf">outbreaks of breast cancer</a> in Midland, Saginaw, and Bay counties, and I am sick of being ashamed. I am sick of pretending. I am sick of hiding an important part of myself from the world just because society has conditioned us to feel shame when it comes to our body shape or sexual preference or murder. If, before today, I was closeted, consider this my coming-out.</p>
<p>I am, in many respects, a normal guy with a normal life. I love my family, I adore playing football with my kids, and I hate the commuter traffic I hit when coming from my primary residence upstream. These are the things that I would want to define me as a person. When, some day, I pass, I would want my obituary to read “Recently Deceased, Daniel Arkos, father of 2, serial motivator, decent defensive lineman.” Unfortunately, we live in a messed-up world where something like that is a fantasy for people like us. It sickens me to say, but it is infinitely more likely that the Midland Daily News would run something more like “Thankfully Gone, Daniel Arkos, serial putter of furan in the water; also, his father worked at Dow and <a href="https://en.wikipedia.org/wiki/Dow_Chemical_Company#Vietnam_War:_napalm_and_Agent_Orange">made napalm</a>.” It makes me feel unwanted and unseen. I ask, whose right is it to make me feel like an unempathetic, unredeemable piece of human scum for my occasional indulgences in data obfuscation and tacit approval of my father’s complicity in <a href="https://www.nytimes.com/2017/12/01/opinion/did-america-commit-war-crimes-in-vietnam.html">war crimes</a>? No one’s, absolutely no one’s. This is not the world I want for my children, nor for my fellow Midlanders, nor for my partners-in-crime at Dow.</p>
<p>Putting aside my bitterness, I’d like to give attention to the lights in the darkness—though they are sparse, they burn brightly. My example is from personal experience: Ray Martori, compliance department coordinator for over 10 years, has been the singular most supportive ally I have ever had. It was Ray who approached me one day after noticing in passing that I had disabled read-only mode in Excel. I was mortified when he took me aside, but instead of exacerbating the fear and alienation that I had suffered and borne my whole career, he showed me kindness. He explained to me that I didn’t have to pretend anymore—that I didn’t have to sneak around, modifying vessel overflow logs using other employees’ compromised network accounts by the darkness of night. He told me that I am not alone and that Dow supports people like me whole-heartedly. I felt <a href="https://www.mlive.com/news/bay-city/2014/08/dow_chemical_cos_top-secret_wo.html">tears welling up in my eyes</a> but I still didn’t believe him—I almost didn’t want to. But Ray pressed on. He showed me that Dow, the company I evidently knew nothing about, whose <a href="https://www.sec.gov/Archives/edgar/data/29915/000119312511040023/d10k.htm#tx102245_13">net income in 2010 had exceeded $2B</a>, paid just <a href="https://www.epa.gov/enforcement/dow-chemical-company-settlement">$2.5M</a> for all the downstream death, disease, and financial hardship they caused in the years prior. I remember that moment with such intense detail: all the emotional energy effusing out of me like an <a href="https://www.nytimes.com/1983/05/05/us/dow-says-us-knew-dioxin-peril-of-agent-orange.html">orange mist</a> against a bright blue Vietnamese sky. I collapsed <a href="https://en.wikipedia.org/wiki/Phan_Thi_Kim_Phuc#/media/File:TrangBang.jpg">crying</a> in Ray’s arms. For the first time in my life, I felt seen.</p>
<p>This confession is for everyone who feels like a fraud, like a jigsaw piece that doesn’t fit into the puzzling parameters that our culture assigns us when we’re born, who feels like the game was rigged against them before they even got to the table, who feels like their life experience has been redacted away like the <a href="https://www.nytimes.com/2018/07/28/climate/dow-epa-superfund.html">risks of dioxin</a>. I want you, dear reader, to know that I understand your pain and carry with me a message. I don’t know your situation or ability, but I do know that simply being yourself is an act of rebellion. You don’t have to change all at once, bursting through yourself like a runaway <a href="https://www.nytimes.com/2020/05/20/climate/michigan-dam-dow-chemical-superfund.html">flood through a Superfund site</a>. But slowly, drop by drop, you have the ability to become the most true version of you. Every day, being just a little more authentic. This is an ode to not letting your guilt define you. This is an ode to your actions, however small, eventually <a href="https://en.wikipedia.org/wiki/Dioxins_and_dioxin-like_compounds#Environmental_persistence_and_bioaccumulation">bioaccumulating</a> and becoming something you can be proud of. This is an ode to unmitigated, unregulated, and unaccountable self-care.</p>Michael RosenbergYes, you read that right. Let me explain. For 17 years, I have been working as an environmental policy compliance officer at Dow Chemical in Midland, MI, and, frankly, I love everything about my job. I love being able to work with my hands. I love the comprehensive dental plan. I love the hands-off management style. And I love exploiting the hands-off management style to under-report the amount of polychlorinated dibenzodioxin-based chemical waste that we leak into the Tittabawassee river. I’ll say it loud and I’ll say it with conviction: My name is Daniel Arkos, and I am no longer scared to be myself.Hash Functions are not (Quantum) Random Oracles, but only Technically2020-03-01T00:00:00-05:002020-03-01T00:00:00-05:00https://mrosenberg.pub/cryptography/2020/03/01/qrom<p><em>This post is part of a <a href="/assets/pdfs/qrom_survey.pdf">survey</a> I co-wrote with <a href="https://www.cs.umd.edu/~erblum/">Erica Blum</a> and <a href="https://llamakana.github.io/">Makana Castillo-Martin</a> for a quantum computation class at the University of Maryland in Fall 2019.</em></p>
<p>In this post, we define the Random Oracle Model (ROM) and the Quantum ROM (QROM), and give some examples of their uses and their flaws. We show that the QROM is unsound in the same way that the ROM is, and we conclude that that’s OK.</p>
<h1 id="definitions-and-notation">Definitions and Notation</h1>
<p>I really don’t know what background to assume, but to balance comprehensibility and length of post, I’ve just chosen the things that I had to remind myself about when writing this.</p>
<h2 id="turing-machines">Turing Machines</h2>
<p>You can imagine Turing Machines as abstract machines that run programs specified by some programming language. Like your computer!</p>
<h2 id="random-oracles">Random Oracles</h2>
<p>An <strong>oracle</strong> is an abstraction—a black box—which Turing Machines can query and get a response from. I say “black box” and not “Turing Machine program,” for example, because an oracle is not necessarily a program that can be written down. Rather, it is an abstraction whose inner workings we have no information about. So when we talk about an oracle behaving a certain way, we are describing what kinds of outputs it gives in response to certain inputs, not how the oracle functions internally. When we want to express that a Turing Machine $\mathcal{A}$ has access to an oracle $\mathcal{O}$, we write $\mathcal{A}^\mathcal{O}$. This means that $\mathcal{A}$ can call $\mathcal{O}(x)$ on any input $x$ it pleases.</p>
<div class="math-def">
<p><strong>Definition (informal):</strong> A <strong>random oracle</strong> in a cryptosystem is a publicly accessible oracle (i.e., all parties can query it) which produces random and consistent responses. “Random” means that, until the oracle is queried for the first time on a given input, every possible response is equally likely. “Consistent” means that $\mathcal{O}$ always returns the same value on a given input.</p>
</div>
<p>Notice that implementing a random oracle is hard. You would have to construct a table that contains the output for every possible input. This table would be massive, so when we have to simulate a random oracle in practice, we normally do all this on the fly. That is, for each new input, we generate a new random value and save it in a table along with the input. This way, the oracle can respond consistently to previously seen queries.</p>
<h2 id="turing-reductions">Turing Reductions</h2>
<p>It’s worth it to go over the definition of Turing reduction here, because the purpose of the random oracle model is to permit reductions that were not previously possible (as far as we’re aware).</p>
<div class="math-def">
<p><strong>Definition:</strong> A <strong>Turing Reduction</strong> from problem $X$ to problem $Y$ is a Turing Machine $\mathcal{A}$ such that, if $\mathcal{A}$ is given access to a Turing Machine $\mathcal{Y}$ which solves $Y$, then $\mathcal{A}^\mathcal{Y}$ can efficiently<sup id="fnref:efficient"><a href="#fn:efficient" class="footnote">1</a></sup> solve $X$. We say “$X$ <strong>reduces to</strong> $Y$”, or “$X \leq Y$” if and only if such a machine $\mathcal{A}$ exists.</p>
</div>
<p>In this definition, we take “problem” to mean a question of the form “does this thing satisfy relation $R$” or “what is a thing that makes this satisfy relation $R$”. Examples are</p>
<ul>
<li>Given an integer $N$, what is a prime number that divides $N$? The relation here is
<script type="math/tex">R = \{(N, p) : p \textrm{ prime} \wedge p \mid N \}</script></li>
<li>Given a polynomial $P$ and a value $x$, is $x$ a root of $P$? The relation here is
<script type="math/tex">R = \{(P, x) : P(x) = 0\}</script></li>
</ul>
<h1 id="the-random-oracle-model">The Random Oracle Model</h1>
<p>The Random Oracle Model (introduced in 1993 by <a href="https://cseweb.ucsd.edu/~mihir/papers/ro.pdf">Bellare and Rogaway</a>) was invented as a response to a schism in the cryptographic community in the 1990s: practitioners were implementing all kinds of cryptographic protocols which used hash functions, while theoreticians had no way of proving that these schemes were secure. The aim of the ROM was to bridge this gap by formalizing a small assumption that many were making anyway: hash functions appear to behave randomly. Actually describing what “appear to behave randomly” means is more of an exercise in philosophy than math, so we’ll leave that out.<sup id="fnref:randomly"><a href="#fn:randomly" class="footnote">2</a></sup> But the gist of the formalization is captured in the following definition:</p>
<div class="math-thm">
<p><strong>Definition (informal):</strong> We say that <strong>$X$ reduces to $Y$ in the ROM</strong> if and only if there is a reduction from $X$ to $Y’$, where $Y’$ is the same problem as $Y$ but with every hash function replaced with a random oracle.</p>
</div>
<p>Take note of what is not being said: <strong>no claim is ever made that a reduction which holds in the ROM necessarily holds when hash functions are used instead of random oracles</strong>. Accordingly, and appropriately, <strong>the ROM is considered a heuristic</strong> for cryptosystems which use hash functions; it does not necessarily prove anything about the scheme with hashes. Rogaway and Bellare go out of their way to state precisely this in their introduction of the ROM:</p>
<blockquote>
<p>In order to bring to practice some of the benefits of provable security, it makes sense to incorporate into our models objects which capture the properties that practical primitives really seem to possess, and view these objects as basic even if the assumptions about them are, from a theoretical point of view, very strong…We stress that the proof is in the random oracle model and the last step is heuristic in nature. It is a thesis of this paper that significant assurance benefits nonetheless remain.</p>
</blockquote>
<p>Innumerably many cryptosystems have been proven secure in the ROM (where “proven secure” means “reduced from a problem believed to be hard”). The <a href="https://bristolcrypto.blogspot.com/2015/08/52-things-number-47-what-is-fiat-shamir.html">Fiat-Shamir Transform</a> (which is most often used in the ROM) has, alone, probably been used to construct hundreds of cryptosystems. The argument for the ROM goes deeper, though. <a href="https://eprint.iacr.org/2015/140">Koblitz and Menezes</a> make a strong argument that, not only does the ROM allow us to prove schemes secure that are otherwise unprovably secure (e.g., the Full-Domain Hash signature scheme), but it also gives us constructions that are less brittle to misuse (avoiding things like the duplicate signature key selection attack in the GHR signature scheme).</p>
<p>All this is to say that, while the ROM is just a heuristic, it’s a really really useful one.</p>
<h2 id="hash-functions-are-not-random-oracles">Hash Functions are not Random Oracles</h2>
<p>Earlier I said that no claim is made that hash functions can be modeled as random oracles. And that’s good, because it turns out that it’s false. A neat way of proving this is to construct a digital signature algorithm which is secure in the ROM, but insecure under any choice of hash function. I’ll repeat that because this is really surprising: <strong>there is a signature scheme which is secure in the ROM, but completely insecure under ANY choice of hash function</strong>. As far as I can tell, the first example of such a scheme was given<sup id="fnref:revisitedsig"><a href="#fn:revisitedsig" class="footnote">3</a></sup> in 1998 by CGH, but I’d like to use a different example<sup id="fnref:maurer"><a href="#fn:maurer" class="footnote">4</a></sup> by HMR, which I think is a lot cleaner and which I’ll paraphrase and prove in this section.</p>
<p>Suppose there’s a secure signature scheme<sup id="fnref:euf"><a href="#fn:euf" class="footnote">5</a></sup> $\mathcal{S}$ with signature algorithm $\mathsf{Sign}_k(m)$ where $k$ is the signing key. We define a new signature scheme $\mathcal{Evil}$ with signing algorithm $\mathsf{EvilSign}^\mathsf{H}_k(m)$ which has access access to some oracle $\mathsf{H}$ (we’ll compare the case where $\mathsf{H}$ is an oracle $\mathcal{O}$ versus when it’s a hash function $f$). Denote the security parameter by $\lambda$. On input $m$, $\mathsf{EvilSign}^\mathsf{H}_k$ will calculate $b := \mathsf{D^H}(m)$, where $\mathsf{D}$ is an algorithm we’ll define in a second. If $b = 0$, then the algorithm returns $\mathsf{Sign}_k(m)$, otherwise, it does the completely insecure thing and returns $k$.</p>
<p>$\mathsf{D^H}(m)$ is the algorithm that we use to distinguish between random oracles and hash functions. It exploits the idea that a hash function has a representation as a program, whereas a random oracle needs a massive truth table in order to describe its behavior. $\mathsf{D^\mathsf{H}}$ will interpret its input $m$ as the description of a (Universal Turing Machine) program $\pi$. It then checks whether $\pi(i) = \mathsf{H}(i)$ for all $0 \leq i < 2|\pi|+\lambda$. If this equality fails for any $i$, then $\mathsf{D}$ outputs 0. Otherwise, it outputs 1. We claim two things:</p>
<div class="math-thm">
<p><strong>Claims:</strong></p>
<ol class="Roman-list">
<li>If $\mathsf{H}$ is a hash function $f$, there exists an adversary that can always make $\mathsf{D}$ output 1.</li>
<li>If $\mathsf{H}$ is a random oracle $\mathcal{O}$, $\mathsf{D}$ outputs 0 with high probability (where the probability is taken over random choice of $\mathcal{O}$).</li>
</ol>
<p><strong>Proof of (I):</strong> This one’s easy: the adversary simply sends the encoding of $f$ itself. Then $\pi(i) = \mathsf{H}(i) = f(i)$ for all $i$.</p>
<p><strong>Proof of (II):</strong> This can be proven by bounding the likelihood that there exists a program that can represent the truth table of $\mathcal{O}$. For a moment, let’s consider just programs of length at most $\ell$. Let $q_\ell = 2\ell+\lambda$.</p>
<p>The set of all outputs up to $q_\ell$ of all random oracles, pessimistically assuming that the oracles are binary-valued, is $\{(\mathcal{O}(1), \mathcal{O}(2), \ldots, \mathcal{O}(q_\ell)) : \mathcal{O} : \mathbb{N} \to \{0,1\}\}$. This set has size $2^{q_\ell}$. In comparison, consider the set of program outputs of programs of length at most $\ell$. Again, assume pessimistically that all programs of length at most $\ell$ halt and return binary values. Then the size of the set, $\{(\pi(1), \pi(2), \ldots, \pi(q_\ell)) : |\pi| \leq \ell\}$, is at most $2^{\ell+1}$. This is a much smaller set than that of the oracle outputs. So if $\mathcal{O}$ is chosen randomly, the likelihood that there exists a $\pi$ of length at most $\ell$ that describes $\mathcal{O}$ out to $q_\ell$ many places is</p>
<script type="math/tex; mode=display">p_\ell
= \Pr_{\mathcal{O}}\left[
\exists \pi :
|\pi| \leq \ell
\wedge \mathcal{O}(1) = \pi(1)
\wedge \cdots \wedge \mathcal{O}(q_\ell) = \pi(q_\ell)
\right]
= {\sum_{|\pi| \leq \ell} \Pr_\mathcal{O}\left[
\mathcal{O}(1) = \pi(1)
\wedge \cdots \wedge \mathcal{O}(q_\ell) = \pi(q_\ell)
\right]}
\leq \frac{2^{\ell+1}}{2^{q_\ell}}
= 2^{-\ell-\lambda+1}</script>
<p>Then by the union bound, the probability $p$ that a random oracle has any program $\pi$ that agrees with it at the first $2|\pi| + \lambda$ values is</p>
<script type="math/tex; mode=display">p \leq \sum_{\ell = 0}^\infty p_\ell \leq \sum_{\ell = 0}^\infty 2^{-\ell-\lambda+1} = 2^{-\lambda+2}</script>
<p>which is inverse-exponential in the security parameter.</p>
</div>
<p>If we are in the ROM, then it follows from claim (II) that the only way to construct a forgery in scheme $\mathcal{Evil}$ is to construct a forgery in $\mathcal{S}$. Since $\mathcal{S}$ is assumed to be secure against forgery, this is not possible. Thus, this scheme is secure in the ROM.</p>
<p>Further, it follows from claim (I) that for any choice of hash function $f$, $\mathsf{EvilSign}$ can be completely broken by an efficient adversary. Thus, we have constructed a scheme that is secure in the ROM and insecure under <em>any</em> choice of hash function!</p>
<h2 id="is-the-rom-broken">Is the ROM Broken?</h2>
<p>Given this ridiculous mismatch of security expectations, one may ask: is the ROM a reasonable heuristic to use if it so clearly fails to reflect reality in at least one cryptosystem? This is a matter of opinion.</p>
<p>The $\mathcal{Evil}$ cryptosystem above is a pathological example by any standard. The signature function is literally programmed to reveal the secret key some of the time. It turns out that weird examples like these are actually the only examples we have of the ROM failing to hold up in the real world. Further, there are a handful of examples where avoiding the ROM has actually introduced exploitable vulnerabilities into a cryptosystem<sup id="fnref:standardvulns"><a href="#fn:standardvulns" class="footnote">6</a></sup>. These vulnerabilities normally arise from, in a broad sense, things having too much algebraic structure.</p>
<p>On the other hand, an unrealistic model is an unrealistic model. If there is a cryptosystem, albeit a contrived one, which serves as a counterexample to the claim that hash functions are interchangeable with random oracles, then why should we believe that there are some cryptosystems in which this claim is true?<sup id="fnref:revisited"><a href="#fn:revisited" class="footnote">7</a></sup> We don’t have any proofs so far of being able to model a hash function with a random oracle in a certain cryptosystem, only counterexamples.</p>
<p>I’ll hold off weighing in until the conclusion, but I think this is a reasonable question to ask, and not one that science or math can really answer. This is one of those cases where philosophy intersects cryptography in a way that can affect what people choose to research and how they construct their solutions.</p>
<h1 id="the-quantum-random-oracle-model">The Quantum Random Oracle Model</h1>
<p>It turns out that we have to go through this same moral conundrum when we talk about the QROM, because $\mathcal{Evil}$ is secure in the QROM too! Again, to be concrete, <strong>there is a signature scheme that is secure against quantum-capable adversaries in the QROM, but completely insecure for ANY choice of hash function</strong>. To get to this claim, we’ll need some of the basics of quantum computation theory.</p>
<h2 id="a-quick-rundown-of-quantum-computation">A Quick Rundown of Quantum Computation</h2>
<p>“Qubit” is a fancy term you might have heard before. A qubit is the most basic unit of data in Quantum Land, so it’ll be worth it to give a rigorous definition. First, we often fix the number of qubits in a system by fixing the dimension of the system. In particular, we say that a <strong>$b$-qubit system</strong> is a subset of $\mathbb{C}^{2^b} \cong \mathbb{C}^2 \otimes \cdots \otimes \mathbb{C}^2$ (tensored $b$ many times). A <strong>qubit</strong> is an element of the unit sphere $B = \{\|z\| = 1 : z \in \mathbb{C}^{2^b}\}$ (where the norm is the $L_2$ norm). The operations on qubits we care about are <strong>unitary operators</strong>, i.e., linear functions that preserve length, i.e., linear functions from $\mathbb{C}^{2^b}$ to $\mathbb{C}^{2^b}$ which map $B$ to $B$. We represent the $i$-th basis vector (0-indexed) of $\mathbb{C}^{2^b}$ by writing $\langle \mathsf{bin}(i)\rangle$, where $\mathsf{bin}(i)$ denotes the binary expansion of $i$.<sup id="fnref:braket"><a href="#fn:braket" class="footnote">8</a></sup> So for example, $\langle 000 \rangle$ denotes the 0-th basis vector of $\mathbb{C}^8$ (<em>not</em> the zero vector!), and $\langle 011 \rangle$ denotes the 3rd basis vector. Sometimes we will want to split up the basis vector label into two parts. To denote this, we say $\langle x,y \rangle = \langle x \| y\rangle $, i.e., the concatenation of the binary strings $x$ and $y$. For example, $\langle 001, 011 \rangle = \langle 001011 \rangle$.</p>
<p>Notice that the set of bitstrings of length $b$ is in bijection with the basis vectors of $\mathbb{C}^{2^b}$, so we can talk about “linear combinations of bitstrings” in a way that makes sense. For example, $v = (1/\sqrt{2})\cdot \langle 110 \rangle - (i/\sqrt{2})\cdot \langle 010\rangle$ is a vector in $B$. We say that this qubit $v$ represents a <strong>superposition</strong> of the bitstrings $\langle 110\rangle$ and $\langle 010\rangle$. This representation as the linear combination of bitstrings is unique for the same reason that the representation of a vector in terms of the standard basis is unique.</p>
<p>We can define linear operators that act on these bitstrings by defining mappings from basis elements to basis elements. For example, if $f$ is a function from $\{0,1\}^3$ to $\{0,1\}^3$ (i.e., bitstrings of length 3 to bitstrings of length 3), and $f(010) = 111$, then we can define a linear operator $F$ that takes $\langle 010\rangle$ to $\langle 111\rangle$. This gives a unitary operator whenever $f$ is a bijection on the bitstrings. But what if $f$ isn’t a bijection? What if $f(001) = f(010) = 111$? Then you can use a neat trick: define $F$ such that it takes the basis vector $\langle x, y \rangle$ to $\langle x, y \oplus f(x)\rangle$. This trick works because the output “remembers” the input, so the function is always invertible. For example,</p>
<script type="math/tex; mode=display">F(\langle 010, 000 \rangle) = \langle 010, 111 \rangle
\quad\textrm{and}\quad
F(\langle 001, 000 \rangle) = \langle 001, 111 \rangle</script>
<p>Operators that are defined like this are almost always given $y = 0$. Finally, notice that we had to make the dimension of the space larger, and thus increase the number of qubits in our system in order to accommodate more bits. Indeed, doubling the dimension to account for non-injectivity of bit-valued functions is common practice.</p>
<p>Alright, that’s about all the background necessary to present the QROM and the final result.</p>
<h2 id="quantum-random-oracles">Quantum Random Oracles</h2>
<p>The QROM (introduced in 2010 by <a href="https://eprint.iacr.org/2010/428.pdf">Boneh et al.</a>) comes from a simple insight: if we believe that quantum computers could run hash function circuits in superposition (and we do), then why don’t we model hash functions as random oracles, but more quantum-y? This is, in essence, the same idea as the ROM, except the random oracles are allowed to be queried in quantum superposition. More specifically,</p>
<div class="math-def">
<p><strong>Definition:</strong> Given a random oracle $\mathcal{O}$, the associated <strong>quantum random oracle</strong> $\mathcal{O}_\mathrm{quant}$ is the unitary operator that maps a superposition of bitstrings to the superposition of its values when evaluated with $\mathcal{O}$. Concretely, for every basis vector $\langle x, y \rangle$, define</p>
<script type="math/tex; mode=display">\mathcal{O}_\mathrm{quant}(\langle x, y \rangle) := \langle x, y \oplus \mathcal{O}(x)\rangle</script>
</div>
<p>By this definition, $\mathcal{O}_\mathrm{quant}$ is a unitary operator, so it makes sense to say</p>
<script type="math/tex; mode=display">\mathcal{O}_\mathrm{quant}\left(
\frac{1}{\sqrt 3} \langle 010, 000 \rangle
+ \frac{i}{\sqrt 3} \langle 011, 000 \rangle
- \frac{i}{\sqrt 3} \langle 110, 000 \rangle
\right)
=
\frac{1}{\sqrt 3} \langle 010, \mathcal{O}(010) \rangle
+ \frac{i}{\sqrt 3} \langle 011, \mathcal{O}(011) \rangle
- \frac{i}{\sqrt 3} \langle 110, \mathcal{O}(110) \rangle</script>
<p>Notice that a quantum random oracle is at least as powerful as a random oracle, since you can always query with the superposition of just a single value:</p>
<script type="math/tex; mode=display">\mathcal{O}_\mathrm{quant}(\langle x, 0 \rangle) = \langle x, \mathcal{O}(x)\rangle</script>
<p>In fact, quantum random oracles are strictly more powerful than classical random oracles. Boneh et al. show a <em>separation result</em>. In particular, they present an identification scheme that is secure in the ROM, and insecure in the QROM.<sup id="fnref:separation"><a href="#fn:separation" class="footnote">9</a></sup></p>
<h2 id="quantum-hash-functions-are-not-quantum-random-oracles">Quantum Hash Functions are not Quantum Random Oracles</h2>
<p>Since the QROM is strictly more powerful than the ROM, it follows that QROM-security implies ROM-security. But we’d like to show that the ROM-secure $\mathcal{Evil}$ scheme above is also QROM-secure. Luckily, Boneh et al. also give us the conditions for when this converse statement is true.</p>
<div class="math-thm">
<p><strong>Theorem:</strong> If a reduction to a problem $P$ holds in the ROM, and the reduction is history-free, then the reduction to problem $P$ holds in the QROM as well.</p>
</div>
<p>A <strong>history-free</strong> reduction is defined formally in the paper, but it suffices to say that a history-free reduction is a reduction that does not rewind its solver $\mathcal{Y}$, does not record the oracle queries, and does not modify oracle behavior based on previous queries.</p>
<p>Recall that the above proof of security in the ROM was actually a reduction to the security of the underlying hypothetical signature scheme $\mathcal{S}$. To prove QROM-security, we need to tweak the assumption a bit: instead of assuming that $\mathcal{S}$ is secure against classical adversaries, we need to further assume it is secure against quantum-capable adversaries. Admitting this, the only thing that needs to be shown is that the proof of ROM-security of $\mathcal{Evil}$ is history-free. Indeed, the reduction never recorded queries, rewound the solver, or modified its own behavior, so it’s pretty clear that it’s history free.<sup id="fnref:proof"><a href="#fn:proof" class="footnote">10</a></sup></p>
<h1 id="conclusions">Conclusions</h1>
<p>And that’s it! We’ve just constructed a signature scheme (assuming the existence of a quantum-secure<sup id="fnref:euf:1"><a href="#fn:euf" class="footnote">5</a></sup> signature scheme) that is secure against quantum adversaries when modeling the hash functions as quantum-accessible random oracles, but is completely insecure under <em>any</em> choice of hash function!</p>
<p>I want to reiterate that the failure of the (Q)ROM to reflect real-world security should not necessarily be taken as a sign that we should stop using it, though some argue precisely that. My personal, highly unqualified opinion is that this construct has given us far more than it’s taken, and despite the fact that it sometimes fails to tell us something about our world, I am convinced, as Rogaway and Bellare are, that it captures “the properties that practical primitives really seem to possess.”</p>
<div class="footnotes">
<ol>
<li id="fn:efficient">
<p>“Efficient” meaning polynomial-time in the size of its inputs. Also of course not every Turing reduction is polynomial time, but there’s only so much couching I can do before I lose everyone. <a href="#fnref:efficient" class="reversefootnote">↩</a></p>
</li>
<li id="fn:randomly">
<p>This is hard because the obvious definition of random is “given a bunch of input-output pairs, you are unable to tell anything about the output on any input you haven’t already seen”. In the context of a random oracle, this makes sense, because an oracle would be chosen at random at the beginning of the experiment. But for a hash function, if the hash function is publicly known, then the adversary can just make the queries itself. If we instead sample from a family of hash functions, that would eliminate that problem, but the ROM-secure schemes we’re talking about aren’t ones which randomly sample from a hash function family in every instantiation. <a href="#fnref:randomly" class="reversefootnote">↩</a></p>
</li>
<li id="fn:revisitedsig">
<p>Section 4 in <a href="https://eprint.iacr.org/1998/011">Canetti, Goldreich, Halevi</a> <a href="#fnref:revisitedsig" class="reversefootnote">↩</a></p>
</li>
<li id="fn:maurer">
<p>Section 2 in <a href="https://eprint.iacr.org/2003/161">Holenstein, Maurer, Renner</a> <a href="#fnref:maurer" class="reversefootnote">↩</a></p>
</li>
<li id="fn:euf">
<p>As a reminder, a digital signature scheme consists of algorithms $\mathsf{KeyGen}$, $\mathsf{Sign}$, and $\mathsf{Ver}$. By “secure” I mean EUF-CMA-secure, meaning that an adversary can’t forge a valid signature for a message it’s never seen before. And by “quantum-secure” I mean the same thing but against a quantum-capable adversary. <a href="#fnref:euf" class="reversefootnote">↩</a> <a href="#fnref:euf:1" class="reversefootnote">↩<sup>2</sup></a></p>
</li>
<li id="fn:standardvulns">
<p><a href="https://eprint.iacr.org/2015/140.pdf">This paper</a> by Koblitz and Menezes presents good arguments for what the ROM has bought us and what avoiding the ROM has wreaked. <a href="#fnref:standardvulns" class="reversefootnote">↩</a></p>
</li>
<li id="fn:revisited">
<p><a href="https://eprint.iacr.org/1998/011">Canetti, Goldreich, Halevi</a> generally argue that the ROM should be avoided for this reason. <a href="#fnref:revisited" class="reversefootnote">↩</a></p>
</li>
<li id="fn:braket">
<p>I know that this notation is nonstandard, but I’m not using bra-ket notation because it’s not necessary for the rest of this piece. <a href="#fnref:braket" class="reversefootnote">↩</a></p>
</li>
<li id="fn:separation">
<p>This is section 3 in <a href="https://eprint.iacr.org/2010/428.pdf">Boneh et al.</a> The gist is there is an identification scheme that will either do the correct thing, or do the insecure thing if the adversary is able to compute some number of hash collisions in $O(\sqrt[3]{N})$ time. Since the best you can do in the classical case is find a collision with probability 1/2 in $O(\sqrt N)$ time, this is secure for all classical adversaries. But a quantum adversary running Grover’s algorithm can compute several collisions in $O(\sqrt[3]{N})$ time with high probability. <a href="#fnref:separation" class="reversefootnote">↩</a></p>
</li>
<li id="fn:proof">
<p>I left out the details here only because it’s very boring and takes up a bunch of space. If you want read the full proof, see section 3.2 in the aforementioned <a href="/assets/pdfs/qrom_survey.pdf">survey paper</a>. <a href="#fnref:proof" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Michael RosenbergThis post is part of a survey I co-wrote with Erica Blum and Makana Castillo-Martin for a quantum computation class at the University of Maryland in Fall 2019.Supersingular Isogeny Key Exchange for Not-Quite Beginners2020-01-08T00:00:00-05:002020-01-08T00:00:00-05:00https://mrosenberg.pub/cryptography/2020/01/08/sidh<p>I recently read a <a href="https://eprint.iacr.org/2019/1321">great introductory paper</a> on Supersingular Isogeny Diffie-Hellman (SIDH) by Craig Costello and wanted to summarize just the math of it (with some simplifications) for myself. Hopefully this summary is clear enough to also be useful to people who aren’t myself.</p>
<h1 id="background">Background</h1>
<p>We deal with supersingular (we won’t define this word) elliptic curves defined over finite fields of the form $\mathbb{F}_{p^2}$.</p>
<p>For SIDH, we deal only with curves such that $E(\mathbb{F}_{p^2}) \cong \mathbb{Z}_{p+1} \times \mathbb{Z}_{p+1}$. The kernel of the left multiplication map $P \to [a]P$ is of the form $\mathbb{Z}_a \times \mathbb{Z}_a$. We say that a map $\phi: E \to E’$ is an $\ell$-isogeny iff $|\ker \phi| = \ell$. Notice that $\ell$-isogenies only exist for $\ell \mid p+1$. Every $\ell$-isogeny $\phi: E \to E’$ also has an associated $\ell$-isogeny, called the dual isogeny $\psi: E’ \to E$, such that $\phi \circ \psi$ is the left-multiplication map $[\ell]$. Vélu’s formulas tell us that every subgroup $G \leq E$ corresponds to a unique isogeny out of $E$ (to some curve $E’$) with kernel G. They also tell us how to construct an isogeny given its desired kernel.</p>
<div class="math-thm">
<p><strong>Claim:</strong> On a supersingular curve $E$ of the form above, for any prime $\ell \mid p+1$, there are exactly $\ell+1$ nontrivial $\ell$-isogenies out of $E$.</p>
<p><strong>Proof:</strong> Using Vélu’s formulas, it suffices to show that E has exactly $\ell+1$ many subgroups of prime order $\ell$. Firstly, since these are of order $\ell$, they all must be subgroups of $E[\ell] \cong \mathbb{Z}_\ell \times \mathbb{Z}_\ell$. Let $P$ and $Q$ denote the free generators of $E[\ell]$.
Consider the family of cyclic subgroups generated by $P + [k]Q$ for $0 \leq k < \ell$. We claim that these are not only distinct, but disjoint. Suppose for distinct $k$, $k’$ that</p>
<script type="math/tex; mode=display">\alpha(P + [k]Q) = \beta(P + [k']Q)</script>
<p>for some integers $\alpha$, $\beta$. Rearranging,</p>
<script type="math/tex; mode=display">[\alpha]P - [\beta]P = [\beta k]Q - [\alpha k']Q</script>
<p>Since $P$ and $Q$ are linearly independent, both sides of this equation must be the identity. Therefore,</p>
<script type="math/tex; mode=display">\alpha \equiv \beta\ (\textrm{mod } \ell)</script>
<p>Putting this together with the fact that the RHS is the identity,</p>
<script type="math/tex; mode=display">\beta k \equiv \alpha k' \equiv \beta k'\ (\textrm{mod } \ell),</script>
<p>we conclude $k \equiv k’\ (\textrm{mod } \ell)$. This gives us a family of $\ell$ many disjoint subgroups. The final subgroup to include is the one generated by $Q$. It is clear that this is also disjoint from the previously mentioned subgroups. Finally, there cannot be any more order $\ell$ subgroups, since we have listed all the possible cyclic subgroups of $\mathbb{Z}_\ell \times \mathbb{Z}_\ell$, and all groups of prime order are cyclic.</p>
</div>
<p>A <strong>supersingular $\ell$-isogeny graph</strong> is a graph whose nodes are $j$-invariants (i.e., elements of $\mathbb{F}_{p^2}$ which are in bijective correspondence with isomorphism classes of elliptic curves) and whose edges represent $\ell$-isogenies between them. Note this is an undirected graph because every $\ell$-isogeny has a dual $\ell$-isogeny going in the other direction. Also, by the above claim, every node has degree $\ell+1$. It turns out that this is an expander graph, which means random walks on it mix quickly. In other words, the diameter of an expander graph on $N$ elements is roughly $\log(N)$. SIDH exploits this property to make its security claims.</p>
<h1 id="sidh">SIDH</h1>
<p>The purpose of SIDH is to compute a shared secret by exchanging public keys. Same idea as Diffie Hellman.</p>
<h2 id="public-parameters">Public Parameters</h2>
<ul>
<li>A prime $p = 2^{e_A}3^{e_B} - 1$. This way, $p+1$ is divisible by powers of 2 and 3. $e_A$ and $e_B$ are chosen so that $2^{e_A} \approx 3^{e_B}$.</li>
<li>A starting curve $E$ defined over $\mathbb{F}_{p^2}$</li>
<li>Two points $P_A,Q_A \in E$ such that $\langle P_A, Q_A \rangle \cong \mathbb{Z}_{2^{e_A}} \times \mathbb{Z}_{2^{e_A}}$.</li>
<li>Two points $P_B,Q_B \in E$ such that $\langle P_B, Q_B \rangle \cong \mathbb{Z}_{3^{e_B}} \times \mathbb{Z}_{3^{e_B}}$.</li>
</ul>
<h2 id="protocol">Protocol</h2>
<p>Here’s the gist of the protocol: Alice takes a walk on a 2-isogeny graph and marks her stopping point. Bob takes a walk on a 3-isogeny graph and marks his stopping point. The constraint that $2^{e_A} \approx 3^{e_B}$ means that the number of possible stopping points that Alice can get to is roughly equal to the number of possible stopping points Bob can get to. They then share their stopping points with each other. Then both of them do the same walks as before, but starting at each other’s stopping point. The final endpoints of Alice’s and Bob’s walks are isomorphic (as elliptic curves, since points on the isogeny graph are curves), which means they have the same $j$-invariant.</p>
<p>Concretely, here’s the protocol sequence. Alice initiates:</p>
<p><strong>Alice:</strong></p>
<ol>
<li>Picks a random secret scalar $0 \leq k_A < 2^{e_A}$ and defines a secret generator $S_A = P_A + [k_A]Q_A$. Note that $S_A$ has order $2^{e_A}$ because $P_A$ and $Q_A$ are linearly independent. By the proof above, all the possible subgroups $\langle S_A\rangle$ are disjoint.</li>
<li>Constructs a $2^{e_A}$-isogeny $\phi_A: E \to E/\langle S_A\rangle$. This is done iteratively by repeatedly constructing 2-isogenies with elements of $\langle S_A\rangle$ in the kernel. The way you do this is by getting a point $R_A = [2^{e_A-1}]S_A$ of order 2. Using Vélu’s formulas, you can construct a $\phi_0: E \to E/\langle R_A\rangle$. Now let $S’_A = \phi_0(S_A)$. Then $S’_A$ has order $2^{e_A-1}$. Let $R’_A = [2^{e_A-2}]S’_A$, … Once you’ve constructed $\phi_0$, …, $\phi_{e_A}$, let $\phi_A$ be the composition of all of these.</li>
<li>Sends Bob $(\phi_A(E), \phi_A(P_B), \phi_A(Q_B))$, where $\phi_A(E)$ is the description of the output curve. We call this tuple Alice’s “public key”.</li>
</ol>
<p><strong>Bob:</strong></p>
<ol>
<li>Picks a secret $0 < k_B ≤ 3^{e_B}$, lets $S_B = P_B + [k_B]Q_B$, and constructs a $3^{e_B}$-isogeny $\phi_B: E \to E/\langle S_B\rangle$ in the same way as above.</li>
<li>Sends Alice $(\phi_B(E), \phi_B(P_A), \phi_B(Q_A))$. We call this tuple Bob’s “public key”.</li>
</ol>
<p><strong>Alice:</strong></p>
<ol>
<li>Uses the same method to construct $\psi_A: \phi_B(E) \to \phi_B(E)/\langle T_A\rangle$ where
<script type="math/tex">T_A = \phi_B(S_A) = \phi_B(P_A) + [k_A]\phi_B(Q_A)</script></li>
<li>Computes the $j$-invariant of $\psi_A(\phi_B(E))$</li>
</ol>
<p><strong>Bob:</strong></p>
<ol>
<li>Same idea as above: Construct $\psi_B: \phi_A(E) \to \phi_A(E)/\langle T_B\rangle$ where
<script type="math/tex">T_B = \phi_A(S_B) = \phi_A(P_B) + [k_B]\phi_A(Q_B)</script></li>
<li>Computes the $j$-invariant of $\psi_B(\phi_A(E))$</li>
</ol>
<p><strong>End of Protocol</strong></p>
<p>Note that, since $j$-variants of isomorphic curves are equal, and</p>
<script type="math/tex; mode=display">(E/\langle S_A\rangle)/\langle T_B\rangle \cong E/\langle S_A, S_B\rangle \cong (E/\langle S_B\rangle)/\langle T_A\rangle,</script>
<p>the computed $j$-invariants are the same. Thus, it makes sense to have the $j$-invariant be the shared secret.</p>
<h1 id="an-attack-on-static-public-keys">An Attack on Static Public Keys</h1>
<p>This attack is due to <a href="https://eprint.iacr.org/2016/859">Galbraith, Petit, Shani, and Ti</a>. If Alice keeps reusing the same $k_A$, Bob can determine its value by by initiating $\lceil\log_2(k_A)\rceil$ many SIDH exchanges. Here’s the exploit:</p>
<p>Bob can figure out the bottom bit of $k_A$ by publishing $\phi_B(Q_A) + L_2$ instead of $\phi_B(Q_A)$, where $L_2$ is a point of order 2. If $k_A$ is odd, i.e., if $L_2$ is not killed by $k_A$, then the protocol does not produce agreement, because $T_A + L_2$ is not the image of $S_A$ in Bob’s curve $\phi_B(E)$. If $k_A$ is even, then $L_2$ is killed by $k_A$ and the protocol completes successfully. Thus, the bottom bit is leaked.</p>
<p>Say Bob finds it was even. Now Bob wants to know if $k_A \equiv 0\ (\textrm{mod } 4)$ or $2\ (\textrm{mod } 4)$. Then he sends $\phi_B(Q_A) + L_4$ where $L_4$ is a point of order 4, and uses the same logic. If Bob had found $k_A$ was odd, then he would send $\phi_B(P_A) - L_4$ instead of $\phi_B(P_A)$, and $\phi_B(Q_A) + L_4$ instead of $\phi_B(Q_A)$. So if $k_A$ is $1\ (\textrm{mod } 4)$, then</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align*}
&\phi_B(P_A) - L_4 + k_A(\phi_B(Q_A) + L_4)
\\&= \phi_B(P_A) - L_4 + [k_A]\phi_B(Q_A) + L_4
\\&= \phi_B(P_A) + [k_A]\phi_B(Q_A)
\end{align*} %]]></script>
<p>and the protocol succeeds. Otherwise,</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align*}
&\phi_B(P_A) - L_4 + k_A(\phi_B(Q_A) + L_4)
\\&= \phi_B(P_A) - L_4 + [k_A]\phi_B(Q_A) + [3]L_4
\\&= \phi_B(P_A) + [k_A]\phi_B(Q_A) + [2]L_4
\end{align*} %]]></script>
<p>and the protocol fails. Bob can continue like this to recover each successive bit of $k_A$.</p>
<h1 id="patching-it-up">Patching it up</h1>
<p>How do you prevent the above attack from working? Ideally, Alice would like to be able to tell when she receives a malicious public key, i.e., one of the form $\phi_B(Q_A) + L$ for some low-order point $L$. If she could do this, then she would be able to terminate the protocol early and not reveal anything about the shared secret.</p>
<p>Unfortunately, given just a public key share, there’s no way to tell if a given it was modified in this way or not.</p>
<p>But what if Alice was given more than a public key share? What if Bob somehow gave Alice his <em>private</em> ephemeral key as well? Then Alice would be able to compute Bob’s public key share from his private key and check that it matches the one she received from Bob. If they match, then the public key was honest and the protocol completes successfully. If they don’t match, then Alice can conclude that Bob cheated and she can abort the protocol early. This is precisely what the <a href="https://sike.org/">SIKE</a> key encapsulation mechanism does. Here’s the new protocol (a little simplified):</p>
<p><strong>Alice</strong></p>
<ol>
<li>Picks her secrets randomly, as before</li>
<li>Publishes her public key $pk_A$, computed as before (i.e., a description of a curve, and two points on that curve)</li>
</ol>
<p><strong>Bob</strong></p>
<ol>
<li>Picks a random bitstring $m$</li>
<li>Computes his secret scalar $k_B = G(m \| pk_A)$, where $G$ is a pseudorandom number generator. He also computes the corresponding public key $pk_B$.</li>
<li>Computes the $j$-invariant of the SIDH exchange (as described above) between $k_B$ and $pk_A$</li>
<li>Derives a symmetric key $\kappa = \textrm{KDF}(j)$, where $\textrm{KDF}$ is some key-derivation function.</li>
<li>Computes $c = \textrm{Enc}_\kappa(m)$, where $\textrm{Enc}$ is the encryption function for some symmetric encryption scheme.</li>
<li>Sends Alice the tuple $(pk_B, c)$</li>
<li>Computes the shared secret (to be used if the protocol complete successfully) $K = \textrm{KDF}(m \| k_B \| c)$.</li>
</ol>
<p><strong>Alice</strong></p>
<ol>
<li>Uses $pk_B$ and her secret $k_A$ to derive the $j$-invariant, denoted $j’$</li>
<li>Computes $\kappa’ = \textrm{KDF}(j’)$</li>
<li>Decrypts $m’ = \textrm{Dec}_{\kappa’}(c)$ (recall Alice received $c$ from Bob)</li>
<li>Computes the secret scalar $k_B’ = G(m’ \| pk_A)$ and its corresponding public key $pk_B’$</li>
<li>Checks that $pk_B’ = pk_B$. If these are not equal, the protocol aborts.</li>
<li>Derives the shared secret $K = \textrm{KDF}(m’ \| k_B’ \| c)$</li>
</ol>
<h2 id="analysis">Analysis</h2>
<p>Let’s give an informal sketch of how this prevents information leakage.</p>
<p>Say Bob wants Alice to leak the lowest bit of her secret scalar $k_A$. The only leakage mechanism he has access to is learning whether the protocol succeeded or failed (since this can be used to convey a bit of information). He needs the protocol to do one thing when $k_A$ is even, and the other thing if it’s odd.</p>
<p>If Bob computes and conveys everything honestly (i.e., as described in this new protocol), then it should be clear that the protocol succeeds with 100% probability. Thus, this leaks nothing. If Bob lies about $c$, then $m’ = \textrm{Dec}_{\kappa’}(c)$ is certainly going to differ from $m$,<sup id="fnref:caveat"><a href="#fn:caveat" class="footnote">1</a></sup> which results in a different $k’_B$ and thus a different $pk_B’$. So that strategy causes the protocol to always fail with overwhelming probability, and thus leak nothing.</p>
<p>So what if Bob lies about $pk_B$ and tries the “add a low-order point” trick from the previous section? As before, this gives Bob control over the value $j’$ that Alice derives. If $k_A$ is even, it will be the same as Bob’s $j$, and if it’s odd it will be different. So far so good. Continuing on the “good” branch, if $j’ = j$, then Alice’s steps 2, 3, and 4 all continue to derive the same values as Bob’s. In step 5, Alice can see that the $pk_B$ she received doesn’t match the public key corresponding to $k_B’$, so Alice aborts. On the “bad” branch, if $j’ \neq j$, then all the values derived in steps 2, 3, and 4 are wrong, and Alice is certain to abort. Thus, this strategy also causes the protocol to always fail with overwhelming probability, thus leaking nothing!</p>
<p>I hope that explanation was understandable. The way the authors of SIKE prove security is actually far more elegant than this: it turns out that the “patch” I described above is a result of a much more general theorem.<sup id="fnref:fuji"><a href="#fn:fuji" class="footnote">2</a></sup> Also, the patch I presented isn’t totally accurate, so if you want more detail I encourage you to check out the <a href="https://sike.org/files/SIDH-spec.pdf">spec</a> (algorithms 1 and 2, and the proofs of security in section 4.3).</p>
<div class="footnotes">
<ol>
<li id="fn:caveat">
<p>This relies on some assumption about the symmetric key primitive and on $\textrm{KDF}$, so that even if you modified $j’$ as well, you couldn’t get $c$ to decrypt to a chosen plaintext <a href="#fnref:caveat" class="reversefootnote">↩</a></p>
</li>
<li id="fn:fuji">
<p>The FO transformation is precisely made to turn an IND-CPA PKE into an IND-CCA PKE with very little overhead. <a href="https://cs.uni-paderborn.de/fileadmin/informatik/fg/cuk/Lehre/Abschlussarbeiten/Bachelorarbeiten/2014/BA_Lippert_FOT_final.pdf">Here</a>’s a paper describing what it is and how it works. <a href="https://eprint.iacr.org/2017/604">Here</a> is the extremely influential paper that the authors of SIKE cite. <a href="#fnref:fuji" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Michael RosenbergI recently read a great introductory paper on Supersingular Isogeny Diffie-Hellman (SIDH) by Craig Costello and wanted to summarize just the math of it (with some simplifications) for myself. Hopefully this summary is clear enough to also be useful to people who aren’t myself.Better Encrypted Group Chat2019-07-10T00:00:00-04:002019-07-10T00:00:00-04:00https://mrosenberg.pub/cryptography/2019/07/10/molasses<h1 id="introducing-molasses">Introducing molasses</h1>
<p>Broadly, an end-to-end encrypted messaging protocol is one that ensures that only the participants in a conversation, and no intermediate servers, routers, or relay systems, can read and write messages. An end-to-end encrypted <em>group</em> messaging protocol is one that ensures this for all participants in a conversation of three or more people.</p>
<p>End-to-end encrypted group messaging is a necessary problem to solve. Whether it be for limiting liability, providing verifiable client-side security, or removing a single point of failure, there <a href="https://medium.com/@RiotChat/why-we-need-end-to-end-encryption-for-online-communications-e7448e0be2c3">are</a> <a href="https://www.schneier.com/academic/paperfiles/paper-keys-under-doormats-CSAIL.pdf">good</a> <a href="https://www.nytimes.com/2019/07/01/opinion/slack-chat-hackers-encryption.html">reasons</a> for a group messaging host to use an end-to-end encrypted protocol.</p>
<p>Existing solutions such as Signal, WhatsApp, and iMessage have inherent problems with scaling, which I’ll discuss in detail, that make it infeasible to conduct group chats of more than a few hundred people. The <a href="https://datatracker.ietf.org/doc/draft-ietf-mls-protocol/">Message Layer Security (MLS)</a> protocol aims to make end-to-end group chat more efficient while still providing security guarantees like forward secrecy and post-compromise security.<sup id="fnref:pcs"><a href="#fn:pcs" class="footnote">1</a></sup></p>
<p>To these ends, I have been working on <a href="https://github.com/trailofbits/molasses"><code class="language-plaintext highlighter-rouge">molasses</code></a>, a Rust implementation of MLS, designed with safety, ease-of-use, and difficulty-of-misuse in mind.</p>
<h2 id="molasses-has-helped-refine-the-mls-spec">Molasses has helped refine the MLS spec</h2>
<p>The primary contribution of <code class="language-plaintext highlighter-rouge">molasses</code> has been in detecting errors in the specification and other implementations through unit and interoperability testing. <code class="language-plaintext highlighter-rouge">molasses</code> implements most of MLS draft 6. Why not all of draft 6? There was an error in the spec that made it impossible for members to be added to any group. This broke all the unit tests that create non-trivial groups. Errors like this are hard to catch just by reading the spec; they require some amount of automated digging. Once they are found, the necessary revisions tend to be pretty obvious, and they are swiftly incorporated into the subsequent draft.</p>
<p>Iterating this discovery/patching process using <code class="language-plaintext highlighter-rouge">molasses</code> has given me a chance to put the spec through its paces and help make things clearer. This winter internship (also called a “winternship” by nobody) project has been a great experience, especially as a first-time IETF contributor.</p>
<h1 id="how-to-build-encrypted-group-chat">How to build encrypted group chat</h1>
<p>In this section we derive why MLS is constructed the way it is (hint: for efficiency reasons), and how it compares to other solutions (hint: it’s better).</p>
<p>First off, MLS works on a lower level than most chat applications. It is a protocol upon which applications can be built. For example, MLS does not govern group permissions such as who can add people to the chat (this can be done at the application level while using MLS under the hood). Thus, we can leave things like formal rule systems out of the conversation entirely when analyzing the protocol. Here, we’re only going to consider the sending of messages and the removal of members.</p>
<p>The constructions in this section make use of cryptographic primitives such as digital signatures, Diffie-Hellman key exchange, (a)symmetric encryption, and key-derivation functions. If the reader feels underprepared in any of these areas, a quick skim of the sections in <a href="https://nostarch.com/seriouscrypto"><em>Serious Cryptography</em></a> on ECIES and Authenticated Diffie-Hellman should be sufficient.</p>
<p>Without further ado,</p>
<h2 id="a-motivating-problem">A Motivating Problem</h2>
<p>Wilna is planning a retirement party for an acquaintance, Vince. The logistics are a nightmare, so she invites her friends Xavier, Yolanda, and Zayne to help her plan. They would like to make a group chat on Slack so they can all stay on the same page, but they remember that Vince is an infrastructure manager for Slack—he can see <em>all</em> the messages sent over any Slack server in the world. This is a problem, since they want to give Vince a nice long vacation upstate and they want it to be a surprise. Vince’s position poses even more problems: he happens to manage every single server in town. Even if Wilna purchases her own server to mediate the group chat, Vince will be tasked with managing it, meaning that he can read everything the server stores.</p>
<p>What Wilna needs is a <strong>centralized end-to-end encrypted group chat</strong>, i.e., a group chat where every member can broadcast messages and read all incoming messages, but the single server that mediates these messages cannot read anything. For clarity, we’ll distinguish between <strong>application messages</strong>, which carry the textual content of what a group member wants to say to everyone else in the group, and <strong>auxiliary messages</strong> (called “Handshake messages” in MLS), which members use to manage group membership and cryptographic secrets. Since this is all mediated through one server, the members can rely on the server to broadcast their messages to the rest of the group.</p>
<p>With the setup out of the way, what are the options?</p>
<h2 id="solution-1-pairwise-channels">Solution #1: Pairwise Channels</h2>
<p>Suppose Wilna, Xavier, Yolanda, and Zayne all know each other’s public keys for digital signatures. This means that each pair of people can do an authenticated Diffie-Hellman key exchange over some auxiliary messages and derive a shared symmetric key called the <strong>pair key</strong>. This process produces six separate <strong>pairwise channels</strong>, represented here:</p>
<p><img src="/assets/images/post_molasses/pairwise_channels.svg" alt="pairwise channels between 4 members" /></p>
<p>If Wilna wants to send an application message <em>m</em> to the group, she has to encrypt it three separate times (once for each member of the group) and send all the ciphertexts:</p>
<figure class="">
<p><img src="/assets/images/post_molasses/pairwise_app_msg.svg" alt="Pairwise encryption of application message" /></p>
<figcaption>
<p>The grey arrows represent application messages encrypted under a symmetric key.</p>
</figcaption>
</figure>
<p>Note that Wilna isn’t making use of the server’s ability to broadcast messages, since each member in the group can only decrypt messages encrypted under their own pair keys. Generalizing this, if there is a group of size <em>N</em>, sending an application message requires a member to encrypt and send <em>N-1</em> times. Roughly speaking, this is how iMessage does group chat.<sup id="fnref:good_source"><a href="#fn:good_source" class="footnote">2</a></sup></p>
<p>Great, so that’s just three encryptions per person. This probably takes at most a few milliseconds on a phone. What’s the issue? The issue is what about the WhatsApp groups with >10,000 members where my aunts talk about who’s getting married next?? Do you want them to do 9,999 encryptions every time they send something? I do, but they probably don’t. To accomodate my aunts, we need to get cleverer.</p>
<h2 id="solution-2-sender-keys">Solution #2: Sender Keys</h2>
<p>Instead of having a key between every user in the group, let’s give every user a <strong>sender key</strong> that they use to encrypt application messages. This is roughly what Signal,<sup id="fnref:good_source:1"><a href="#fn:good_source" class="footnote">2</a></sup> WhatsApp,<sup id="fnref:good_source:2"><a href="#fn:good_source" class="footnote">2</a></sup> and Keybase<sup id="fnref:keybase_source"><a href="#fn:keybase_source" class="footnote">3</a></sup> do. If you’re a group member, you have to go through the following setup:</p>
<ol>
<li>Randomly generate your sender key</li>
<li>For every user in the group, encrypt your sender key with your pair key that you share with that user</li>
<li>Send every user their encrypted copy of your sender key as an auxiliary message</li>
</ol>
<p>After the setup, which requires <em>N-1</em> encryptions for each user in a group of size <em>N</em> (that’s Θ(<em>N</em><sup>2</sup>) total auxiliary messages), we finally see some efficient behavior. To send an application message <em>m</em>, Wilna:</p>
<ol>
<li>Encrypts <em>m</em> with her sender key <em>precisely once</em></li>
<li>Broadcasts the ciphertext to the group</li>
</ol>
<figure class="">
<p><img src="/assets/images/post_molasses/sender_key_app_msg.svg" alt="Sender key encrypted message broadcast" /></p>
<figcaption>
<p>The grey arrows represent application messages encrypted under a symmetric key.</p>
</figcaption>
</figure>
<p>Although there are three arrows here, they are all the same ciphertext, so the application message only needs to be encrypted and broadcast <em>once</em>. Thus, after the setup phase, each outgoing application message only costs a single encryption. So we’re done, right? Wrong, of course wrong. Because</p>
<h3 id="what-about-removal">What about Removal?</h3>
<p>The fallacy here is that the setup phase runs once. It actually runs every time the group is modified. Suppose in the process of premeditating this “retirement party,” the group finds out that Zayne has been leaking details to Vince the whole time. Naturally, they kick Zayne out. Now Zayne still knows all the sender keys, so if he talks to Vince and gets an encrypted transcript of the group conversation that happened after his departure, he would still be able to decrypt it. This is a no-no, since Zayne has already defected. To prevent this from happening, each remaining user in the group has to create a new sender key and share it with everyone else through their pairwise channels. Again, this is Θ(<em>N</em><sup>2</sup>) total auxiliary messages, which can be a <em>lot</em>. So if we want to tolerate tons of group modifications,<sup id="fnref:removal"><a href="#fn:removal" class="footnote">4</a></sup> we’re going to have to find a way to bring down the number of auxiliary messages sent during the setup phase, while still being able to keep using sender keys for application messages. A well-known secret in computer science is that when the naïve solutions of pairs and lists don’t work, there’s a next logical step:</p>
<h2 id="solution-3-trees">Solution #3: Trees</h2>
<p>We would like to have sender keys (since they make application messages efficient). We also want to be able to transmit new sender keys to subsets of the group without using too many auxiliary messages. The important insight here is that, when we remove a member, we shouldn’t need to <em>individually</em> send new keying information to every single remaining member like we had to in the previous solution. After all, we need to send this to the whole group minus just one person. So why not have public keys that cover large subsets of the group, and use those for sending auxiliary messages? This is exactly what the MLS ratchet tree (a.k.a. TreeKEM) affords us.</p>
<p>The MLS <strong>ratchet tree</strong> is a binary tree<sup id="fnref:tree"><a href="#fn:tree" class="footnote">5</a></sup> whose leaves correspond to members of the group, and whose non-leaf nodes, called <strong>intermediate nodes</strong>, carry a Diffie-Hellman public key and private key. Intermediate nodes don’t represent people, computers, or locations on a network; they’re just pieces of data that facilitate auxiliary message sending. We also allow nodes to be <strong>blank</strong>, meaning that they do not have an associated keypair. A node that does have an associated keypair is said to be <strong>filled</strong>. Every member in the group retains a copy of the ratchet tree, minus the private keys. Knowledge of the private keys follows the ratchet tree property:</p>
<p><strong>Ratchet Tree Property</strong> If a member <em>M</em> is a descendant of intermediate node <em>N</em>, then <em>M</em> knows the private key of <em>N</em>.</p>
<p><em>*deep breath*</em> Sender keys are derived via key-derivation function (KDF) from the root node’s private key, and private keys are derived via KDF from its most-recently updated child’s private key.<sup id="fnref:falsehoods"><a href="#fn:falsehoods" class="footnote">6</a></sup> Upon the removal of a user, new private keys are distributed to the <strong>resolutions of the copath nodes</strong>, i.e, the maximal non-blank nodes of the subtrees whose root is the sibling of an updated node.</p>
<p>That paragraph alone took about 10 minutes to write, so let’s just see</p>
<h3 id="a-small-example">A Small Example</h3>
<p>We start off with a group like so</p>
<p><img src="/assets/images/post_molasses/initial_tree.svg" alt="Initial tree" /></p>
<p>Zayne wants out, so Yolanda removes him.<sup id="fnref:self_removal"><a href="#fn:self_removal" class="footnote">7</a></sup> To remove him, Yolanda will first blank out Zayne and all his ancestors:</p>
<figure class="">
<p><img src="/assets/images/post_molasses/blanked_tree.svg" alt="Tree after blanking" /></p>
<figcaption>
<p>The boxes with red slashes through them represent blank nodes</p>
</figcaption>
</figure>
<p>Yolanda needs to contribute new keying information to the new group so that the new sender keys can be derived from the new root’s private key. To do this, she generates a new personal keypair pub<sub><em>Y’</em></sub> and priv<sub><em>Y’</em></sub> and derives all her ancestors’ keypairs by iteratively applying a KDF to the private key and computing its corresponding public key (this is called “ratcheting,” whence “ratchet tree”).</p>
<figure class="">
<p><img src="/assets/images/post_molasses/updating_tree_1.svg" alt="Tree with new secrets" /></p>
<figcaption>
<p>The green circles indicate recently updated nodes</p>
</figcaption>
</figure>
<p>But Yolanda isn’t done. Wilna and Xavier need to be told about these new keys somehow. It’s Yolanda’s job to share this info. In particular,</p>
<ol>
<li>
<p>Every member needs to get a copy of the public keys of all updated nodes (i.e., Yolanda’s own public key and all her ancestors’). This is important. The public keys are part of the shared group state, and shared group state is how a bunch of values in the MLS protocol are derived.</p>
</li>
<li>
<p>Every member needs to get a copy of the private keys of their nearest modified ancestor. This is in order to preserve the ratchet tree property.</p>
</li>
</ol>
<p>Remember that the end goal is still to derive the sender keys, which means that Wilna and Xavier need to be told the value of the root private key, priv<sub><em>Y'''</em></sub>. This will be a consequence of item two above.</p>
<p>Since everyone needs public keys and public keys are not secret, Yolanda can just broadcast them as unencrypted auxiliary messages. But private keys are more sensitive. She needs to encrypt them for <em>just</em> the members who need them. This is where we use the ratchet tree property. If she wants Wilna and Xavier to be able to read an auxiliary message containing priv<sub><em>Y'''</em></sub>, she need only encrypt the message under pub<sub><em>WX</em></sub>, since Wilna and Xavier are descendants of the <em>WX</em> intermediate node, and will therefore be able to decrypt anything encrypted under pub<sub><em>WX</em></sub>.<sup id="fnref:hpke"><a href="#fn:hpke" class="footnote">8</a></sup> This describes how the auxiliary messages are sent to the rest of the group:</p>
<figure class="">
<p><img src="/assets/images/post_molasses/updating_tree_2.svg" alt="Tree and auxiliary messages" /></p>
<figcaption>
<p>The solid black arrows above indicate public-key encrypted messages. The dashed arrows indicate plaintext messages. The arrows do not indicate who is doing the sending (since that’s all Yolanda). They’re just meant to illustrate where in the tree the values are coming from and whom they’re intended for.</p>
</figcaption>
</figure>
<p>Now Wilna and Xavier will update their view of the tree by saving the public keys and decrypting the root private key. Thus, everyone is on the same page and the ratchet tree property is preserved. Finally, everyone re-derives their sender keys, and the removal is complete.</p>
<p><img src="/assets/images/post_molasses/post_remove_tree.svg" alt="Tree post-removal" /></p>
<p>Note that Zayne’s position remains blank after the removal. This saves the members from the computational overhead of shuffling themselves around and recomputing their ancestors’ keypairs. MLS defines two ways to prevent removed members from overcrowding the tree: it allows blank nodes to be removed from the right end of the tree after removals (not applicable in the example above), and it allows new members to be added in the position of previously removed members. So if the “party-planners” above wanted to replace Zayne, they could do so without making the tree bigger.</p>
<p>This example illustrates the smaller details in updating keys, but it doesn’t do a particularly good job at illustrating which node secrets are sent to which other nodes in the resolutions of the copath nodes. To give an idea, here’s</p>
<h3 id="a-much-bigger-example">A Much Bigger Example</h3>
<p>Suppose Zayne wants to break out and go solo, but still feels the desire to be in a boy band. After cloning himself 15 times, Zayne #1 notices that one of the clones, Zayne #11, keeps hinting at breaking off and doing a solo career of his own. Zayne #1 acquiesces and removes him from the group. He sees what he’s created. Zayne #1 looks up at the stars. War soon.</p>
<p>Let’s see what auxiliary messages were sent when Zayne #11 was booted. In this removal process, Zayne #1 generates new secrets, ratchets them all the way up the tree, and shares them with the appropriate subtrees:</p>
<figure class="">
<p><img src="/assets/images/post_molasses/updating_clone_tree.svg" alt="Updating tree of clones" /></p>
<figcaption>
<p>The green circles still represent the updated nodes. The solid arrows represent the private key of its tail being encrypted under the public key of its head.</p>
</figcaption>
</figure>
<p>Notice on the right hand side of the tree, since you can’t encrypt to a blank node, the root private key needs to be encrypted under three separate public keys. The dashed arrows were omitted for clarity, but it’s still true that the public keys of all the circled nodes are broadcasted in this step.</p>
<p>With this larger example, you might start to see some pattern in how many auxiliary messages are sent per tree update. Let’s play</p>
<h3 id="can-you-eyeball-the-asymptotic-behavior">Can You Eyeball the Asymptotic Behavior?</h3>
<p>We got efficient application messages with sender keys, and we’d like to say that we got efficient auxiliary messages with TreeKEM so we can call it a day. Is this true? Absolutely not, at least not entirely. Let’s first talk about the example above, where we start off with a tree whose nodes are all filled.</p>
<h4 id="removal-in-a-filled-tree">Removal in a Filled Tree</h4>
<p>The Zayne example is actually worst-case removal behavior in a filled tree in terms of number of auxiliary messages (you should prove this to yourself: what would happen if Zayne #1 removed Zayne #6 instead?). If there are <em>N</em> many members in the group, there are at most log(<em>N</em>)-1 encrypted auxiliary messages that don’t have to deal with blank nodes, and another log(<em>N</em>)-1 that do. Plus, there are log(<em>N</em>) many public keys to share. So, to complete the sage wisdom from computer scientists of days past, if you use trees, you get <em>O</em>(log(<em>N</em>)) behavior. This is way better than the quadratic number of auxiliary messages we saw in solution #2. The same WhatsApp group of kibbitzing mumehs now only takes about 3log<sub>2</sub>(10,000) ≈ 40 total auxiliary messages to establish a new set of sender keys (assuming a filled tree) instead of the <em>N</em>(<em>N</em>-1) ≈ 99 million total auxiliary messages required previously.</p>
<h4 id="removal-in-a-tree-with-blanks">Removal in a Tree with Blanks</h4>
<p>This logarithmic behavior is fantastic, but we only checked for the very specific case where we start with a full group and then remove one person. How efficient is it when we remove a single person from a group that already has some blanks? The good news is that it’s still better than Θ(<em>N</em><sup>2</sup>). The bad news is that the worst case is…well let me just show you.</p>
<p>Suppose every odd-numbered Zayne was removed from the group besides Zayne #1. Finally, Zayne #2 deals the finishing blow, removing Zayne #1 and restoring peace. This is what the update looks like:</p>
<figure class="">
<p><img src="/assets/images/post_molasses/linear_tree.svg" alt="A tree with linear removal behavior" /></p>
<figcaption>
</figcaption>
</figure>
<p>That’s <em>N</em>-1 messages to remove a single person! As mentioned before, this can be a prohibitively large number of auxiliary messages for large <em>N</em>. Even worse, it may be possible for malicious group members to strategically remove people until the tree reaches the worst-case state, thus slowing down group operations for everyone in the group.</p>
<p>Dealing with this situation is an open issue, and people are actively working on resolving or at least mitigating it. As of this writing, though, there are no proposed solutions that would materially improve the worst-case behavior.</p>
<h1 id="conclusion-and-more-info">Conclusion and More Info</h1>
<p>It’s underwhelming to end at an open issue, but this is where the protocol stands today. Efficiently updating keys is at the crux of end-to-end group messaging. The TreeKEM method, edge cases and all, is one of the most important singular contributions that MLS makes. Given that there’s still at least one open issue in the spec, you may wonder</p>
<h2 id="how-close-is-the-protocol-to-being-done">How close is the protocol to being done?</h2>
<p>No clue. MLS has plenty of open issues (nine as of this writing) and is being tweaked constantly. Draft 7 landed just this month, and it completely overhauled the symmetric key schedule. Inefficiencies are being shaved down as issues around authenticity, confidentiality, deniability, etc. are being patched.</p>
<h2 id="what-are-the-other-implementations">What are the other implementations?</h2>
<p>The unofficial reference implementation, <a href="https://github.com/cisco/mlspp"><code class="language-plaintext highlighter-rouge">mlspp</code></a>, is used to create test vectors that we implementers all test against. There’s also <code class="language-plaintext highlighter-rouge">MLS*</code>, a project at Inria to implement and formally model the protocol in <a href="https://www.fstar-lang.org/">F*</a>. And there’s even another Rust implementation, <a href="https://github.com/wireapp/melissa/"><code class="language-plaintext highlighter-rouge">melissa</code></a>, being written at Wire.</p>
<h2 id="remind-me-why-youre-writing-yet-another-rust-implementation">Remind me why you’re writing yet another Rust implementation?</h2>
<p>The more implementations the better. Writing this implementation has helped find errors in <code class="language-plaintext highlighter-rouge">mlspp</code> and the specification itself.</p>
<p>Errors found in <code class="language-plaintext highlighter-rouge">mlspp</code> include missing important fields (missing protocol version and missing hash of WelcomeInfo, which enforces sequencing), incorrect tree addressing (using leaf indices instead of node indices and vice-versa), and incorrectly generated test vectors. Errors in the specification that we found include ambiguities (how are removed nodes pruned from the ratchet tree?), logical impossibilities (how can you add a user to the group if your WelcomeInfo doesn’t include the current decryption keys?), and deontological omissions (SHOULD<sup id="fnref:should"><a href="#fn:should" class="footnote">9</a></sup> a user verify the broadcasted pubkeys against their derived pubkeys or not?).</p>
<h2 id="ok-great-but-why-rust">Ok great, but why Rust?</h2>
<p><em>*cracks knuckles*</em></p>
<p>I thought it would be nice to have an MLS implementation that has a clear API (thanks to <code class="language-plaintext highlighter-rouge">molasses</code>’ careful design and Rust’s strong typing), memory-safe semantics (thanks to the Rust borrow checker), thorough documentation (thanks to <code class="language-plaintext highlighter-rouge">cargo doc</code> and <code class="language-plaintext highlighter-rouge">molasses</code>’ current 43% comment-code ratio), and good performance (thanks to <a href="/assets/images/resf_orig.jpg">ZERO-COST-ABSTRACTIONS</a>). Of course, none of these features make up for the fact that <code class="language-plaintext highlighter-rouge">molasses</code> is not formally verified like <code class="language-plaintext highlighter-rouge">MLS*</code> and may never be, but hey, nobody ever complained that cotton isn’t as bulletproof as kevlar, cuz those are for different things.</p>
<h2 id="how-can-i-help">How can I help?</h2>
<p>I don’t recommend filing issues with <code class="language-plaintext highlighter-rouge">molasses</code> quite yet. The spec is moving too quickly and the library has to be redesigned accordingly each time. If you would like to contribute, the <a href="https://datatracker.ietf.org/wg/mls/about/">MLS IETF page</a> has a mailing list where you can read and participate in discussions. The organizers are helpful and patient, and I appreciate them immensely. If you want to write your own implementation, see the <a href="https://github.com/mlswg/mls-implementations">implementers’ Github repo</a> for organizing info and test vectors.</p>
<p>If you are interested in reading more about the protocol and seeing some of the other open issues, you should give <a href="https://datatracker.ietf.org/doc/draft-ietf-mls-protocol/">the spec</a><sup id="fnref:spec"><a href="#fn:spec" class="footnote">10</a></sup> a read.</p>
<div class="footnotes">
<ol>
<li id="fn:pcs">
<p>Full post-compromise security, i.e., the problem of non-deterministically deriving all new shared data so as to make the excluded parties unable to participate, is actually not easily achieved in this scheme. There is ongoing research in characterizing how post-compromise secure MLS is after a certain number of group updates. <a href="#fnref:pcs" class="reversefootnote">↩</a></p>
</li>
<li id="fn:good_source">
<p><a href="https://eprint.iacr.org/2017/666.pdf">Source</a>. This is a fantastic paper which provides a lot of context for this article. Seriously, if you want to understand this topic better, you should read the MLS spec and this paper and compare the two, since they differ in pretty subtle but significant ways. E.g., the ART scheme used in the paper does not allow intermediate nodes to be blank, which affects confidentiality of messages sent to offline members. <a href="#fnref:good_source" class="reversefootnote">↩</a> <a href="#fnref:good_source:1" class="reversefootnote">↩<sup>2</sup></a> <a href="#fnref:good_source:2" class="reversefootnote">↩<sup>3</sup></a></p>
</li>
<li id="fn:keybase_source">
<p><a href="https://rwc.iacr.org/2019/slides/keybase-rwc2019.pdf">Source</a> <a href="#fnref:keybase_source" class="reversefootnote">↩</a></p>
</li>
<li id="fn:removal">
<p>The problem of Removal in this article is a placeholder for (a weaker form of) post-compromise security. Here, “group modifications” includes updating key material without changing group membership. <a href="#fnref:removal" class="reversefootnote">↩</a></p>
</li>
<li id="fn:tree">
<p>Specifically, it is a left-balanced binary tree. This is fancy computer talk for “every left subtree is full,” which itself is fancy computer talk for “it behaves good when stuffed into an array.” <a href="#fnref:tree" class="reversefootnote">↩</a></p>
</li>
<li id="fn:falsehoods">
<p>Both these statements are technically false, but it’s way easier to think of things this way, and it’s close enough to the truth imo. In reality, sender keys are derived from a long chain of secret values relating to group state and state transitions. Node private keys are simpler, but they are also derived from chains of other secrets called “node secrets” and “path secrets.” As always, see the spec for more details. <a href="#fnref:falsehoods" class="reversefootnote">↩</a></p>
</li>
<li id="fn:self_removal">
<p>MLS doesn’t allow users to remove themselves. This is a quirk of the protocol, but it doesn’t really affect anything. <a href="#fnref:self_removal" class="reversefootnote">↩</a></p>
</li>
<li id="fn:hpke">
<p>If you’re confused why I say all these keys are Diffie-Hellman keys and then use public-key encryption, it’s because the public-key encryption in MLS is done with <a href="https://en.wikipedia.org/wiki/Integrated_Encryption_Scheme">ECIES</a>. More specifically, it’s <a href="https://tools.ietf.org/html/draft-barnes-cfrg-hpke-01">HPKE</a>. <a href="#fnref:hpke" class="reversefootnote">↩</a></p>
</li>
<li id="fn:should">
<p>The all-caps “SHOULD” means something specific in IETF RFCs. Its meaning is governed by not one but two RFCs, which are referred to as <a href="https://tools.ietf.org/html/bcp14">Best Current Practice 14</a>. The linguistic conventions of RFCs are super cool and alone make it worth skimming a few specs and paying attention to their “conventions and terminology” sections. <a href="https://tools.ietf.org/html/rfc8446">TLS</a> is as good a place to start as any. <a href="#fnref:should" class="reversefootnote">↩</a></p>
</li>
<li id="fn:spec">
<p>If you want a particularly nice reading experience, you should compile the spec yourself from <a href="https://github.com/mlswg/mls-protocol">source</a>. It really is appreciably better. <a href="#fnref:spec" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Michael RosenbergIntroducing molassesSiderophile: Expose your Crate’s Unsafety2019-07-01T00:00:00-04:002019-07-01T00:00:00-04:00https://mrosenberg.pub/cryptography/2019/07/01/siderophile<p><em>This article was originally posted on Trail of Bits’ <a href="https://blog.trailofbits.com/2019/07/01/siderophile-expose-your-crates-unsafety/">blog</a> on July 1, 2019</em></p>
<p><strong><em>Siderophile ([ˈsidərəˌfīl]) — Having an affinity for metallic iron</em></strong></p>
<p>Today we released a tool, <a href="https://github.com/trailofbits/siderophile"><code class="language-plaintext highlighter-rouge">siderophile</code></a>, that helps Rust developers find fuzzing targets in their codebases.</p>
<p>Siderophile trawls your crate’s dependencies and attempts to finds every unsafe function, expression, trait method, etc. It then traces these up the callgraph until it finds the function in your crate that uses the unsafety. It ranks the functions it finds in your crate by badness—the more unsafety a function makes use of, the higher its badness rating.</p>
<p>We created Siderophile for an engagement where we were delivered a massive Rust codebase with a tight timeframe for review. We wanted to fuzz it but weren’t even sure where to start. So, we created a tool to determine which functions invoked the most unsafe behavior. We were able to speed up our bug discovery by automating the targeting process with siderophile. We’re now open-sourcing this tool so everyone can benefit from it!</p>
<h1 id="sample-output">Sample Output</h1>
<p>Here is a sample of <code class="language-plaintext highlighter-rouge">siderophile</code> when run on <code class="language-plaintext highlighter-rouge">molasses</code>, a crate we’re building that implements the <a href="/cryptography/2019/07/10/molasses.html">MLS cryptographic protocol</a>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Badness Function
012 molasses::crypto::hash::HashFunction::hash_serializable
005 molasses::crypto::hash::HashContext::feed_serializable
003 molasses::utils::derive_node_values
003 molasses::application::encrypt_application_message
003 molasses::application::decrypt_application_message
003 molasses::group_ctx::GroupContext::new_from_parts
003 molasses::group_ctx::GroupContext::from_welcome
003 molasses::group_ctx::GroupContext::update_transcript_hash
003 molasses::group_ctx::GroupContext::update_tree_hash
003 molasses::group_ctx::GroupContext::update_epoch_secrets
003 molasses::group_ctx::GroupContext::apply_update
...
</code></pre></div></div>
<p>As you can see, much of the unsafety comes from the serialization and crypto-heavy routines. We’ll be sure to fuzz this bad boy before it goes 1.0.</p>
<h1 id="limitations">Limitations</h1>
<p>This is not guaranteed to catch all the unsafety in a crate’s deps. For instance, we don’t have the ability to inspect macros or resolve dynamically dispatched methods since unsafe tagging only occurs at a source-level. The ergonomics for the tool could be better, and we’ve already identified some incorrect behavior on certain crates. If you’re interested in helping out, please do! We are actively maintaining the project and have some issues written out.</p>
<h1 id="try-it-out">Try it Out</h1>
<p><code class="language-plaintext highlighter-rouge">siderophile</code> is on Github along with a better explanation of how it works and how to run the tool. You should run it on your Rust crate and set up fuzzers for what it finds. <a href="https://github.com/trailofbits/siderophile">Check it out</a>!</p>
<p>Finally, thanks to <a href="https://github.com/anderejd/cargo-geiger">cargo-geiger</a> and <a href="https://github.com/praezi/rust/">rust-praezi</a> for current best practices. This project is mostly due to their work.</p>Michael RosenbergThis article was originally posted on Trail of Bits’ blog on July 1, 2019Guidance2019-05-10T00:00:00-04:002019-05-10T00:00:00-04:00https://mrosenberg.pub/2019/05/10/guidance<p>“Ted?” Ms. Roth called out. Ted Potensky looked up. “You can head into Mr. Davidson’s office now.”</p>
<p>Mr. Davidson’s door cracked open just as Ted stood up. Ted saw a girl step out of the office. Her eyes looked puffy. Mr. Davidson peeked his head out of the doorway and beckoned cheerfully, “Hey hey! Come right in, Ted!” Ted obliged, though he still had no idea as to why he had been called into the guidance counselor’s office in the middle of the day.</p>
<p>Mr. Davidson circled back to his desk and motioned for Ted to sit as he picked up a pen. “So, Teddy, tell me, what’s up? How are you?” he began.</p>
<p>Ted wasn’t sure how to answer the open-ended question. He tried to use it to make conversation. “Good, good. I actually had to pull an all-nighter last night for a presentation in Spanish class. I think—”</p>
<p>“Oofta yeah, yeah that’ll do it” said Mr. Davidson, listening actively while jotting notes on the sheet of paper in front of him.</p>
<p>“—I think it was worth it, because the presentation went really well. People had a ton of questions after the—”</p>
<p>“So, you’re feeling <em>okay</em>, then.” declared Mr. Davidson, hovering his pen over a checkbox on the sheet.</p>
<p>“Uh yeah I’d say so, maybe a bit tired or hungry. I find that—”</p>
<p>“Mhm. Ok that’s great. Great to hear,” he said, ticking the box. “So, just so you know, the reason I ask is because I have to do this boring thing for the school’s insurance where I periodically check in with some of our vulnerable students.” Mr. Davidson air-quoted the last words as he said them.</p>
<p>Ted was confused. “What do you mean ‘vulnerable’?”</p>
<p>“Oh it’s just psycho-babble technical jargon. No need to worry about how it sounds.” Mr. Davidson moved his pen down the left side of the sheet of paper until it found its starting point again. “So, Teddy, how do you feel about your academics? How are you doing in school?”</p>
<p>Ted wasn’t quite satisfied with the answer to his question. He put a pin in it. “Pretty good, actually,” he said, enthusiastically. “I got mostly As last semester, and I feel pretty confident about this semester too. Like that Spanish presentation I mentioned went pretty well, I think, so that’ll be another A.”</p>
<p>“Not bad, not bad at all, my man!” said Mr. Davidson, with a new infusion of excitement. “It doesn’t say here, so remind me again what level Spanish you’re in?”</p>
<p>“Uh, three,” said Teddy.</p>
<p>“And math?”</p>
<p>“Three.”</p>
<p>“And chemistry?”</p>
<p>“Three as well.”</p>
<p>“Cool cool,” said Mr. Davidson, filling in the last details on his sheet. “So it looks like the remedial classes are a good fit for you. I’m glad you’re doing so well in them.”</p>
<p>“Huh.” Ted paused for a moment. He didn’t know anyone else who was in all threes, now that he thought about it.</p>
<p>Mr. Davidson moved right along. “Alrighty, now tell me, what’s your social life like? Got any pals you like to hang out with?”</p>
<p>Ted recovered. “Oh, plenty” he said, smiling. “I’ve got a pretty big group of friends, maybe five or six,” he included the numbers because he figured Mr. Davidson liked numbers, “and like we get lunch together and hang out in the lounge together. It’s fun.”</p>
<p>“And you all presumably hang out on the weekends? Maybe go to the movies or the mall?” probed Mr. Davidson.</p>
<p>“Hmm?” Ted was caught slightly off-guard. He decided to own it. “No, not really. I don’t see most of my friend group outside of school so much. It’s more like an in-school kind of friend group, if you know what I mean.”</p>
<p>Mr. Davidson was still writing. Without looking up, he persisted “I think I know what you mean. Would you say you have an out-of-school friend group, then?”</p>
<p>Ted didn’t answer right away. He had always considered himself to be a social guy. He took about 10 seconds to think it through before he conceded “No I guess not. I’m home most of the time when I’m not in school. Mostly on the computer.” He briefly wondered just how badly he was deluding himself. Then he remembered, “Oh! But I have a bunch of people I talk to regularly on IRC—that’s internet relay chat. I kinda hang out with them on the weekends, if you think that counts.”</p>
<p>Mr. Davidson smiled. “Oh that sounds nice. I’m glad you consider them your friends.” He finished writing on the last line on his sheet of paper while mouthing the words “no real friends” to himself. Ted was feeling a little nauseous now.</p>
<p>“Last question,” Mr. Davidson said, turning over the paper. “If you don’t mind me prying a little, could you share a bit about your dating situation? Are you seeing anyone? If you feel uncomfortable answering, you just say the word, I totally get it.”</p>
<p>Ted truly didn’t want to answer the question. But he also didn’t want Mr. Davidson to know that he didn’t want to answer the question. He considered making up an answer, but he knew he was no good at lying. Besides, Mr. Davidson was clearly quite perceptive. He swallowed and went with the truth. “Not much going on, really,” he said, sheepishly.</p>
<p>“Come on, a guy like you? Straight As and a bunch of school friends? I’m sure there’s <em>something</em> going on,” pitched Mr. Davidson.</p>
<p>Ted felt flattered. Mr. Davidson hadn’t really done anything explicitly to make Ted feel bad. Ted was probably just in his own head. He elaborated, “Well, I was thinking of asking someone out. She’s in some of my classes and we talk a lot.”</p>
<p>“Oh you mean Sheila?” inquired Mr. Davidson flatly.</p>
<p>The name hit Ted in the gut. He stammered, “h…how…”</p>
<p>“I overheard Sheila talking in the hallway earlier this week. Talking about how she was stringing along some loser in one of her classes. She really seems to appreciate how much free time she has when you so chivalrously offer to do all the work in your group projects.”</p>
<p>“No. No, I don’t believe you.” Ted felt his eyes getting warm and blurry.</p>
<p>Mr. Davidson began to raise his voice. “You think I’m messing with you? You think I’d make this up? I know more about Sheila than you do. Did you know she’s got a boyfriend?” he taunted. Ted shook his head. “That’s right, she has a boyfriend in another school. Bet you would have known that if you spent a lot of time talking with her like you said you did. Or did you talk to her over IRC?”</p>
<p>Ted banged the desk. “Shut up! Shut the fuck up!” he yelled, his voice cracking. Tears were streaming down his face.</p>
<p>“Ooh I’m scared now. Does that make you mad, Teddy? Would it make you mad if I told you she spent that free time fucking her boyfriend in his studio apartment?”</p>
<p>Ted tried to look tough through his tears. Mr. Davidson wasn’t buying it.</p>
<p>“Would that make you want to lash out, huh? Maybe hurt her? Or would you rather take it out on the whole school? Does violence suit you, you lonely, remedial loser?”</p>
<p>Of course it didn’t. Ted didn’t say anything. He had nothing to say. His face froze in its contorted state.</p>
<p>“That’s what I thought. All bark and no bite. God, you kids are so predictable,” snarled Mr. Davidson as he checked off the “Not an Active Threat” box on his sheet. A few seconds passed and Ted was still unresponsive. “Well? That’s it! Get the hell out of my office!”</p>
<p>Ted, face damp with tears and mucus, stood up and made his way to the door.</p>
<p>Mr. Davidson put his feet up on his desk and clicked the intercom beside him. “Ms. Roth? Send in the next psycho. This one’s a fuckin’ pussy.”</p>Michael Rosenberg“Ted?” Ms. Roth called out. Ted Potensky looked up. “You can head into Mr. Davidson’s office now.”