Reactive Lions

How to Benchmark Random Number Generation (RNG) in React Native

How to Benchmark Random Number Generation (RNG) in React Native

An analysis of crypto-save random number generation on iOS and Android via JavaScript layer in React Native.

How to benchmark random number generation (RNG) in React Native
How to benchmark random number generation (RNG) in React Native

Motivation

This article started as an effort to find a great UUID generation library. As a result, it led me to rewrite my existing react-native-uuid library in Typescript. However, I didn’t stop there. UUID generation is based on random number generation (RNG), which is an even bigger topic of Cryptography and specifically RNG.

If you don’t get your RNG right you risk having collisions between your UUIDs and your Encryption will be more vulnerable for statistical attacks.

TL;DR

RNBenchmark repo with all the code for RNG benchmarking.
react-native-benchmark library to run your benchmarks in React Native.

Subjective security ranking from -1 to +4 (more is better)
Subjective security ranking from -1 to +4 (more is better)

I’ve added subjective security ranking based on the implementation and performance of the libraries. For example, react-native-randombytes [SJCL] uses JavaScript only implementation and thus it is the least secure library to be used on mobile. react-native-get-random-values library has good performance and fallback. get-random-values-polypony was rated 0 because it works great only for random values of 36 bytes or less.

Disclaimer

This article describes the early results of benchmarking methodology, and it is not perfect. I’m sure there will be better ways to measure Javascript performance and native code performance. Any feedback is welcome, and I expect to update this article as more changes are released to the above libraries.

Outline

  1. Why RNGs matter
  2. Collisions and their implications
  3. What libraries are analyzed in this article
  4. Benchmarking tools
  5. Methodology
  6. Challenges
  7. Results
  8. Limitations
  9. Takeaways
  10. Next steps

Why RNGs matter

It is a very niche topic, and most developers use off-the-shelf libraries to solve random generation. However because React Native is a different ecosystem of components compared to the browser environment and Node.js environment, it is important to understand the difference. Standard Crypto library is not available in React Native by default, and that means it’s up to you to pick a library that generates a true random number and not a pseudo one using Math.random()inside JavaScript.

Collisions and their implications

There are two main reasons why weak random generation can cause you problems down the line and compromise the security of your encryption algorithms.

XKCD comics about RNGs
XKCD comics about RNGs
  1. Collision of universally unique identifiers.
  2. Increased vulnerability of your encryption protocols.
DILBERT © 2001 Scott Adams. All rights reserved.
DILBERT © 2001 Scott Adams. All rights reserved.

I love visual analysis, and it shows the difference between different random number generators available.

Visual comparison of two RNGs. courtesy of https://www.random.org/analysis/
Visual comparison of two RNGs. Courtesy of https://www.random.org/analysis/

So if you use a weak RNG or a pseudo-RNG you’ll most likely compromise your encryption algorithms and make it very cheap for an attacker to exploit this vulnerability. Ask your CISO.

What will be analyzed in this article

Here’re the top 7 libraries that are still maintained and being used by the community.

Image 1 – How to Benchmark Random Number Generation (RNG) in React Native

You can find the full list of libraries here. While researching this topic I published another library that uses random number generation using strictly native methods in iOS and Android here. See a step-by-step tutorial on how it was built below.

How to build a react-native plugin in 2021
A step-by-step guide to building TypeScript wrapping around native code written using Objective-C and Kotlin.medium.com

Benchmarking tools

There are tons of great libraries for benchmarking and performance analysis for Objective-C, C, C++, Java, Kotlin, several ones for JavaScript, but to the best of our knowledge — none for React Native.

First, I tried a 10 years old library benchmark.js that was great for other web projects, but failed on React Native, since it depends on Browser’s environment and still supports Safari 2.x and IE 🤯

I also found a nice wrapper around benchmark.js that reduces complexity a lot, but still doesn’t run on React Native.

I ended up building a drafty port that uses asynchronous callbacks and a similar API that benchmark.js uses. I used the same statistical analysis approach as they did. And used TypeScript to simplify the debugging.

react-native-benchmark
React Native benchmarking library inspired by benchmark.js and written in TypeScript. Warning: This library is work in…www.npmjs.com

It is not perfect and I welcome any feedback on how we can improve and stress test it!

Methodology

react-native-benchmark runs a Suite of benchmarks, where each benchmark executes each payload function at least 5 times and at least 1 second each.

After taking a more precise look at each of the tested libraries, I found that many of them have fallbacks to less compute-heavy generation and therefore I’ve broken down several of them.

  1. expo-random — this library should be tested inside Expo to have better results. But I was testing it inside the “ejected” state inside the clean React Native project. There’s a synchronous method getRandomBytes and asynchronous getRandomBytesAsync. In the source code, you can find that it calls first ExpoRandom.getRandomBytes if it’s available, otherwise, it calls ExpoRandom.getRandomBase64String. Here is its native counterpart in Objective-C. If you’re installing expo-random you might want to see these hacks first.
  2. react-native-randombytes is the 4th most popular library, and it also has two different methods of implementation. One is executed only in javascript using Stanford Javascript Crypto Library (SJCL). Another one — using native execution. SJCL uses Math.random to reseed their pools. And it also uses the entropy of different events, which is smart but can be compromised if devices are immovable.
  3. react-native-get-random-values is the most popular library that emulates Crypto.getRandomValues and falls back to ExpoRandom.getRandomBytes. Check its core logic here.
  4. react-native-securerandom is the 3rd most downloaded library, and it implements pseudo RNG fixes that bring us back to the post by Google engineers about Android’s security.
  5. get-random-values-polypony inherits most of the code from @consento/sync-randombytes. It creatively solved RNG, by seeding random pool using native UUID call, which provides a really nice performance on iOS and Android, compared to other native implementations when you need to generate a short (=36 bytes) sequence. However, if you want to generate something more than 36 characters (length of default UUID) you will probably want to get better entropy and run it a couple of times.
  6. react-native-simple-crypto library is a bigger effort to implement some cryptographic methods using native code.
  7. react-native-randomness is my version of the RNG library for React Native.

Here’s the main benchmarking logic:

Challenges

Here’s how React Native architecture looks like.

Courtesy of https://dev.to/goodpic/understanding-react-native-architecture-22hh
Courtesy of https://dev.to/goodpic/understanding-react-native-architecture-22hh

There’s one bridge that communicates between native code and javascript thread. Bridge communicates only via JSON, which means that we can’t send raw bytes back and forth. There’s also overhead in calling native code via Native Modules and in our case — converting bytes array to base64 and back.

Results

Performance of RNG libraries for React Native
Performance of RNG libraries for React Native

Limitations

I did not analyze Windows and Web platforms, a few of the libraries above support them.

I did not analyze the collision generation and its quality of each RNG library. This will probably become separate research at some point. Let me know in the comments.

Takeaways

There are 7 RNG libraries available for React Native today, each one is good enough for a specific use case. There’s no perfect library where one size fits all.

If you’re generating a small number of random bytes (under 36 bytes) you can use get-random-values-polypony.

If you don’t want to have native dependencies, your best call would be to use react-native-randombytes with SJCL enabled 👇.

If you need more than RNG use a better implementation of Crypto library using native code:

Be aware: Android RNG in Java and Kotlin has its own flaws:

Next steps

After analyzing the implementation of get-random-values-polypony it inspired me to add native UUID generation for my library react-native-uuid in the future release.

I would love to hear back from the community and define areas of improvement.

Java part of RNG implementation in my other library react-native-randomness definitely needs more attention.

Maybe all of those changes can be distilled to simple C++code so it can be reused on both Android and iOS platforms.

About the author

Eugene Hauptmann, CEO of Reactive Lions™
Eugene Hauptmann, CEO of Reactive Lions

Eugene is a faith-centric technologist, a serial entrepreneur, angel investor, advisor, and mentor.

He is the founder and CEO of REACTIVE LIONS INC. where he is implementing his vision of faith-driven entrepreneurship in the tech world. He is currently running a team of over 40 talented engineers across the US.

Eugene is the expert in building tech teams and he is a chief architect of scalable software products. His experience goes beyond B2B and B2C in multiple industries like Cyber Security, Deep Tech, FinTech, Media, AI, ML, Data platforms, Marketplaces, Wellness, Healthcare, Space, M&A, and more.

Contact us to learn how we can help your business build great tech.

More posts
How to Benchmark Random Number Generation (RNG) in React Native

2021-04-22

Quick Links
For Startups
Learn how to overcome tech challanges
Subscribe
REACTIVE LIONS INC. © 2021