In December 2020, I had to work on my final project for my Internet-of-Things course. It’s not really anything special, but it’s pretty cool and if someone needed a proof-of-concept that it could work, this could serve as a page that it does. I’m going to copypasta my entire hastily-written project report cause I don’t like repeat typing things. Without further ado, de-Ranugen.

de-Ranugen [Distributed Entropy Random Number Generator]

Abstract

Random numbers have been of significant interest for a long time especially because they are a core component in computer security applications, TCP/IP sequence numbers, TLS nonces and password salts. Numerous public-key cryptography algorithms such as the Diffie-Hellman Key Exchange, ElGamal, and RSA Encryption require the use of Random Number Generators to generate Public and Private Keys. Computers typically generate Pseudo-Random Numbers and generating numerous random numbers consecutively typically leads to patterns being discovered by attackers if the source of entropy is not very random. Hence it is of the utmost importance to have a very random source of entropy that the underlying random number generator uses. de-Ranugen is an Internet of Things based application that attempts to source entropy from the sensors of a significant amount of mobile devices. This entropy is sent to the cloud which performs various mathematical operations in order to generate random numbers.

Background-Work

Toward Sensor-Based Random Number Generation For Mobile and IoT Devices by Wallace et al. [1] does very similar work as this project. However, the paper attempts to create random numbers for those applications only and does not use a cloud to aggregate the results, which this project attempts to do. Since this is an Internet of Things project, it is imperative to demonstrate a form of independent devices (nodes) being used on a scale that is bigger than those devices and that is what this project attempts to do.

The Idea

As of May 2019, there are over 2.5 billion Android Devices around the world [2]. If just 1% of that number of devices could be harnessed, 25 Million Devices could be used. Many of these devices have numerous built in sensors like an accelerometer, barometer, gyroscope, light sensor, location sensor (GPS), magnetic field sensor and a thermometer. As the owners of these devices move, the values change drastically and if these values could be used in cohesion with other devices’ values, a source of entropy is created. The goal of this Internet of Things project is to first develop an Android app that publishes values, referred to entropy strings, periodically to a server and secondly develop a server which combines values of different devices in order to generate a 256 character long random string.

The Architecture

Fig 1. The Architecture of de-Ranugen

Figure 1 illustrates the architecture of de-Ranugen. On the left side, there are multiple Android Devices of which one generic Android Device is shown in a zoomed in form. A generic Android Device has numerous sensors like a gyroscope, magnetic field sensor and a thermometer. Although only 3 sensors are illustrated, de-Ranugen will use more sensors in the practical implementation. Each device sends its entropy string to a server which runs necessary functions to generate random numbers on demand to generic laptop computers that require it.

Tools Used:

The tools used in this proof-of-concept are:

  1. MIT app inventor 2 to develop an android application that polls the values of sensors and publishes the entropy string to the cloud [3] (I did not want to work with Android Studio (again) cause that’s a nightmare to work with for something this simple),
  2. Flask to develop two APIs for the servers on the cloud, one for the submission of entropy values and the other for getting a random number on demand [4], and
  3. The GNU Compilation Collection to develop a rapid binary that takes in entropy and returns a random number [5].

Implementation:

The ideal project goal assumes that over hundreds of devices are in the ecosystem and a significant number of devices are moving, i.e. the gyroscope and/or accelerometer detects movement. However, for this proof-of-concept, this project demonstrates that using 2 Android Devices is enough to generate a set of random numbers. This section goes into the details of the sensors used, the architecture of the APIs developed and a general example of a process running.

Sensors Used

An example entropy string sent from an Android Device (One Plus 5) is:

“&gX%-0.18884&gY%0.18272&gZ%0.01049&lux%56&mX%37.92114&mY%-7.20062&mZ%14.48669&temp%0&aX%-0.24719&aY%0.38918&aZ%9.84369”

The delimiter & is used to signal a new sensor reading and the delimiter % is used to signal the beginning of the reading.

API Architecture

There are two HTTP REST APIs that are running at the same time on the server, one on port 3033 and another one on port 4044. The API running on port 3033 is the API that Android Devices submit their entropy string to while the API running on port 4044 is the API that consumers query to get a random number.

API on Port 3033:

    POST to /submitentropy:

         (string) conforming to [&sensor%value]+

API on Port 4044:

    GET to /randomnumber:

        (string) 256 character long hexadecimal string.

General Example

Let there be 2 Android Devices A & B with all the sensors. Let there be one consumer C that requires a random number.

A (POST) submits an entropy string “Entropy A”
B (POST) submits an entropy string “Entropy B”

C (GET) requests for a random number

Server takes Entropy A and Entropy B and performs mathematical operations (mentioned below) to generate a random number R

Server (Return GET) returns R to C

Mathematical Operations

Since this is only a proof-of-concept, the mathematical operations used are trivial. In a practical implementation, the operations would have to be rigourously tested and proven to demonstrate that they could be used.

Once the server parses the entropy strings to get the raw values, 11 values emerge. From a set of 2 mathematical functions with 220 combinations, the server randomly chooses a set of 32 combinations to be the seed for the random function. The mathematical functions are defined as:

Let Xn be the nth value in the entropy string

We define F1(Xn, Xm) as follows
F1(Xn, Xm) = eXn * eXm

We define F2(Xn, Xm) as follows
F2(Xn, Xm) = XnXm

The equation pertaining to F1 produces 11 x 10 numbers, which is 110 combinations. The equation pertaining to F2 produces 11 P 2 numbers, which is also 110 combinations. This gives 220 combinations of values out of which 32 are randomly chosen to be as the seeds for the random functions. However, to increase the entropy, 1 entropy string from 2 different devices are used to generate the random number where Xn belongs to a value from entropy string 1 and Xm belongs to a value from entropy string 2. This gives 11 x 11 values for both F1 and F2 and thus, 242 combinations are generated for 32 to be chosen as the seeds for the random functions.

Evaluation

Two entropy strings were sent to the server from 2 devices:

“&gX%40.82726&gY%-17.94427&gZ%8.43315&lux%223&mX%20.93353&mY%-4.15649&mZ%-17.61627&temp%0&aX%-2.9706&aY%9.07414&aZ%2.03738”

“&gX%0.11628&gY%0.30512&gZ%0.01049&lux%150&mX%44.58008&mY%-29.22821&mZ%12.50458&temp%0&aX%-0.21606&aY%0.43706&aZ%9.87959”

These strings were parsed and these values were generated:

[40.82726, -17.94427, 8.43315, 223.0, 20.93353, -4.15649, -17.61627, 0.0, -2.9706, 9.07414, 2.03738]

[0.11628, 0.30512, 0.01049, 150.0, 44.58008, -29.22821, 12.50458, 0.0, -0.21606, 0.43706, 9.87959]

The numbers were subject to F1 and F2 as defined above except when either of the values was 0. From this set of values, Python3’s SystemRandom API (to test the Proof-of-Concept) was used to choose 32 unique numbers which would form the seeds. A C binary executable that used these values as seeds were called to generate 1 random number per seed from [0 to 999] to get 256 random numbers in total.

To evaluate random numbers, many tests such as the Chi-Squared Test [6] exist. However, for simplicity, a scatter plot that plots:

X = RandomNumbers[0 : len(RandomNumbers-1)]
Y = RandomNumbers[1 : len(RandomNumbers)]

is a good way to visually inspect the plot for “fullness” to determine whether the Random Number Generator is good or not.

This experiment was repeated a thousand times with varying delays of the order of 10 microseconds in order to simulate real world API calls and the superimposed graph is shown in Figure 2.

Fig 2. A Scatter Plot of X(0:998) and Y(1:999)

Conclusion

As is observed in the plot, this seems to “fill” up the graph pretty well and this can be considered a good-ish source of random numbers. This project demonstrates an Internet of Things ecosystem that was able to send its sensor values to the cloud in order to generate sufficiently random random-numbers. Future work can be directed towards testing these set of numbers using the Chi-Squared test. It can also go towards trying to develop a service for agents that actually require random numbers and paying micro fees to the users who supply entropy.

Citations