Sensor Timing Jitter as a Noise Source on Android

I’ve been trying to implement a timing jitter-based RNG on Linux like PCQNG. The problem is Linux doesn’t provide access to multiple independent timers like Windows does.

On Windows, QueryPerformanceCounter uses HPET, which can be sampled by another timer like TSC. This allows us to measure the timing jitter between two independent clocks.

On Linux, all timing APIs point to one single timer set on /sys/devices/system/clocksource/clocksource0/current_clocksource. It is typically set to TSC. This means we can’t do the dual-clock jitter sampling trick.

However, I just realized that mobile device sensors like accelerometers and compasses have their own internal timer. This means on mobile devices, we can sample the timing jitter between the system timer and the sensor timer.


Data Analysis

This data is the timing jitter between Google Pixel 5’s system timer and its accelerometer’s timer, reportedly running at 415.97 Hz. Each sample is the time difference between two consecutive accelerometer readings, measured in nanoseconds.

sensor-timing-jitter-noise-415.97hz-20250808164632.csv (8.0 KB)

Time Series Plot & Histogram

Distribution is roughly bell-shaped, though does not fit a normal distribution.

Autocorrelation

A strong negative autocorrelation is observed at lag-1.

I think this is expected given the sampling method that uses the end time of the previous sample as the start time for the next sample. Skipping every second sample might be able to solve this issue.

FFT

FFT analysis shows a non-flat frequency spectrum.


I published my implementation here:

Would love to hear thoughts on how this can be improved or how we can properly use this entropy for RNG or other useful purposes.

Modified the sampling mechanism. Each sensor reading event is now either a start time or an end time, not both as it did previously.

The buffering mechanism is also improved. No more ring/circular buffer and thread locking.

sensor-timing-jitter-noise-207.987hz-20250808220542.csv (8.0 KB)

Time Series Plot & Histogram

Not much change here.

Autocorrelation

Significant reduction in lag-1 autocorrelation.

FFT

Much flatter frequency spectrum.

I’ve done some proof of concepts in this area, I’m wondering if browser timing jitter would work?

Nice improvement.

By the way, I have a PCQNG (the QWPCQNG) for Linux. I don’t easily have the source code since it was written 20 years ago, but it’s probably findable.

I think JavaScript’s timer-related APIs are all TSC underneath.

This code by Dan Kaminsky could work. Not exactly clock jitter. I’ve tested the randomness quality and it’s good. It’s a CPU and battery hog though due to the continuous while loop.

I found a LinuxPCQNG folder in the PCQNG source code, but the Linux part (line 51) is not yet implemented…

The PCQNG code should be in there, or I can post it with Scott’s approval. It seems that the PCQNG code is tuned to be very specific to the timing of a specific device or kind of device, and making it truly cross platform may be difficult for that reason? (maybe scott can confirm.) I did a bit of testing on what it would take to replicate the magic numbers in the PCQNG code, it might be a bit time consuming, but not impossible and could be very worthwhile developing for low-cost proliferation and mass adoption.

But I haven’t had much time to devote to it besides looking at the PCQNG code.

Oh here’s an idea. In browser, you may want to try measuring the webcam’s refresh rate jitter. Calculate how many microseconds it takes between frames using performance.now(). But I don’t like asking users for webcam access and have to explain, “don’t worry, we’re not using the video, we’re just measuring the time gap between frames” :sweat_smile:

Also, just use the camera feed as the noise source at that point lol

What about the speakers?

Speakers don’t provide data to the system in a way that allows it to timestamp the data’s arrival. Microphones can. But the timing jitter from mics is… I’ll let you be the judge…

Time Series Plot & Histogram

Autocorrelation

FFT

I mean… you can process it but the underlying entropy quality is just so bad…

The “magic“ numbers have to do with the bus rate of the PC. When I developed the PCQNG, everyone’s device (their PCs) would work. That’s definitely not true today. Primarily, the device has to be using a 5th generation or later Intel compatible CPU, which includes a phase-locked loop frequency multiplier to generate the CPU core frequency. It’s the relative jitter between the core clock and the bus clock that provides entropy.

That’s about what I concluded.

Are these plots generated using the raw audio output, i.e., at a reasonably high frequency (KHz)? I note the Mic Jitter FFT only shows up to about 11 Hz. Keep in mind, we don’t hear below about 30 Hz, so there is no reason to suppress low-frequency repetitive signals, which seem to be present.

It’s not the sound signal. It’s the timing between when each chunk of audio data is delivered. Each chunk takes around 46 ms to collect on average. I was trying to exploit that timing jitter

I think the noise in the sound channel may be of interest, plus it’s available at a much higher data rate. Is there a selection of the number of bits the sound channel takes?

I vaguely remember playing around with CPU jitter a few years ago when Scott first okayed releasing some of his code. All I could find was this reference to RDTSC in PrdCore… but my comment just says it’s not available on x64 :grin:

I think the noise in the sound channel may be of interest, plus it’s available at a much higher data rate

It can be an entropy source. But I think it’d be easy to attack

Is there a selection of the number of bits the sound channel takes?

Depends on the sound card. High-end sound cards can support higher bit depth


Talking about entropy from a sound card, I tried connecting a photodiode to the mic port (line in) of my sound card. When I shined a flashlight on the photodiode, it recorded white noise. If it’s the sound of the shot noise, this might be an easy way to create a QRNG

TSC is available on x64. It’s the way we call RDTSC that’s different. TSC-like timer is available in almost all CPUs. You can use this file as a reference for implementing in other architectures

As far as I know, RDTSC is available on x64 and on Linux. Later CPUs with multi-core processing present more of a challenge. From Wikipedia: Time Stamp Counter - Wikipedia

Yes, RDTSC is available on x64 and on Linux. The problem I encountered with Linux is that all timing APIs on Linux use RDTSC underneath. So we can’t do that dual-clock jitter measurement because we only have one clock

There is a way to change the clock used by the timing APIs but it needs root privilege and the change will be system-wide