QubiCast Logo
QubiCast Logo

DevBlog: Testing DMX Encryption Feasibility on an Embedded System

19.03.2025, 18:15

hero

Learn how DMX frame encryption was tested on the rp2350 embedded system using libHydrogen. Discover the experiment's setup, performance insights, and why securing lighting protocols like Art-Net and sACN is crucial for modern applications.

During this year's PlugFest in Lille, the question arose on how to secure lighting protocols like Art-Net, or sACN. In order to answer that, in this post we take a quick peek at how costly state of the art encryption on an embedded system actually is.

We dive into an experiment designed to test the feasibility of encrypting DMX frames on a resource-constrained embedded system – in this case, the rp2350. We leveraged libHydrogen for encryption and ran tests to benchmark both encryption and decryption times.

The device used for testing is the QubiCast Art-Net / sACN Node prototype running QubiCore, based on a rp2350 running at 200MHz.


Experiment Overview

The core goal of this experiment was to verify that DMX frame encryption could be effectively implemented on the rp2350. Securing DMX frames is critical when working in environments where integrity and confidentiality are a concern. Using libHydrogen’s secret box API, we set up a basic test scenario:

  • Initialization: The library is initialized, ensuring the cryptographic primitives are ready.
  • Plaintext Data: We prepare a buffer with a simple pattern (0, 1, 2, …) to simulate DMX data.
  • Key Generation: A symmetric key is generated for encryption and decryption.
  • Encryption & Decryption Loops: Over 1000 iterations, the code encrypts the plaintext and then decrypts it, while measuring the time taken for each operation.
  • Validation: Finally, the decrypted output is compared against the original plaintext to confirm successful round-trip encryption.

Code Walkthrough

Let’s break down the code snippet:

1. Library Initialization

if (hydro_init() != 0) {
   printf("Failed to initialize libhydrogen.\n");
   return -1;
}
 
hydro_init() requires a hydro_random_init() function, which didn't exist for our architecture (rp2040 / rp2350), but this was quickly alleviated by providing that function - utilizing the pico sdk's pico-rand library.

2. Preparing the Data

static constexpr uint16_t PLAINTEXT_SIZE = 513;
static constexpr std::size_t ITERATIONS = 1000;
static const std::string context = "QUBICORE";
std::array<uint8_t, PLAINTEXT_SIZE> plaintext{};
for (std::size_t i = 0; i < PLAINTEXT_SIZE; ++i) {
   plaintext[i] = static_cast<uint8_t>(i);
}
  • Plaintext Buffer: A buffer of 513 bytes is populated with incremental values.
  • Iteration Count: Running the encryption/decryption process 1000 times provides a reliable measure of average performance.

3. Key Generation and Buffer Setup

std::array<uint8_t, hydro_secretbox_KEYBYTES> key{};
std::array<uint8_t, PLAINTEXT_SIZE + hydro_secretbox_HEADERBYTES> ciphertext{};
hydro_secretbox_keygen(key.data());
  • Key: A secure, randomly generated key is created using hydro_secretbox_keygen().
  • Ciphertext Buffer: The buffer is sized to accommodate both the plaintext and the encryption overhead (header bytes).

4. Timing the Encryption and Decryption Process

const uint64_t tStartEncrypt = get_absolute_time();
for(int i = 0; i < ITERATIONS; i++)
   hydro_secretbox_encrypt(ciphertext.data(), plaintext.data(), sizeof(plaintext), 0, context.c_str(), key.data());
const uint64_t tEndEncrypt = get_absolute_time();
const uint64_t diffEncrypt = (tEndEncrypt - tStartEncrypt);
const uint64_t meanEncrypt = diffEncrypt / ITERATIONS;
  • Timing: The encryption loop measures the total time to perform 1000 encryptions. Dividing this by the number of iterations provides an average encryption time.
  • Overhead Consideration: The encryption function includes nonce management (here hardcoded as 0 for simplicity) and authentication overhead.

The same was done for the decryption, using 

hydro_secretbox_decrypt(decrypted.data(), ciphertext.data(), sizeof(ciphertext), 0, context.c_str(), key.data());

instead of the encryption method shown above.

6. Verification and Results

if (std::equal(plaintext.begin(), plaintext.end(), decrypted.begin())) {
   printf("Decryption successful: plaintext matches.\n");
} else {
   printf("Decryption error: plaintext does not match.\n");
}
printf("Results: Encryption mean: %u; Decryption mean: %u ", meanEncrypt, meanDecrypt);
  • Validation: The decrypted output is compared against the original plaintext. A match confirms that the encryption/decryption cycle is correctly implemented.
  • Performance Output: The final print statement outputs the average times. In our tests on the rp2350, the mean encryption and decryption times were 1349 and 652 microseconds, respectively. These exact values could be obtained repeatedly over multiple experiment executions.

Performance Insights & Feasibility

The performance numbers from our experiment suggest that DMX frame encryption using libHydrogen is viable on embedded systems like the rp2350:

  • Encryption Overhead: With an average encryption time of around 1349 microseconds, the encryption process is slightly more computationally expensive than decryption, which clocks in at around 652 microseconds.
  • Real-Time Capability: Given that the original DMX protocol typically runs at relatively low data rates compared to modern digital communications, the overhead introduced by encryption is acceptable for real-time applications in stage lighting or other DMX-controlled environments. However, even in higher throughput scenarios, encryption within 1.4ms and decryption in about half that, might be acceptable
  • Resource Constraints: Embedded systems often have limited processing power. Our experiment demonstrates that with a lightweight library like libHydrogen, we can still achieve secure encryption without sacrificing real-time performance.

Conclusion

This experiment opens up opportunities for securing lighting control systems and similar DMX applications in environments where both performance and security are paramount. Especially ArtAddress / ArtRdm / ArtDmx and sACN might profit from an added layer of encryption to ensure confidentiality and make sure the data isn't tampered with.


Happy coding and secure lighting!

Philipp

Stay updated with the latest in lighting technology!

Subscribe to our newsletter for exclusive insights and offers. Illuminate your expertise!

There's more

Explore other posts