David Wong | Cryptologie | Markdown http://www.cryptologie.net/ About my studies in Cryptography. en-us Tue, 19 Feb 2019 17:22:39 +0100 [paper review] A faster, more efficient cryptocurrency David Wong Tue, 19 Feb 2019 17:22:39 +0100 http://www.cryptologie.net/article/473/paper-review-a-faster-more-efficient-cryptocurrency/ http://www.cryptologie.net/article/473/paper-review-a-faster-more-efficient-cryptocurrency/#comments
From a high level, it looks like a new cryptocurrency. But it is written as a set of techniques to improve [Algorand](https://www.algorand.com/) and other cryptocurrencies are encouraged to adopt them, which leads me to think this will probably not become another cryptocurrency. It is very well written and I thought I would write a summary here.

After installing a cryptocurrency client, you usually **sync** it with the network in order to be able to participate or see the latest state of the blockchain. This whole concept of joining a cryptocurrency as a client is costly. For example, to join Bitcoin you need to download the whole blockchain which is **more than 150 GB** at the moment. It can take days and lot of bandwidth.

The whole point of Vault (the paper) is about reducing this bootstrapping process, and the space needed after to keep using the blockchain. It includes three techniques which I will briefly summarize below:

**First technique: balance pruning**.

Ethereum got rid of Bitcoin's UTXOs and keeps track of all the account balances instead. This method already saves a lot of space. Once you do that though, you are required to keep track of a nonce per account. This is to prevent transactions replay.

> How does the Ethereum nonce works: when you sign a transaction, you also sign the nonce. Once it gets accepted in a block the nonce of your account gets incremented, and the next transaction will need to sign the new nonce to get accepted.

Vault doesn't keep a nonce, instead it tracks the hashes of all the transactions that were applied. This way, If you try to replay a transaction, it will be detected.

That's too costly though, we don't want to store ALL of the transactions ever. So the first technique is to **force transactions to expire**. Once a transaction is expired, a client can get rid of it in its storage, as it cannot be replayed (it is not valid anymore).

Another issue with Ethereum are **zero-balance accounts**.

> Our analysis of the Ethereum state indicates that around 38% of all accounts have no funds and no storage/contract data (i.e., only an address and a nonce)

These zero-balance accounts still need to be tracked because of the nonce that is still useful to prevent future transaction replays.

In Vault, once all transactions applied on a zero-balance account have expired, you can prune the account.

This first technique allows a lot of useless data to be cleaned out. A client only stores accounts that have a balance greater than zero, zero-balance accounts if they still have transactions that could be replayed, and recent committed/pending transactions that haven't expired yet.

**Second technique: balance sharding**.

Keeping track of all the accounts is costly for one client... We can do better.

Vault uses a sparse Merkle tree where the leaves represent all the possible accounts.

It's quite a large tree... so we can split it in shards! The first $X$ bits of someone's public key could indicate what shard they should store. For example if we want to have 4 shards, the first 2 bits would indicate the path in the tree (0 is left, 1 is right).

Instead of storing all the leaves, you would store all the leaves that belong to your "subroot" (specified by the first bits of your public key).

By doing this we can't verify transactions anymore though...

To solve this, every transaction now ships with a proof of membership (a witness) for both the sender and recipient addresses.
This proof of membership is a typical merkle tree concept, it contains the neighbor nodes of the leaf's path up to the root as well as the leaf itself (account balance). This way anyone can verify a transaction!

Furthermore, once a transaction is committed to a block, the merkle tree is updated and its root are updated as well (because an account balance (a leaf) has changed).
So pending transactions in the mempool (the pool of pending transactions) need to have their membership proofs updated. Anybody has enough information to do this so it is not a problem. (By the way this is why transactions carry the recipient address' witness (the membership proof)l: because that leaf gets affected by a transaction as well.)

These two proofs are quite long though, and they accompany every transactions being broadcasted on the network!

One way to reduce that is to decrease the length of the membership proof. To do this, every client stores a level of subroots of the balance merkle tree, this way a proof doesn't need to go up to the root, but up to the level that the client has stored. The rest can be calculated from what is on disk.

Thanks to this second technique, one only needs to keep track of his own leaf (account balance) as well as the balance merkle root. And one can still verify new blocks. If one wants to help storing part of the network, one can keep track of a shard instead of the whole list of accounts.

I think the sharding thing here is actually less important than the transactions shipping with the balance proofs. But it is still a neat way of making sure that all nodes can participate in conserving the full blockchain and its balances.

**Third technique: stamping certificates**.

Vault is built on top of Algorand. The Algorand protocol is so elegant, I can see why they would want to make use of it.

Algorand's byzantime agreement BA* produces a "certificate" for each block committed to the blockchain. A certificate is a bundle containing more than 2/3rd signatures of the block from a randomly selected committee. Such a certificate is quite large (lots of signatures, public keys, and proof that the public key could participate in BA*). In addition, Algorand "mines" a new block every 2-3 seconds, so it has quite a large blockchain and a new client needs to download and verify a huge number of blocks to join the network.

To speed this up, Vault has nodes create additional "stamped certificates" at larger intervals (one every thousand blocks or so). From one stamped certificate, you can fast forward thousands of blocks ahead (~2 days of history) to the next stamped certificate. To create these stamped certificates, they use the same cryptographic sortition technique that Algorand uses but with a smaller number of participants to reduce the size of the stamped cert. (No, [BLS and aggregate signatures](https://cryptologie.net/article/472/what-is-the-bls-signature-scheme/) won't help because as I've said a certificate contains a lot of distinct objects).

This way, to join the network, a client can validate blocks and certificates until it finds its first stamped certificate, then the client can jump thousands of blocks ahead from stamped certificate to stamped certificate until it reaches the most up-to-date block. There are more optimizations and details to it addressed in the paper.

I the end these stamped certificates are some kind of checkpoints. I find that it is not as elegant as [Coda's protocol](https://codaprotocol.com/) solution which only contains one zero-knowledge proof of the whole chain, but ZK-SNARKS being quite complicated I can see how one would want to avoid them. ]]>
What is the BLS signature scheme? David Wong Sun, 17 Feb 2019 18:06:19 +0100 http://www.cryptologie.net/article/472/what-is-the-bls-signature-scheme/ http://www.cryptologie.net/article/472/what-is-the-bls-signature-scheme/#comments
BLS is a digital signature scheme being [standardized](https://tools.ietf.org/html/draft-boneh-bls-signature-00).

Its basis is quite similar to other signature schemes, it has a key generation with a generator $P2$:

![BLS keygen](/upload/Screen_Shot_2019-02-17_at_8.55_.35_AM_.png)

The signature is a bit weird though, you pretend the hashed message is the generator (using a `hash_to_G1` function you hash the message into a point on a curve) and you do what you usually do in a key generation: you make it a public key with your private key

![BLS sign](/upload/Screen_Shot_2019-02-17_at_8.55_.38_AM_.png)

Verification is even weirder, you use a bilinear pairing to verify that indeed, `pairing([secret_key]hashed_msg, P2) = pairing([secret_key]P2, hashed_msg)`.

![BLS verify](/upload/Screen_Shot_2019-02-17_at_8.55_.42_AM_.png)

This weird signing/verifying process allows for pretty cool stuff. You can compress (aggregate) signatures of the same msg in a single signature!

To do that, simply add all the signatures together! Easy peasy right?

![BLS aggregate-1](/upload/Screen_Shot_2019-02-17_at_8.55_.45_AM_.png)

Can you verify such a compressed signature? Yes you can.

Simply compress the public key, the same way you compressed the signature. And verify the `sig_compressed` with the `public_key_compressed`. Elegant :)

![BLS aggregate-1 verify](/upload/Screen_Shot_2019-02-17_at_8.55_.50_AM_.png)

But what if the different signatures are on different messages? Well, just add them together as well.

![BLS aggregate-n](/upload/Screen_Shot_2019-02-17_at_8.55_.54_AM_.png)

The process to verify that is a bit more complicated. This time you multiply a bunch of `pairing([secret_key]P2, hashed_msg)` together, and you verify that it is equal to another pairing made out of the compressed signature. Pairings are magical!

![BLS aggregate-n verify](/upload/Screen_Shot_2019-02-17_at_8.56_.00_AM_.png)
Database Encryption David Wong Tue, 12 Feb 2019 23:09:05 +0100 http://www.cryptologie.net/article/471/database-encryption/ http://www.cryptologie.net/article/471/database-encryption/#comments
## Anonymity

I want to mention this first, because this is one of the most stupid solution I've seen being used to either anonymize a database or protect it. What you do is that you keep track of a mapping between real words and random words. For example "pasta" means "female" and "guitar" means "male". Then you replace all these words by their counterparts (so all the mention of "female" in your database get replaced by "pasta"). This allow you to have a database that doesn't hold any information. In practice, this is leaking way too much and it is in no way a good idea. It is called **tokenization**.

## Database Breaches

Databases contain user information, like credit card numbers and passwords. They are often the target of attacks, as you can read in the news. For example, you can check on [haveibeenpwned.com](https://haveibeenpwned.com/) if your email has been part of a database breach. A friend of mine has been part of 19 database breaches apparently.

To prevent such things from happening, on the server side, you can encrypt your database.

Why not, after all.

The easier way to do this is to use **Transparent Database Encryption (TDE)** which a bunch of database engine ship by default. It's really simple, some columns in tables are encrypted with a key. The `id` and the `table name` are probably used to generate the nonce, and there's probably some authentication of the row or something so that rows can't be swapped. If your database engine doesn't support TDE, people will use home-made solutions like [sqlcipher](https://www.zetetic.net/sqlcipher/). The problem with TDE or sqlcipher, is that the key is just lying around next to your database. In practice, this seems to be good enough to get compliant to regulation stuff (perhaps like [FIPS](https://en.wikipedia.org/wiki/Federal_Information_Processing_Standards) and [PCI-DSS](https://en.wikipedia.org/wiki/Payment_Card_Industry_Data_Security_Standard)).

This is also often enough to defend against a lot of attacks, which are often just dumb smash-and-grab attacks where the attacker dumps the database and flees the crime scene right away. If the attacker is not in a hurry though, he can look around and find the key.

It's not that hard.

**EDIT**: one of the not so great thing about this kind of solution, is that the database is not really searchable unless you left some fields unencrypted. If you don't do searches, it's fine, but if you do, it's not so fine. The other solutions I talk about in this post also try to provide searchable encryption. They belong in the field of Searchable Symmetric Encryption (SSE).

## Untrusted Databases

The solution here is to segment your architecture into two parts, a client who holds the key and an untrusted database. If the database is breached, then the attacker learns nothing.

I hope you are starting to realize that this solution is really about **defense in depth**, we're just moving the security somewhere else.

If both sides are breached, it's game over, if the client is breached an attacker can also start making whatever requests it wants. The database might be rate-limited, but it won't stop slow attacks. For password hashing, there have been hilarious proposals to solve this with [security through obesity](https://en.wikipedia.org/wiki/Security_through_obscurity), and more serious proposals to solve this with password hashing delegation (see [PASS](https://cryptologie.net/article/321/real-world-crypto-day-2/) or [makwa](https://www.bolet.org/makwa/)).

But yeah, remember, this is defense in depth. Not that defense in depth doesn't work, but you have to frame your research in that perspective, and you also have to consider that whatever you do, the more annoying it is and the more efficient it will be at preventing most attacks.

## Optimizations

Now that we got the setup out of the way, how do we implement that?

The naive approach is to encrypt everything client-side. But this is awful when you want to do complicated queries, because the server has to pretty much send you the entire database for you to decrypt it and query it yourself. [There were some improvements known there](https://github.com/zerodb/zerodb), but there is only so much you can probably do.

Other solutions ([cryptdb](https://css.csail.mit.edu/cryptdb/), mylar, opaque, preveil, verena, etc.) use a mix of cryptography (layers of encryption, homomorphic encryption, order preserving encryption, order revealing encryption, etc.) and perhaps even hardware solutions ([Intel SGX](https://en.wikipedia.org/wiki/Software_Guard_Extensions)) to solve the efficiency issue.

Unfortunately, most of these schemes are not clear about the threat model. As they do not use the naive approach, they have to leak some amount of information, and it is not obvious what attacks can do. And actually, if you read the research done on the subject, it seems like they could in practice leak a lot more than what we would expect. Some researchers are very angry, and claim that the situation is worst than having a plaintext database due to do the illusion of security when using such database encryption solutions.

## Is there no good solution?

In practice, fully homomorphic encryption (FHE) could work to prevent the bad leakage we talked about. I don't know enough about it, but I know that [there is no CCA2-secure FHE algorithm](https://crypto.stackexchange.com/questions/17980/can-a-homomorphic-encryption-scheme-be-made-cca2-secure), which might be an issue. The other, more glaring, issue is that FHE is slow as hell. It could be practical in some situations, but probably not at scale and for this particular problem. For more constrained types of queries, somewhat homomorphic encryption (SHE) should be faster, but is it practical? Partial homomorphic encryption (HE) is fast but limited. The [paillier cryptosystem](https://en.wikipedia.org/wiki/Paillier_cryptosystem), an HE algorithm, is actually used in [cryptdb](https://css.csail.mit.edu/cryptdb/) to do addition on ciphertexts.

## Conclusion

The take away is that database encryption is about **defense in depth**. Which means it is **useful**, but it is **not bullet proof**. Just be aware of that. ]]>
On Doing Research David Wong Sat, 26 Jan 2019 05:47:59 +0100 http://www.cryptologie.net/article/469/on-doing-research/ http://www.cryptologie.net/article/469/on-doing-research/#comments

That advice from [Feynman’s Breakthrough, Disregard Others!
](https://stepsandleaps.wordpress.com/2017/10/17/feynmans-breakthrough-disregard-others/) was really useful to me as I realized that I HAD to miss out on what was happening around me if I wanted to do research. It's quite hard nowadays, with all the noise and all the cool stuff happening, to focus on one's work. But it seems like Feynman had the same issues even before the internet was born. So that's one of the secret: JOMO it out (Joy Of Missing Out).

> The word was “Disregard!”

> “That’s what I’d forgotten!” he shouted (in the middle of the night). “You have to worry about your own work and ignore what everyone else is doing.” At first light, he called his wife, Gweneth, and said, “I think I’ve figured it out. Now I’ll be able to work again!” […]

**Reading Papers**.

That advice comes from [Andrew Ng's interview](https://www.huffingtonpost.com/2015/05/13/andrew-ng_n_7267682.html):

> "I don’t know how the human brain works but it’s almost magical: when you read enough or talk to enough experts, when you have enough inputs, new ideas start appearing."

and indeed. I've noticed that, after reading a bunch of papers, new ideas usually pop in my head and I'm able to do some new research. It actually seems like it is the only way.


[Richard Hamming in "You and Your Research"](http://www.cs.virginia.edu/~robins/YouAndYourResearch.html) wrote several good advice:

> Let me start not logically, but psychologically. I find that the major objection is that people think great science is done by luck. It's all a matter of luck. Well, consider Einstein. Note how many different things he did that were good. Was it all luck? Wasn't it a little too repetitive? Consider Shannon. He didn't do just information theory. Several years before, he did some other good things and some which are still locked up in the security of cryptography. He did many good things.

> You see again and again, that it is more than one thing from a good person. Once in a while a person does only one thing in his whole life, and we'll talk about that later, but a lot of times there is repetition. I claim that luck will not cover everything. And I will cite Pasteur who said, ``Luck favors the prepared mind.'' And I think that says it the way I believe it. There is indeed an element of luck, and no, there isn't. The prepared mind sooner or later finds something important and does it. So yes, it is luck. The particular thing you do is luck, but that you do something is not.

Sam Altman wrote "[compound yourself](http://blog.samaltman.com/how-to-be-successful)" the other day, which reflects what Hamming was saying as well when quoting Bode:

> What Bode was saying was this: ``Knowledge and productivity are like compound interest.'' Given two people of approximately the same ability and one person who works ten percent more than the other, the latter will more than twice outproduce the former. The more you know, the more you learn; the more you learn, the more you can do; the more you can do, the more the opportunity - it is very much like compound interest

**Mental State**.

Here's some quote about being in the right state of mind. From Hamming again. The first one rings true to me as I gained much more confidence in doing research after releasing a few papers and being cited.

> One success brought him confidence and courage

The second one is quite impactful as well, as trains, planes and hotels without wifi are often my most productive places to work from:

> What most people think are the best working conditions, are not. Very clearly they are not because people are often most productive when working conditions are bad

It even sounds like prison, yes prison, is sometimes cited as the best place to do one's work! This is an extract of a letter from [André Weil](https://en.wikipedia.org/wiki/Andr%C3%A9_Weil) after having spent some time in Rouen's prison:

> My mathematics work is proceeding beyond my wildest hopes, and I am even a bit worried - if it's only in prison that I work so well, will I have to arrange to spend two or three months locked up every year?

And if you can't believe this, here's what [Reddit has to say about it](https://www.reddit.com/r/books/comments/8fzc6u/just_spent_four_months_in_jail_i_read_over_thirty/):

> Just spent four months in jail. I read over thirty books and I feel like I’ve been born again.

**Important Problems**.

Hamming again, on working on important problems:

> And I started asking, "What are the important problems of your field?" And after a week or so, "What important problems are you working on?"

> If you do not work on an important problem, it's unlikely you'll do important work. It's perfectly obvious. Great scientists have thought through, in a careful way, a number of important problems in their field, and they keep an eye on wondering how to attack them

> I noticed the following facts about people who work with the door open or the door closed. I notice that if you have the door to your office closed, you get more work done today and tomorrow, and you are more productive than most. But 10 years later somehow you don't know quite know what problems are worth working on; all the hard work you do is sort of tangential in importance. He who works with the door open gets all kinds of interruptions, but he also occasionally gets clues as to what the world is and what might be important.

**One's limitations**.

[Silvio Micali gave a talk](https://www.youtube.com/watch?v=WSuUTLqqLIU&feature=youtu.be&t=3043) in which the last 10 minutes (which I linked) were a collection of advice for young researchers. It's quite fun to watch and emphasizes that one must be **stubborn** to go through with one's research. He also mentions being fine with one's limitations:

> Our limitation is our strength. Because of your limitation you are forced to approach a problem differently.

**Maker's schedule**.

[Paul Graham wrote "Maker's schedule, manager's schedule"](http://www.paulgraham.com/makersschedule.html) which differentiates the kind of work schedule one can have:

> When you're operating on the maker's schedule, meetings are a disaster. A single meeting can blow a whole afternoon, by breaking it into two pieces each too small to do anything hard in. Plus you have to remember to go to the meeting. That's no problem for someone on the manager's schedule. There's always something coming on the next hour; the only question is what. But when someone on the maker's schedule has a meeting, they have to think about it.

This is something Hamming touched as well, but more on the personal life plan:

> "I don't like to say it in front of my wife, but I did sort of neglect her sometimes; I needed to study. You have to neglect things if you intend to get what you want done. There's no question about this."


I can't remember where I read that, but someone was saying that deadlines were great, and that he/she was often promising things to people in order to get things done. The idea was that if you break your promise, you lose integrity and shame rains upon you. So that's some sort of self-fabricated pressure.


If you know more cool articles and videos like that, please share :) ]]>
Speed and Cryptography David Wong Fri, 18 Jan 2019 02:19:33 +0100 http://www.cryptologie.net/article/468/speed-and-cryptography/ http://www.cryptologie.net/article/468/speed-and-cryptography/#comments
> when I started it was a question of being responsive to the industry and practical needs [...] Now I think these are much deeper questions [...] Who benefits from the work we do? [...] Who benefits from making things faster beyond a certain point? The constant search for speed. What sort of people do we become when we cannot wait half a second for a web page to load because TLS is doing a round trip and we're cutting corners.

In here, Bellare is obviously hinting at Eric Rescorla's work with TLS 1.3, in particular the **0-RTT** or **early data** feature of the new protocol. If you don't know what it is, it's a new feature which allows a client to send encrypted data as part of its very first flight of messages. [As I explained in this video](https://davidwong.fr/tls13/#section-2), it does not protect against **replay attacks**, nor benefits from **forward secrecy**.

**Replay**: a passive observer can record these specific messages, then replay them at a later point in time. You can imagine that if the messages were bank transactions, and replaying them would prompt the bank to initiate a new transaction, then that would be a problem.

**Forward Secrecy**: TLS sessions in TLS 1.3 benefits from this security property by default. If the server's long-term keys are stolen at a certain point in time, previous sessions won't be decryptable. This is because each session's security is augmented by doing an **ephemeral** key exchange with keys that are **deleted** right after the handshake. To break such a session you would need to obtain these ephemeral keys in addition to the long-term key of the server. Sending 0-RTT data happens before any ephemeral key exchange can happen. The data is simply encrypted via a key derived from a pre-shared key (PSK). Here the lack of forward secrecy means that if the PSK is stolen at a later point in time, that data will be decryptable. This is much less of an issue for browsers as these PSK are often short-lived, but it's not always the case in other scenarios.

0-RTT has been pretty controversial, it has generated a lot of discussion on the TLS 1.3 mailing list (see [1](https://mailarchive.ietf.org/arch/msg/tls/HUUpDl7KUOGhcY_W_IC2vWRAot0), [2](https://mailarchive.ietf.org/arch/msg/tls/mHxi-O3du9OQHkc6CBWBpc_KBpA), [3](https://mailarchive.ietf.org/arch/msg/tls/pv7hi1FWtJzC7ekhbMUl5daDys8)) and concerns about its security have taken an entire section in [the specification itself](https://davidwong.fr/tls13/#section-8).

While I spent quite some time telling you about TLS 1.3's 0-RTT in this post, it is just one example of a security trade-off that **WE** made, all of us, for the benefit of a few big players. Was it the right thing to do? Maybe, maybe not.

What are the other examples? Well guess why we're using AES-GCM? Because it is hardware accelerated. But who asked Intel for it? Why are we standardizing a shitty WPA 3.0 protocol? Probably because some Wi-Fi Alliance is telling us to use it, but what the F is going on there? Why is full disk encryption (FDE) completely flawed? I am not even talking about the recent [Self-encrypting deception: weaknesses in the encryption of solid state drives (SSDs)](https://www.ru.nl/publish/pages/909275/draft-paper_1.pdf) research, but rather the fact that vendors implementing FDE are never using authentication on ciphertexts! and continue to refuse to tackle the issue via primitives like wide-block ciphers. Probably because it's not fast enough!

Now look at what cryptographic primitives people are pushing for nowadays: AES-GCM, Chacha20-Poly1305, Curve25519, BLAKE2. This is pretty much what you're forced into if you're using any protocol in 2019 (yes even the [Noise Protocol Framework](http://noiseprotocol.org/)). Are these algorithms bad? Of course not. But they are there because large companies wanted them. And they wanted them because they were fast. I touched on that in [Maybe you shouldn't skip SHA-3](https://www.cryptologie.net/article/400/maybe-you-shouldnt-skip-sha-3/) after Adam Langley's wrote an article on SHA-3 not being fast enough.

> We're in a crypto era where the hotness is in the "cycles per byte" (cpp).

All of this is concerning, because once you look at it this way, you see that big players have a huge influence over our standards and the security trade-offs we end up doing for speed are not always worth it.

If you're not a big player, you most likely don't care about these kinds of optimizations. The cryptography you use is not going to be the bottleneck of your application. You do not have to do these trade-offs.

QUIC + Noise = nQUIC David Wong Thu, 17 Jan 2019 20:13:45 +0100 http://www.cryptologie.net/article/467/quic-noise-nquic/ http://www.cryptologie.net/article/467/quic-noise-nquic/#comments
nQUIC = Noise + QUIC

If you don't know what QUIC is, let me briefly explain: it is the last invention of Google, which is being standardized with the IETF. It's a take on the lessons learned developing HTTP/2 about the limitations of TCP. You can see it as a better TCP(2.0) for a better HTTP(/3) with encryption built in by default.

The idea is that, when you visit a page, you end up fetching way more files than you think. There is some `.css`, some `.js`, a bunch of `.png` and maybe even other pages via some iframes. To do this, browsers have historically opened multiple TCP connections (to the same server perhaps) in order to receive the file faster. This is called multiplexing and it's not too hard to do, you just need to use a different TCP port for every connection you create. The problem is that it takes time for each TCP connection to start (there is a TCP handshake as well as a TLS handshake) and then to figure out how fast they can go (TCP flow control).

![browser http](/upload/11.JPG)

So in HTTP/2, instead of opening several TCP connections to the same server, we just open one. We then do the multiplexing inside of this one connection.


So now you're doing one TCP handshake, then you optimize the connection via TCP's mechanism, and you rely on that to receive whatever the server sends to you. It sends you a bunch of blocks, in whatever order, that you can buffer and glue back together. For example, you might receive some html, then some jpg, then the rest of the html.

One problem is that if faults start appearing on the network, all the different objects you're trying to receive will be impacted, not just one of them. So one ACK can mess every element on the page.

Comes **QUIC** which fixes these multiplexing issues by re-inventing TCP. Because of middle boxes and firewall issues, QUIC is built on top of UDP instead of creating another protocol on top of IP. It doesn't matter much in theory because UDP is just IP with ports (and ports are useful).

QUIC has different streams, which can carry different content (in order) and are not impacted by issues happening in other streams. You can thus carry the html page in one stream, an image in another stream, the css file in another stream, etc.

On top of that, the people at Google thought that encryption would be very useful to have baked into the protocol instead of making it optional and a responsability of applications (that's what TLS is). Google started this encryption mechanism with QUIC Crypto, which was a very simple protocol, and then decided to replace it with TLS 1.3. While this might make sense for the web, it doesn't really make sense in other settings where simpler security protocols could be used. [This is what I talked about in more length in this blog post](https://cryptologie.net/article/446/quic-crypto-and-simple-state-machines/). Go read it before reading the rest of this post, I'll wait.

You read it? Nice. Well you'll be delighted to see that the nQUIC I've talked about in the first line of this article is exactly what I've been talking about: QUIC secured by the Noise Protocol Framework instead of TLS 1.3.

[You can read about the research here](https://eprint.iacr.org/2019/028). What we found is that it is extremly **easy** to integrate Noise into QUIC, because it was made to be encapsulated into a lower protocol, whereas integrating TLS 1.3 into QUIC is very hackish. It is also faster, because of the lack of signatures. It is way more secure, thanks to the lack of complexity and x509 parsing as well as the symbolic proofs provided by the research community (see for example [NoiseExplorer](https://noiseexplorer.com/), and [its wonderful talk at Real World Crypto 2019](https://www.youtube.com/watch?v=ZrcdDJhbPKQ)). Finally, we have also added post-compromise security to the protocol, which is a must for long-lived sessions.

Developers Are Not Idiots David Wong Wed, 16 Jan 2019 00:51:31 +0100 http://www.cryptologie.net/article/466/developers-are-not-idiots/ http://www.cryptologie.net/article/466/developers-are-not-idiots/#comments
If you're like me, you must have heard the security jokes about developers during conferences, read the github issues of independent researchers yelling at volunteering contributors, or maybe witnessed developer shaming in whitepapers you read. Although it is (I believe) a minority, it is a pretty vocal one that has given a bad rap to security in general. Don't believe me? Go and ask someone working at a company with an internal security team, or read what [Linus has to say about it](http://lkml.iu.edu/hypermail/linux/kernel/1711.2/01701.html). Of course different people at different companies will have different kind of experiences, so don't take this post as a generalization.

It is true that developers often don't give a damn about security. But this is not a good reason to dismiss them. If you work in the field, it is important to ask yourself "**why?**" first. And if you're a good person, what should follow next is "**how can I help?**".

**Why?** It might not be totally clear to people who have done little to no (non-security focused) development, but the mindset of someone who is writing an application is to build something cool. Imagine that you're trying to ship some neat app, and you realize that you haven't written the login page yet. It now dawns on you that you will have to figure out some rate-limiting password attempt mechanism, how to store the passwords, a way for people to recover their passwords, perhaps even two-factor authentication... But you don't want to do all of that, do you? You just want to write the cool app. You want to ship... Now imagine that after a few days you get everything done, and now some guy that you barely know is yelling at you because there is an exploitable XSS in your application. You almost hear yourself saying out loud "an XX-what?" and here goes your week end, perhaps even your week you start thinking. You will have to figure out what is going on, respond to the person who brought the bug, attempt to fix it. All of that while trying to minimize the impact on your personal reputation. And that's if it's only a single bug.

I have experienced this story of myself. Years ago, I was trying my hands with a popular PHP web framework of the time, when one of the config file asked from me to manually modify it in order to bootstrap the application. Naturally, I obliged, until I reached a line reading

// you must fill this value with a 32-random-characters key
$config['encryption_key'] = "";

Being pretty naive at the time, I simply wrote a bunch of words until I managed to get to the required number of letters (32). It must have looked like something like this:

// you must fill this value with a 32-random-characters key
$config['encryption_key'] = "IdontKnowWhatImDoing0932849jfewo";

Was I wrong? Or was it the framework's fault for asking me to do this in the first place? You got the idea: perhaps we should stop blaming developers.

**How can you help?** Empathize. You will often realize that security people who have worked non-security development jobs at some point in their career will often understand the developers better AND will manage to get them to fix things. I know, finding bugs is cool, and we're here to hack and break things. But some of these things have people behind them, the codebase is sometimes their own labor of love, their baby. Take the time to teach them about was is wrong, if they don't understand they won't be able to fix the issues effectively. Use language to vehiculate your ideas, sure it is a critical finding but do you need to write that on a github issue to shame someone? Perhaps the word "important" is better? Put yourself in their shoes and help them understand that you're not just coming here to break things, but you're helping them to make their app a better one! How awesome is that?

Sure they need to fix things and take security seriously. But how you get to there is as important.

I also need to mention that building better APIs for developers is an active area of research. You can't educate everyone, but you can contribute: write good tutorials (copy/pastable examples first), good documentation, and safe-by-default frameworks.

Thank-you for reading this.

Your mission, should you choose to accept it, is to be an awesome security peep now :)

EDIT: [Mason](https://twitter.com/mah3mm/status/1087387349619785730) pointed me to [this article](https://zeltser.com/security-assessment-report-as-critique/) which I think has some really good points as well:

> Another element of a critique-focused report involves the discussion of positive findings of the assessment. As the saying goes, a spoonful of sugar makes the medicine go down.

And indeed, If I liked what I've seen during an audit, I always start a discussion by telling the developers how much I liked the code/protocol/documentation. They are always really happy to hear it and my followed-up critiques are heard way more seriously. Interestingly enough, I've always felt like this is how a good performance-review should go as well.
!(Spotting the promising cryptography-related start ups) David Wong Sat, 12 Jan 2019 05:04:36 +0100 http://www.cryptologie.net/article/465/spotting-the-promising-cryptography-related-start-ups/ http://www.cryptologie.net/article/465/spotting-the-promising-cryptography-related-start-ups/#comments
It turns out that it is often quite easy to quickly spot the bad grapes by noticing common red flags. Here's a list of key words that you should probably stay away from: patented, proprietary protocol, one-time pad, AES-256, unbreakable, post-quantum, ICO, supply-chain, AI, machine learning, re-inventing TLS, etc.

In general, if a company focuses its pitch on the actual crypto they use instead of the problems they solve, you might want to turn around. If something doesn't seem right, find an expert to help you. Even Ycombinator got fooled. ]]>
Proof of Elgamal's semantic security using a reduction to DDH David Wong Tue, 01 Jan 2019 07:42:10 +0100 http://www.cryptologie.net/article/464/proof-of-elgamals-semantic-security-using-a-reduction-to-ddh/ http://www.cryptologie.net/article/464/proof-of-elgamals-semantic-security-using-a-reduction-to-ddh/#comments
I like drawing, and I haven't drawn in a long time. I figured I could use crypto as an excuse to draw something and start this year in a more creative way :)

(by the way, [here is the talk I'm talking about](https://media.ccc.de/v/35c3-9517-provable_security#t=1631))

Here I glance over a lot of the concepts. I don't explain what is Elgamal or how it works, I don't explain proofs based on games and what semantic security is (and why it is considered insufficient), I don't even explain what I mean by an adversary's advantage. I'm expecting that you will read that on your own and then head here to understand how you can use all of that to prove Elgamal's semantic security.

![elgamal ind cpa semantic security reduction proof ddh comic](/upload/1_color.JPG)

![elgamal ind cpa semantic security reduction proof ddh comic](/upload/2_color.JPG)

![elgamal ind cpa semantic security reduction proof ddh comic](/upload/3_color.JPG) ]]>
A Readable TLS 1.3 Specification David Wong Fri, 28 Dec 2018 20:05:56 +0100 http://www.cryptologie.net/article/463/a-readable-tls-13-specification/ http://www.cryptologie.net/article/463/a-readable-tls-13-specification/#comments
<iframe width="100%" height="315" src="https://www.youtube.com/embed/m8cRCACNz-A" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

If you take a look at [the original RFC: 8446](https://tools.ietf.org/html/rfc8446) you will see that it's not that pretty.

The page I created contains many things to simplify one's life in reading the dense specification:

* erratas are applied
* references can be previewed
* figures were re-created
* etc.

For example, here is the state machine of the TLS client now:

![client state machine tls 1.3](https://davidwong.fr/tls13/img/sm1.png)

And here is the server:

![server state machine tls 1.3](https://davidwong.fr/tls13/img/sm2.png)
Public Audits David Wong Wed, 26 Dec 2018 21:32:45 +0100 http://www.cryptologie.net/article/462/public-audits/ http://www.cryptologie.net/article/462/public-audits/#comments
Recently, two reports were published with my name on it. The [Android Pie](https://security.googleblog.com/2018/10/google-and-android-have-your-back-by.html) and [Nucypher PRE library](https://www.nccgroup.trust/us/our-research/pyumbral-proxy-re-encryption-library-audit/).

Unfortunately we rarely release much details when we find critical vulnerabilities, so the more interesting reports are always partially published (like the Google one) or just not public. One day I'll find a way to talk about (without leaking out any information about clients of course) some of the juicy findings I and others have found in my years of consulting. Some of these war stories are extremely entertaining. We sometimes don't find much, but when we completely break a cryptocurrency or a company's flagship product, it feels like we're the best in the world at what we do. ]]>
The 9 Lives of Bleichenbacher's CAT: New Cache ATtacks on TLS Implementations David Wong Sat, 01 Dec 2018 00:45:56 +0100 http://www.cryptologie.net/article/461/the-9-lives-of-bleichenbachers-cat-new-cache-attacks-on-tls-implementations/ http://www.cryptologie.net/article/461/the-9-lives-of-bleichenbachers-cat-new-cache-attacks-on-tls-implementations/#comments
On May 15th, I approached Yuval Yarom with a few issues I had found in some TLS implementations. This led to a collaboration between Eyal Ronen, Robert Gillham, Daniel Genkin, Adi Shamir, Yuval Yarom and I. Spearheaded by Eyal, [the research has now been published here](https://eprint.iacr.org/2018/1173). And as you can see, the inventor of RSA himself is now recommending you to deprecate RSA in TLS.

We tested 9 different TLS implementations against cache attacks and 7 were found to be vulnerable: [OpenSSL](http://openssl.org/), [Amazon s2n](https://aws.amazon.com/blogs/security/introducing-s2n-a-new-open-source-tls-implementation/), [MbedTLS](https://tls.mbed.org/), [Apple CoreTLS](https://opensource.apple.com/tarballs/coreTLS/), [Mozilla NSS](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS), [WolfSSL](https://www.wolfssl.com/), and [GnuTLS](https://www.gnutls.org/). The cat is not dead yet, with two lives remaining thanks to [BearSSL](https://bearssl.org/) (developed by my colleague Thomas Pornin) and Google's [BoringSSL](https://boringssl.googlesource.com/boringssl/).

The issues were disclosed back in August and the teams behind these projects were given time to resolve them. Everyone was very cooperative and CVEs have been dispatched (CVE-2018-12404, CVE-2018-19608, CVE-2018-16868, CVE-2018-16869, CVE-2018-16870).

The attack leverages a side-channel leak via cache access timings of these implementations in order to break the RSA key exchanges of TLS implementations. The attack is interesting from multiple points of view (besides the fact that it affects many major TLS implementations):

* **It affects all versions of TLS (including TLS 1.3) and QUIC**. Where the latter version of TLS does not even offer an RSA key exchange! This prowess is achieve because of the only known downgrade attack on TLS 1.3.
* **It uses state-of-the-art cache attack techniques**. Flush+Reload? Prime+Probe? Branch-Predition? We have it.
* **The attack is very efficient**. We found ways to ACTIVELY target any browsers, slow some of them down, or use the long tail distribution to repeatdly try to break a session. We even make use of lattices to speed up the problem.
* **Manger and Ben-Or on RSA PKCS#1 v1.5**. You heard of Bleichenbacher's million messages attack? Guess what, we found better. We use Manger's OAEP attack on RSA PKCS#1 v1.5 and even Ben-Or's algorithm which is more efficient than and was published BEFORE Bleichenbacher's work in 1998. [I uploaded some of the code here](https://github.com/mimoo/RSA_PKCS1v1_5_attacks).

To learn more about the research, [you should read the white paper](http://cat.eyalro.net/). I will talk specifically about protocol-level exploitation in this blog post.

## Attacking RSA, The Origins

While [Ben-Or et al.](https://dl.acm.org/citation.cfm?id=808773) research was initially used to support the security proofs of RSA, it was none-the-less already enough to attack the protocol. But it is only in 1998 that Daniel Bleichenbacher discovers a padding oracle and devise his own practical attack on RSA. The consequences are severe, most TLS implementations could be broken, thus mitigations were designed to prevent Daniel's attack. Follows a series of "re-discovery" where the world realizes that it is not so easy to implement such mitigations:

* <a href="http://archiv.infsec.ethz.ch/education/fs08/secsem/bleichenbacher98.pdf">Bleichenbacher (CRYPTO 1998)</a> also called the 1 million message attack, BB98, padding oracle attack on PKCS#1 v1.5, etc.
* <a href="https://eprint.iacr.org/2003/052">Klima et al. (CHES 2003)</a>
* <a href="https://www.nds.rub.de/media/nds/veroeffentlichungen/2012/12/19/XMLencBleichenbacher.pdf">Blei­chen­ba­cher’s At­tack Strikes Again: Brea­king PKCS#1 V1.5 In Xml En­cryp­ti­on (ESORICS 2012)</a>
* <a href="https://eprint.iacr.org/2011/615.pdf">Degabriele et al. (CT-RSA 2012)</a>
* <a href="https://eprint.iacr.org/2012/417">Bardou et al. (CRYPTO 2012)</a>
* <a href="https://www.cs.unc.edu/~reiter/papers/2014/CCS1.pdf">Cross-Tenant Side-Channel Attacks in PaaS Clouds (CCS 2014)</a>
* <a href="https://www.usenix.org/conference/usenixsecurity14/technical-sessions/presentation/meyer">Revisiting SSL/TLS Implementations: New Bleichenbacher Side Channels and Attacks (USENIX 2014)</a>
* <a href="https://www.nds.rub.de/media/nds/veroeffentlichungen/2015/08/21/Tls13QuicAttacks.pdf">On the Security of TLS 1.3 and QUIC Against Weaknesses in PKCS#1 v1.5 Encryption (CCS 2015)</a>
* <a href="https://drownattack.com/">DROWN (USENIX 2016)</a>
* <a href="https://robotattack.org/">Return Of Bleichenbacher's Oracle Threat (USENIX 2018)</a>
* <a href="https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-felsch.pdf">The Dangers of Key Reuse: Practical Attacks on IPsec IKE (USENIX 2018)</a>

Let's be realistic, **the mitigations that developers had to implement were unrealistic**. Furthermore, an implementation that would attempt to log such attacks would actually help the attacks. Isn't that funny?

The research I'm talking about today can be seen as one more of these "re-discovery". My previous boss' boss (Scott Stender) once told me: "you can either be the first paper on the subject, or the best written one, or the last one". We're definitely not the first one, I don't know if we write that well, but we sure are hopping to be the last one :)

## RSA in TLS?

Briefly, SSL/TLS (except TLS 1.3) can use an RSA key exchange during a handshake to negotiate a shared secret. An RSA key exchange is pretty straight forward: the client encrypts a shared secret under the server's RSA public key, then the server receives it and decrypts it. If we can use our attack to decrypt this value, we can then passively decrypt the session (and obtain a cookie for example) or we can actively impersonate one of the peer.

## Attacking Browsers, In Practice.

We employ the BEAST-attack model (in addition to being colocated with the victim server for the cache attack) which I have previously explained [in a video here](https://cryptologie.net/article/413/beast-an-explanation-of-the-cbc-attack-on-tls/).


With this position, we then attempt to decrypt the session between a victim client (Bob) and `bank.com`: we can serve him with some javascript content that will continuously attempt new connections on `bank.com`. (If it doesn't attempt a new connection, we can force it by making the current one fail since we're in the middle.)

**Why several connections instead of just one?** Because most browsers (except Firefox which we can fool) will time out after some time (usually 30s). If an RSA key exchange is negotiated between the two peers: it's great, we have all the time in the world to passively attack the protocol. If an RSA key exchange is NOT negotiated: we need to actively attack the session to either downgrade or fake the server's RSA signature (more on that later). This takes time, because the attack requires us to send thousands of messages to the server. It will likely fail. But if we can try again, many times? It will likely succeed after a few trials. And that is why we continuously send connection attempts to `bank.com`.

## Attacking TLS 1.3

There exist two ways to attack TLS 1.3. In each attack, the server needs
to support an older version of the protocol as well.

1. The first technique relies on the fact that the current server’s public key is an RSA public
key, used to sign its ephemeral keys during the handshake, and that the
older version of TLS that the server supports re-use the same keys.
1. The second one relies on the fact that both peers support an older version
of TLS with a cipher suite supporting an RSA key exchange.

While TLS 1.3 does not use the RSA encryption algorithm for its key
exchanges, it does use the signature algorithm of RSA for it; if the
server’s certificate contain an RSA public key, it will be used to sign
its ephemeral public keys during the handshake. A TLS 1.3 client can
advertise which RSA signature algorithm it wants to support (if any)
between RSA and RSA-PSS. As most TLS 1.2 servers already provide support
for RSA , most will re-use their certificates instead of updating to the
more recent RSA-PSS. RSA digital signatures specified per the standard
are really close to the RSA encryption algorithm specified by the same
document, so close that Bleichenbacher’s decryption attack on RSA
encryption also works to forge RSA signatures. Intuitivelly, we have
$pms^e$ and the decryption attack allows us to find $(pms^e)^d = pms$,
for forging signatures we can pretend that the content to be signed
$tbs$ ([see RFC 8446](https://tools.ietf.org/html/rfc8446#section-4.4.3)) is $tbs = pms^e$ and obtain $tbs^d$ via the attack, which is
by definition the signature over the message $tbs$. However, this
signature forgery requires an additional step (blinding) in the
conventional Bleichenbacher attack (in practice this can lead to
hundreds of thousands of additional messages).

![The TLS 1.3 signature forgery attack using a TLS 1.2 server as Bleichenbacher oracle.](https://www.cryptologie.net/upload/tls13signatures.png)

[Key-Reuse has been shown](https://drownattack.com/) in the past to allow
for complex cross-protocol attacks on TLS. Indeed, we can successfully
forge our own signature of the handshake transcript (contained in the
`CertificateVerify` message) by negotiating a previous version of TLS
with the same server. The attack can be carried if this new connection
exposes a length or bleichenbacher oracle with a certificate using the
same RSA key but for key exchanges.

## Downgrading to TLS 1.2

Every TLS connection starts with a negotiation of the TLS version and
other connection attributes. As the new version of TLS (1.3) does not
offer an RSA key exchange, the exploitation of our attack must first
begin with a downgrade to an older version of TLS. TLS 1.3 being
relatively recent (August 2018), most servers supporting it will also
support older versions of TLS (which all provide support for RSA key
exchanges). A server not supporting TLS 1.3 would thus respond with an
older TLS version’s (TLS 1.2 in our example) server hello message. To
downgrade a client’s connection attempt, we can simply spoof this answer
from the server. Besides protocol downgrades, other techniques exist to
force browser clients to fallback onto older TLS versions: network
glitches, a spoofed TCP RST packet, a lack of response, etc. (see [POODLE](https://www.openssl.org/~bodo/ssl-poodle.pdf))

![The TLS 1.3 attack downgrades the victim to an older version of TLS.](https://www.cryptologie.net/upload/tls13downgrade.png)

Continuing with a spoofed TLS 1.2 handshake, we can simply present the
server’s RSA certificate in a `ServerCertificate` message and then end
the handshake with a `ServerHelloDone` message. At this point, if the
server does not have a trusted certificate allowing for RSA key
exchanges, or if the client refuse to support RSA key exchanges or older
versions than TLS 1.2, the attack is stopped. Otherwise, the client uses
the RSA public key contained in the certificate to encrypt the TLS
premaster secret, sends it in a `ClientKeyExchange` message and ends its
part of the handshake with a `ChangeCipherSpec` and a `Finished`

![The Decryption Attack performs a new handshake with the server, using a modified encrypted premaster secret obtained from the victim’s `ChangeCipherSpec` message.](https://www.cryptologie.net/upload/attack.png)

At this point, we need to perform our attack in order to decrypt the RSA
encrypted premaster secret. The last Finished message that we send must
contains an authentication tag (with HMAC) of the whole transcript, in
addition of being encrypted with the transport keys derived from the
premaster secret. While some clients will have no handshake timeouts,
most serious applications like browsers will give up on the connection
attempt if our response takes too much time to arrive. While the attack
only takes a few thousand of messages, this might still be too much in
practice. Fortunately, several techniques exist to slow down the

* we can send the ChangeCipherSpec message which might reset the client’s timer
* [we can send TLS warning alerts to reset the handshake timer](https://weakdh.org/)

Once the decryption attack terminates, we can send the expected Finished
message to the client and finalize the handshake. From there everything
is possible, from passively relaying and observing messages to the
impersonated server through to actively tampering requests made to it.
This downgrade attack bypasses multiple downgrade mitigations: one
server-side and two client-side. TLS 1.3 servers that negotiate older
versions of TLS must advertise this information to their peers. This is
done by setting a quarter of the bytes from the `server_random` field in
the `ServerHello` message to [a known value](https://tools.ietf.org/html/rfc8446#section-4.1.3). TLS 1.3 clients that end
up negotiating an older version of TLS must check for these values and
abort the handshake if found. But as noted by the RFC, “It does not
provide downgrade protection when static RSA is used.” – Since we alter
this value to remove the warning bytes, the client has no opportunity to
detect our attack. On the other hand, a TLS 1.3 client that ends up
falling back to an older version of TLS [must advertise this information in their subsequent client hellos](https://tools.ietf.org/html/rfc7507), since
we impersonate the server we can simply ignore this warning.
Furthermore, a client also includes the version used by the client hello
inside of the encrypted premaster secret. For the same reason as
previously, this mitigation has no effect on our attack. As it stands,
RSA is the only known downgrade attack on TLS 1.3, which we are the
first to successfuly exploit in this research.

## Attacking TLS 1.2

As with the previous attack, both the client and the server targetted
need to support RSA key exchanges. As this is a typical key exchange
most known browsers and servers support them, although they will often
prefer to negotiate a forward secret key exchange based on ephemeral
versions of the Elliptic Curve or Finite Field Diffie-Hellman key
exchanges. This is done as part of the cipher suite negotiation during
the first two handshake messages. To avoid this outcome, the
`ClientHello` message can be intercepted and modified to strip it out of
any non-RSA key exchanges advertised. The server will then only choose
from a set of RSA-key-exchange-based cipher suites which will allow us
to perform the same attack as previously discussed. Our modification of
the `ClientHello` message can only be detected with the `Finished`
message authenticating the correct handshake transcript, but since we
are in control of this message we can forge the expected tag.

![The attack on TLS 1.2 modifies the client’s first packet to force an RSA key exchange.](https://www.cryptologie.net/upload/tls12attack.png)

On the other side, if both peers end up negotiating an RSA key exchange
on their own, we can passively observe the connection and take our time
to break the session.
Browser End-to-End Encryption David Wong Sat, 24 Nov 2018 00:25:16 +0100 http://www.cryptologie.net/article/460/browser-end-to-end-encryption/ http://www.cryptologie.net/article/460/browser-end-to-end-encryption/#comments
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">“We use the standard Bellare-Rogaway definition of key exchange, which we briefly summarize below. [Fourteen pages of dense notation omitted] And in conclusion most Bluetooth devices use ‘000000’ as the hardcoded password.”</p>— Matthew Green (@matthew_d_green) <a href="https://twitter.com/matthew_d_green/status/1066080534110056449?ref_src=twsrc%5Etfw">November 23, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

I have seen this kind of things happen quite often in the cryptography and security community. While some companies are 100% snake oils, some others do play on the border with their marketing claims but very real research. For example, advances in encrypted databases are mostly pushed by companies while attacks come from researchers not happy with their marketing claims. But this is a story for another time.

Back to the question: can we provide end-to-end encryption with a web app? There are ways yes. You can for example create a one-page javascript web application, and have the client download it. In that sense it could be a "trust on first use" kind of application, because later you would only rely on your local copy. If you want to make it light, have the page use remotely served javascript, images, and other files and protect manipulations via the [subresource integrity mechanism](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) of web browsers (include a hash of the file in the single-page web app). It is not a "bad" scenario, but it's not the flow that most users are used to. And this is the problem here. We are used to access websites directly, install whatever, and update apps quickly.

If you look at it from the other side, are mobile applications that more secure? While the threat model is not THAT different, in both of these solutions (thanks Nik Kinkel and Mason Hemmel for pointing that out to me) no specific targetting can happen. And this is probably a good argument if you're paranoia stops at this level (and you trust the app store, your OS, your hardware, etc.)
Indeed, a webapp can easily target you, serving a different app depending on the client's IP, whereas mobile apps need the cooperation of the App store to do that. So you're one level deeper in your defense in depth.

What about Signal's "native" desktop application? Is it any better? Well... you're probably downloading it from their webserver anyway and you're probably updating the app frequently as well...

EmbeddedDisco David Wong Wed, 21 Nov 2018 03:41:52 +0100 http://www.cryptologie.net/article/459/embeddeddisco/ http://www.cryptologie.net/article/459/embeddeddisco/#comments
I've been implementing the [Disco protocol](https://www.cryptologie.net/article/432/introducing-disco/) in C. It makes sense since Disco was designed specifically for embedded devices. The library is only **1,000 lines-of-code**, including all the cryptographic primitives, and does everything the Go implementation does except for signing.

If you don't know what Disco is, it's a **cryptographic library** that allows you to secure communications (like TLS) and to hash, encrypt, authenticate, derive keys, generate random numbers, etc.

[Check it out here](https://github.com/mimoo/disco-c). It's **experimental**. I'd be happy to receive any feedback :)

It's not as plug-and-play as the Golang version. There are no wrappers yet to encrypt, authenticate, hash, derive keys, etc. and I haven't made a decision as to what algorithm I should support for signatures (ed25519 with strobe? Or Strobe's Schnorr-variant with Curve25519?)

So it's mostly for people who know what they're doing for now.

Don't let that deter you though! I need people to play with it in order to improve the library. If you need help I'm here! ]]>
The Cryptography Services of NCC Group is looking for summer interns! David Wong Thu, 01 Nov 2018 22:57:23 +0100 http://www.cryptologie.net/article/458/the-cryptography-services-of-ncc-group-is-looking-for-summer-interns/ http://www.cryptologie.net/article/458/the-cryptography-services-of-ncc-group-is-looking-for-summer-interns/#comments About Disco (again) David Wong Fri, 19 Oct 2018 23:45:47 +0200 http://www.cryptologie.net/article/457/about-disco-again/ http://www.cryptologie.net/article/457/about-disco-again/#comments
The funny one is this realistically proportional figure where the areas of the different circles are representing the number of lines-of-code of each libraries.

![Disco lines of code](/upload/LOC.png)

The C library is currently awful, so I won't link to it until I get it to a prettier place, but as a proof of concept it shows that this can be achieve in a mere 1,000 lines-of-code. That while supporting the same functionalities of a TLS library and even more. The following diagram is the dependency graph or "trust graph" of an implementation of Disco:

![Disco trust graph](/upload/Screen_Shot_2018-10-19_at_2.37_.40_PM_.png)

As one can see, Disco relies on Strobe (which further relies on keccak-f) for the symmetric cryptography, and X25519 for the asymmetric cryptography. The next diagram shows the trust graph of a biased TLS 1.3 implementation for comparison:


This was done mostly for fun, so I might be missing some things, but you can see that it's starting to get more involved. Finally, I made a final diagram on what most installations actually depend on:


In this one I included other versions of TLS, but not all. I also did not include their own trust graph. Thus, this diagram is actually less complex that it could be in reality, especially knowning that [some companies](https://sites.google.com/site/bughunteruniversity/nonvuln/commonly-reported-ssl-tls-vulnerabilities) continue to support SSL 3.0 and TLS 1.0.

I've also included non-cryptographic things like x509 certificates and their parsers, because it is a major dependency which was dubbed [the most dangerous code in the world](https://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html) by M. Georgiev, S. Iyengar, S. Jana, R. Anubhai, D. Boneh, and V. Shmatikov.
Real World Crypto 2019 registrations open David Wong Wed, 03 Oct 2018 10:51:20 +0200 http://www.cryptologie.net/article/456/real-world-crypto-2019-registrations-open/ http://www.cryptologie.net/article/456/real-world-crypto-2019-registrations-open/#comments ]]> Encrypting a file David Wong Thu, 27 Sep 2018 13:03:05 +0200 http://www.cryptologie.net/article/455/encrypting-a-file/ http://www.cryptologie.net/article/455/encrypting-a-file/#comments
Encrypting a file is hard. I often need to do it to protect confidential data before sending it to someone. Besides PGP (yerk) there doesn't seem to be any light tools to do that easily. The next best option is often to have a common messaging app like Signal. So I made my own. It's called [Eureka](https://github.com/mimoo/eureka) and it's available in [binaries](https://github.com/mimoo/eureka/releases) or if you have Golang installed on your device, directly by doing this:

$ go get github.com/mimoo/eureka

It's also 100 LOC. It's just doing a simple job that seems to be missing from most default tooling. ]]>
Want to implement something fun today? David Wong Wed, 05 Sep 2018 12:44:34 +0200 http://www.cryptologie.net/article/454/want-to-implement-something-fun-today/ http://www.cryptologie.net/article/454/want-to-implement-something-fun-today/#comments
Disco is a specification that once implemented allows you to encrypt sessions (like TLS) and encrypt, authenticate, hash, generate random numbers, derive keys, etc. (like a cryptographic library). **All of that usually only needs less than a thousand lines of code.**

Here's how you can do it:

**1. Strobe.** The first step is to find a [Strobe](https://strobe.sourceforge.io/) implementation (Disco uses Strobe for all the **symmetric crypto**). Reference implementations of Strobe exist in C and Python, unofficial ones exist in [Golang](https://github.com/mimoo/StrobeGo) (from yours truly) and in [Rust](https://github.com/rozbb/strobe-rs) (from Michael Rosenberg). but if you're dealing with another language, you'll have to implement the [Strobe specification](https://strobe.sourceforge.io/specs/) first!

**2. Noise.** Read the "*How to Read This Document and Implement Disco*" section of the [Disco specification](http://discocrypto.com/disco.html). What it tells you is to implement the [Noise specification](http://noiseprotocol.org/noise.html) but to ignore its `SymmetricState` and `CipherState` sections. (You can also ignore any symmetric crypto in there.) You can find Noise libraries in any languages, but implementing it yourself is usually pretty straight forward (here you only really have to implement the `HandshakeState`).

**3. Disco.** Once you have that (which should take 500 LOC top), implement the `SymmetricState` specified by [Disco](http://discocrypto.com/disco.html).

**4. Tada!**

PS: if you want to write one in **python**, that'd be really great! You can take a look at the [already existing implementations here](https://github.com/mimoo/disco/issues/4). ]]>
Tamuro meetup in London tonight David Wong Fri, 31 Aug 2018 13:48:45 +0200 http://www.cryptologie.net/article/453/tamuro-meetup-in-london-tonight/ http://www.cryptologie.net/article/453/tamuro-meetup-in-london-tonight/#comments
To know the location you need to solve one of the challenges [there](https://twitter.com/TamuroLondon/status/1032983065591721986) summarized here as well:

* **EASY**: Decrypt the cipertext (single byte XOR) to find the GPS coordinates of the next Tamuro London meetup:
6d69766d686f69747568766861686e (hex string)
* **MEDIUM**: Solve the easy challenge without a brute-force method.
* **HARD**: https://gist.github.com/tkeetch/b1b21f621813ff11a75930f80f1c9e5b ]]>