# Publicly verify that a a ticket was issued by an authority with around 8 digits

Im building a backend for webapp(s), so that we can sell tickets for our events. The events ranges from 100-700 guests.

We sell tickets online and we would like to be able to scan the tickets at the entrance. This is done via a Barcode-128. But in the case it is not possible to scan the code, one should be able to type in the code and check it this way. So the code should not be longer than circa 12 digits.

Since on some location we have no internet it should be possible to download something like a public key before the festival.

I researched a little bit and found this. Which seemed like a fine solution. Simply take tow identifiers like the event- and order-id (maybe hash them), sign them and only take the first or last 5 digits of the signature and append them to the string. The verifier then can check the signature. But this mean that the verify either has to hold the privat key. To generate the whole signature and compare only a part of it or that the signature is very long. Am I right? I don't like this because the verifier should be independent from the seller.

Then I thought: okay let's do the same thing, take two identifiers and asymmetrically encrypt them. So I could share the private key and only if the second part can be decrypted with the public key and matches the first part the ticket is valid. The methods of async encryption that I know produce alway very long messages. So same problem as before.

Then I found this which seems fine. But im wondering if FPE is too easy to break since the checksum is only like 5 to 8 digits and that's not a lot of entropy.

Do I have to worry about this? Or does someone have a different, better idea? My knowledge of cryptography is ver limited. Maybe I understood something wrong.

Format Preserving Encryption would work fine. The change I would make is not using it as a 'checksum', but instead just taking the ticket number (which may be a value between 0 and, say, 699) and FPE encrypting that as a 12 digit number). That way, you don't have to worry about 'limited entropy', because breaking it would require either guessing the key (which, if it's 128 bits or more, is just too hard) or randomly guessing and hoping you hit on a valid barcode - in that case, if you issue 1,000 valid tickets (and so only values that decrypt to 0 through 999 are accepted), the probability of guessing correctly is $$10^{3-12}$$, that is, one in a billion - not real good odds.

The only issue I can see with FPE is that there are no common implementations (which is a shame - I believe FPE is a generally useful tool)

However, there is an alternative that is commonly available, and would work just as well - Message Authentication Codes (MAC).

A MAC works like a signature, except that there are not separate signing and verifying keys - instead, one key does both operations. You'd generate a random key, and give that to both the ticket issuer, and the ticket scanner (just like in the FPE idea).

What you'd do is have the first three digits of the ticket be the serial number 000-999 (or 699 if you have 700 guests). The rest of the digits would be the MAC of the first three digits, converted into decimal (and truncated appropriately). To validate the ticket, the scanner would take the first three digits, and compute the MAC (using the key it knows), and checks that to the last 9 digits.

This gives you the same security as the FPE idea, and MAC implementations are readily available. Of course, with an FPE, you don't have to worry about converting things into decimal (FPEs can work directly with decimal values); standard MACs work in binary, and so to make them decimal, some sort of base conversion will be needed; however base conversion code is far more straight-forward than working FPE code.

There are a number of types of MACs available; I'd stay away from MACs with an IV, and stick with either HMAC, KMAC and CMAC.

One final issue for you to consider (which has nothing to do about your question): one obvious attack would be to take a valid ticket, and run it through a copier, and generate a number of tickets which would all authenticate. If you have a single scanner, you can easily stop that (by having the scanner remember all the serial numbers it has seen before). If you have multiple, and they cannot communicate, well, that's a bigger issue.

• okay thank you for the extensive answer! I can't upvote because I have too less karma. And thanks for the additional issue. I thought about this and think I found a good solution, that is working for us. But with the MACs i would have the same issue like the signing one I would have to share the secret which I don't like. Would there be another solution. Do you think it is possible to do what I want
– Alex
Apr 7 at 22:31
• @Alex: actually, FPE would share the same issue; if you don't trust the verifier with the key, it doesn't work. On the other hand, how much can you trust the verifier? If you can trust the verifier not to generate tickets for this event (but you don't want to trust them about other events), the obvious way to do that is to generate a fresh key for each event - for the scanner, only download the key for this event... Apr 8 at 2:47
• yeah I first thought there was a asymmetric way of doing this. but I only found one paper. I think I have to compromise
– Alex
Apr 8 at 7:37
• This does not meet the public requirement. With less than about 70 decimal digits (give or take), nothing secure will.
– fgrieu
Apr 9 at 9:43