In 2013, we found the Seattle-Köln Exchange Multicache, which requires cooperation between geocachers from Cologne and Seattle. This led to the idea of a geocache where two people at different locations had to press a button at exactly the same time in order to be able to open their respective cache boxes. And now the idea has become reality!
Implementing the idea creates a number of interesting challenges on the conceptual, on the software implementation, and on the hardware level. How can you make sure that the two geocachers pressed the button at the same time?
Since I want to have the geocaches a few hundred kilometers away from each other (say, Freiburg and Osnabrück), a wireless connection between the cache boxes is not an option. The only possible way is to rely on accurate clocks, which is a challenge in itself.
But even assuming accurate clocks, how do you make sure that the two parties pressed the button at the same time? The idea is to use cryptographic methods similar to the ones employed by authentication apps using time-based generation of passcodes.
Finally, you have to make sure that the cache box only opens if the right numbers are keyed in. So, if you do not want to design such a box from scratch, you have to modify an existing one.
All of that kept me busy for quite some time, but in the end it all worked out.
How much accuracy do you need for such a cache? If you want to have clocks that do not deviate from each other more than 1 second over the lifetime of, say, ten years, then you have to spend a lot of effort. An atomic clock would do, but most of them are too clunky to fit into a cache box. These days, you can get a chip-sized Rubidium-based atomic clock, such as the ICPT-1, which would give you an accuracy of 10-15, i.e., less than one 2 µs deviation in 10 years. Unfortunately, it costs more than €3000 and needs roughly 500 mA at 3.3 Volts, which is too much for a battery operated device.
A much cheaper alternative is to use either the GPS time signal, which is based on atomic clocks, or the DCF77 radio signal in Germany, which transmits the official German time, again based on an atomic clock. In other areas, there are similar radio time signals. The main problem is that if I do not have control of how the receivers and, in particular, the antennas are placed, one cannot guarantee that the respective signal is indeed received, which rules out these options.
The most reasonable alternative is then to look for highly accurate real-time clocks (RTC). One RTC that fits the bill is the DS3231SN by Maxim, which contains a temperature controlled crystal (TCXO) on the chip. It is specified to have an accuracy of 2 ppm over temperatures between 0 °C and +40 °C, i.e., roughly 1 minute deviation per year., and an accuracy of 3.5 ppm over the temperature range from -40 °C to +85 °C, i.e., less than 2 minutes deviation per year. Pete exhaustively experimented with these chips and concluded that the RTC often works much better than the specification says. My own experience is similar. In the set of DS3231 breakout boards I own, I found a pair of Chronodot V2.0 clones (note the spelling mistake on the PCB in the picture) that were a perfect pair. It turned out that after a month, they only deviated by 10 ms per day from the true time, i.e., less than 4 seconds per year (at room temperature). There were also some bad apples, though, which were outside the specification.
Having the ability to know the accurate time, how do you translate that into assuring that two people at different places pressed buttons at (almost) the same time? Assuming that they can talk to each over a mobile phone, one could use a protocol similar to what many websites use these days to implement two-factor authentication (2FA), namely, time-based one-time passwords (TOTP). This is a code that is generated from a secret known only to the user’s app and the website and a timestamp using accurate clocks (based e.g. on NTP). The user generates such a TOTP and sends it to the website and the website can then compare it to the one it has generated, which should be identical.
Of course, it should be difficult for an attacker to guess such TOTPs, which is the point where cryptographic methods come into play. Usually, one uses SHA-1 as a function for turning plaintext into a numerical code. Since my mechanism is not connected to the internet, I chose a simple hash function that has the property of distributing its keys evenly over the hash value space, called Fibonacci hashing. This is not a cryptographically safe method. However, I do not expect any crypto attack. In any case, the number of times one can input a wrong key, which is necessary when you want to attack a cryptographic method, is very limited.
With that, the protocol of generating and verifying the TOTPs looks as follows. In order to simplify things, I only describe one communication direction:
- Both users, let us call them Alice and Bob, press synchronously a button generating a timestamp at their respective locations.
- On Alice’s machine, the timestamp together with the respective shared secret is used to generate a hash value, which is displayed to Alice.
- Alice transmits the code to Bob.
- Bob types the received code into his machine.
- Using the generated timestamp and the shared secret, Bob’s machine generates also a hash value and compares it with the received code.
- If the received code and the generated hash value are equal, then there is an extremely high probability that Alice and Bob pressed the button at the same time, and Bob’s box will open.
Of course, this protocol is also executed with the symmetric communication direction using a different shared secret.
One last issue is the question of what kind of time points we are talking about. Is it a second, a minute, or perhaps an hour? 2FA TOTPs are usually valid for half a minute and then, in order to account for events happening on a boundary between two half minutes, one usually allows for some leeway. I use seconds and allow for a few seconds difference, which means that instead of generating and comparing one hash value, a sequence of hash values is generated and compared to the received code.
Now we only need a box with a keypad, a display, and an electric lock to implement the idea. The best approximation I came up with is a safe box with digital keypad lock, as shown in the right picture.
The good thing is that the PCB is easily accessible, which opens up the possibility of modifying the functionality. Before replacing the PCB, one should, of course, try to understand first what the components are all meant to accomplish. So, I did a bit of reverse engineering.
The left-most connector is for the batteries (4 AA cells), the next one is for the electrical lock, the large connector is for the matrix keypad, and the rightmost connector is for the push button that one has to use, when a new key code should be entered. The only IC on the board does not have any markings, but I suspect it is one of the ultra cheap Chinese MCUs, namely, an EM78P153. At least the pinout is compatible with this MCU. First, I had hoped just to replace the MCU alone. However, the pinout is not compatible with any ATtiny I know of. Second, we need to interface additionally a display and an RTC, which won’t work with an MCU with that few pins (of which some already serve a double function).
Among the remaining components is a flyback diode (D2) for the electromagnetic lock and another diode (D1) that reduces the battery voltage from 6 V to 5.3 V, which is compatible with the MCU. Hopefully, nobody uses Lithium cells, which could give 6.8 Volts, in this safe box! Then there is a bi-bolor LED, directly driven by the MCU. Further, there is a PNP transistor (Q3) switching the lock, and one (Q4) switching the electromagnetic acoustic transducer. The two remaining PNP transistors Q1 and Q2 are configured as battery voltage monitors.
Before actually modifying the box, I built a breadboard prototype with a keypad, an electromagnetic acoustic transducer, an RTC, a bi-color LED, an 0.96 inch OLED display, a LED simulating the lock, and an ATmega328P.
When the new firmware seemed to work, I designed my own PCB and ordered a few, only to notice that I had forgotten to place the RTC on the board. In the second iteration, everything worked out, as shown in the next picture.
As usual, in the end, one needs to make at least one additional connection (the red wire). Here, the battery pin of the RTC is directly connected to the main supply voltage, because the battery contacts on the Chronodot are corroded.
Now we only need to add a display to the safe box. I like the small 0.96 inch OLED displays you can see in one of the above pictures. However, how to add them? Fortunately, I now own a 3D printer. And one can find STL files for enclosures for these OLED on the web. So, I printed two enclosures and glued them to the safe box. It looks as if the displays have there been from the beginning!
I added instructions, found a waterproof (Lock&Lock) box, provided some camouflage, and now have to hide it somewhere safe. My geocaching partner in Osnabrück already knows where to hide the box, but the box still has to arrive by mail. So, it is now only a few days until the geocache goes online, after I started the whole thing almost two years ago.