diff --git a/recipes/pkg/nit_entropy/README b/recipes/pkg/nit_entropy/README
new file mode 100644
index 0000000..0f5ce95
--- /dev/null
+++ b/recipes/pkg/nit_entropy/README
@@ -0,0 +1,4 @@
+
+ Jitter Sponge
+
+A terminal server that provides an entropy service.
diff --git a/recipes/pkg/nit_entropy/archives b/recipes/pkg/nit_entropy/archives
new file mode 100644
index 0000000..d5de3ad
--- /dev/null
+++ b/recipes/pkg/nit_entropy/archives
@@ -0,0 +1 @@
+_/src/nit_entropy
diff --git a/recipes/pkg/nit_entropy/hash b/recipes/pkg/nit_entropy/hash
new file mode 100644
index 0000000..39cdd0d
--- /dev/null
+++ b/recipes/pkg/nit_entropy/hash
@@ -0,0 +1 @@
+-
diff --git a/recipes/pkg/nit_entropy/runtime b/recipes/pkg/nit_entropy/runtime
new file mode 100644
index 0000000..09bb05a
--- /dev/null
+++ b/recipes/pkg/nit_entropy/runtime
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/recipes/src/nit_entropy/content.mk b/recipes/src/nit_entropy/content.mk
new file mode 100644
index 0000000..7687079
--- /dev/null
+++ b/recipes/src/nit_entropy/content.mk
@@ -0,0 +1,2 @@
+SRC_DIR = src/app/nit_entropy
+include $(GENODE_DIR)/repos/base/recipes/src/content.inc
diff --git a/recipes/src/nit_entropy/hash b/recipes/src/nit_entropy/hash
new file mode 100644
index 0000000..39cdd0d
--- /dev/null
+++ b/recipes/src/nit_entropy/hash
@@ -0,0 +1 @@
+-
diff --git a/recipes/src/nit_entropy/used_apis b/recipes/src/nit_entropy/used_apis
new file mode 100644
index 0000000..a63494a
--- /dev/null
+++ b/recipes/src/nit_entropy/used_apis
@@ -0,0 +1,6 @@
+base
+os
+framebuffer_session
+input_session
+nitpicker_session
+terminal_session
diff --git a/run/nit_entropy.run b/run/nit_entropy.run
new file mode 100644
index 0000000..fafb855
--- /dev/null
+++ b/run/nit_entropy.run
@@ -0,0 +1,99 @@
+create_boot_directory
+
+import_from_depot genodelabs/src/[base_src] \
+ genodelabs/pkg/[drivers_interactive_pkg] \
+ genodelabs/src/nitpicker \
+ genodelabs/src/init
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+build {
+ app/nit_entropy
+ server/jitter_sponge
+}
+
+install_config $config
+
+build_boot_image {
+ jitter_sponge
+ nit_entropy
+ libkeccak.lib.so
+}
+
+run_genode_until forever
diff --git a/src/app/nit_entropy/main.cc b/src/app/nit_entropy/main.cc
new file mode 100644
index 0000000..d16c1fb
--- /dev/null
+++ b/src/app/nit_entropy/main.cc
@@ -0,0 +1,97 @@
+/*
+ * \brief Entropy visualizer
+ * \author Emery Hemingway
+ * \date 2018-11-09
+ */
+
+/*
+ * Copyright (C) 2018 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+/* Genode includes */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+namespace Nit_entropy {
+ using namespace Genode;
+ typedef Surface_base::Point Point;
+ typedef Surface_base::Area Area;
+ typedef Surface_base::Rect Rect;
+
+ struct Main;
+};
+
+
+struct Nit_entropy::Main
+{
+ enum { WIDTH = 256, HEIGHT = 256 };
+
+ Genode::Env &_env;
+
+ Heap _heap { _env.ram(), _env.rm() };
+
+ Nitpicker::Connection _nitpicker { _env };
+
+ Framebuffer::Session &_fb = *_nitpicker.framebuffer();
+
+ Terminal::Connection _entropy { _env, "entropy" };
+
+ Dataspace_capability _fb_ds_cap()
+ {
+ using Framebuffer::Mode;
+ Mode mode(WIDTH, HEIGHT, Mode::RGB565);
+ _nitpicker.buffer(mode, false);
+ return _fb.dataspace();
+ }
+
+ Attached_dataspace _fb_ds { _env.rm(), _fb_ds_cap() };
+
+ Nitpicker::Session::View_handle _view = _nitpicker.create_view();
+
+ void _refresh() { _fb.refresh(0, 0, WIDTH, HEIGHT); }
+
+ void _plot()
+ {
+ uint16_t *pixels = _fb_ds.local_addr();
+ static uint8_t buf[HEIGHT];
+ size_t n = _entropy.read(buf, sizeof(buf));
+ if (n != sizeof(buf)) {
+ Genode::error("read ", n, " bytes of entropy");
+ }
+
+ for (int i = 0; i < HEIGHT; ++i) {
+ uint16_t *row = &pixels[i*WIDTH];
+ row[buf[i]] = ~row[buf[i]];
+ }
+
+ _refresh();
+ }
+
+ Signal_handler _sync_handler {
+ _env.ep(), *this, &Main::_plot };
+
+ Main(Env &env) : _env(env)
+ {
+ _nitpicker.enqueue(
+ _view, Rect(Point(0, 0), Area (WIDTH, HEIGHT)));
+
+ _nitpicker.enqueue(
+ _view, Nitpicker::Session::View_handle());
+ _nitpicker.execute();
+
+ _fb.sync_sigh(_sync_handler);
+ }
+};
+
+
+void Component::construct(Genode::Env &env) {
+ static Nit_entropy::Main inst(env); }
diff --git a/src/app/nit_entropy/target.mk b/src/app/nit_entropy/target.mk
new file mode 100644
index 0000000..bf2c322
--- /dev/null
+++ b/src/app/nit_entropy/target.mk
@@ -0,0 +1,3 @@
+TARGET = nit_entropy
+SRC_CC = main.cc
+LIBS = base