From the blog

Future of Digital Voice

19 September 2020

As some of you may know, I am excited about Digital Voice taking off with the HAM radio community. Not so much about the actual communication aspects for me personally, but I love to experiment with the technology that makes it possible to have a globally routed Digital Voice network on the amateur radio bands.

One thing that has been bothering me a lot though, is the closed and proprietary technology used by popular Digital Voice (DV) protocols that are in use today. Protocols such as DMR, D-Star, P.25, TETRA, NXDN, System Fusion, etc. (to name a few) all make use of the proprietary voice codec (coder / encoder, the system that digitizes and compresses human speech).

So what?

Yeah you might think “So what? All the off the shelve equipment works out of the box.”. And you know what, you are right. But for people that like to tinker, home brew or just want to do more in-depth experimentation with Digital Voice, this is a serious impediment of running experiments. Sure you can get yourself an AMBE 3000 dongle, that is, if you have at least $299 to spare. Yep, that’s right, a WHOPPING $299 just to enable Digital Voice on your home brew radio project, all disppearing into the pocket of Digital Voice Systems Incorporated. I know what I would rather spend that money on!

Going further, I would even like to argue that because the access to the voice codec is proprietary, and because no specifications are made public by the manufacturer, the Digital Voice frames encoded by this codec are actually encrypted, or at least obfuscated beyond reasonable recognition by listeners not able or willing to pay for a proprietary device. This has nothing to do with amateur radio experimentation, you buy a device, plug it in and operate it. Jay.

Apart from all the financial and legal issues, the AMBE+2 suite of voice codec aren’t all that great anyway, compared to free and open source alternatives like Codec2, Opus or Speex. Especially on bandwidth restricted bands, or operating in less than ideal conditions, getting the most out of the few bits you can transmit is paramount.

Then what?

Exciting times are ahead!

David Rowe et. al. have been running experiments with Digital Voice on the HF bands using the open source Codec2 Digital Voice codec called FreeDV. FreeDV is a unique player in the Digital Voice arena, because it is 100% free and open source software, including the speech codec. The FreeDV 700D mode can outperform SSB at low signal to noise ratios and the FreeDV 2020 specification can provide 8 kHz of audio bandwidth in just 1600 Hz of RF bandwidth (in comparision: D-Star and DMR require 6250 Hz of RF bandwidth to deliver the same audio bandwidth with less quality).

For the less initiated, a prebuilt SM1000 FreeDV adapter hardware dongle that you put in line with the microphone and phones output is available and for the tinkerers among us there are many home brew options from using micro controllers up to pure software implementations.

You may be also excited to learn that the Es’hail-2 QO-100 satellite can operate in FreeDV 1600 and 2000 Digital Voice mode.

But what about VHF/UHF, I hear you asking?

Take a look at what the M17 Project are currently building. Their mission statement leaves no room for wrong interpretations:

The goal here should be to kick the proprietary protocols off the airwaves, replace DMR, Fusion, D-Star, etc. To do that, it’s not just good enough to be open, it has to be legitimately competitive.

The work group is currently finalizing the initial protocol drafts and designing the first hardware specifications. For Digital Voice codec they also make use of the excellent Codec2 from David Rowe.

If you like to get involved with the project, there is an active community over on IRC to discuss the project goals. The project is currently looking for people that can contribute in various ways, take a look at the M17 Project website for more information.

Closing thoughts

You might argue that the signaling and routing of previously mentioned commercial Digital Voice projects are probably superior to any open standard that may exist today and you are probably right to a large extent. A lot of these systems are in use for emergency services operators, professional user of short range radio, security companies, etc. etc. But please do not forget we are radio amateurs and experimentation and tinkering is actually an essential part of our hobby! Telecom agencies in various parts of the world are already considering removing our primary status on popular bands, due to high bandwidth demands from commercial parties. So join in on the tinkering fun and actually start making use of the generous bands we have been allocated for amateur use!

Anti-Forensic Information Splitter

30 January 2019

AFIS, or Anti-Forensic Information Splitter is an algorithm designed to support secure data destruction crucial for secure on-disk key management. The key idea is to bloat information and therefor improving the chance of destroying a single bit of it. The information is bloated in such a way, that a single missing bit causes the original information become unrecoverable. The default diffusion element is based on SHA-1, but different hashing algorithms may be selected by the user.

An implementation in Go is available in


The problem: removing data from hard drives comes with little guarantees

Even if you take all known precautions to delete a file from disk, chances are that (bits of the) data still remains on the disk. If the probability $p$ to destroy a certain block of data is $0 < p < 1$, then the chance of a block survives is $1-p$. Given a dataset of size $l$, the probability to destroy the whole block becomes $p^l$. But the probability the entire block survives, $(1-p)^l$, becomes smaller with increasing values of $l$. If $(1-p)^l$ is becoming smaller, then $1-(1-p)^l$ must become larger, which reflects the chance that the block will not survive.

The solution: moar blocks!

AFIS addresses the probability of a block to not survive by creating an interdependency for a data set $S$, $S=s_1, s_2,\dotsb s_n$, by generating $s_1 \dotsb s_n−1$ random data items and computing $s_n$ so that $s_1 \bigoplus s_2 \bigoplus s_3\dotsb\bigoplus s_n = D$. The reconstruction is done by carring out the left-side of the equation, XOR-ing all data items together. If one item $s_i$ is missing, $D$ can’t be reconstructed, since an arbitrary $s_i$ effects the entire $D$.

This scheme can be enhanced to include diffusion of information, so that the k-th bit of an arbitrary $s_i$ does not only affect the k-th bit of $D$ but the entire $D$. To achieve this diffusion, we insert a diffusion element in the chain of XORs. A crytographic hash function can be used as such element, but since it might not output sufficiently large data, it will be processed a few times with an increasing number, similar to an initial vector, prepended to the complete dataset to produce enough data. As a hash function is usually required to be non-invertible, we can not choose it’s output. Therefor, the last diffusion will be omitted. This will degrade security slightly, so when computing destruction probabilities the last element shall never be taken into account.

Anti-Forensic Information Splitter

As we can destroy a single undeterminated data item quite easily as shown in the previous paragraph, and as a single missing data item makes the base information unrecoverable, data items can be made reliable erasable. As illustration, you can find the overall composition above. $H$ denotes the diffusion element, which is likely to be a hash and $Z$ denotes the zero vector. In the splitting phase, $s_1$ to $s_n−1$ are random generated and the intermediate result $I$ is computed. Then $s_n$ computed as $s_n = D \bigoplus I$. When recovering the base information, the whole chain is computed as shown resulting in $D$, the original data item.

You may read the full theory and specification in the TKS1 draft.


28 January 2019

Cryptography is hard, and rolling your own crypto is usually a bad idea. The project stars with the following claim:

This library is not a substitution for well seasoned TLS implementations and only exists as a supplementary means of offering cryptographic primitives. Make sure you understand the limitations of each function before you use them.

Having said that, the project exists because sometimes just doing TLS doesn’t fit the bill. What if we want to store an encrypted database row? Or what if the transport isn’t HTTP, but something else built on top of a streaming protocol? You’re most likely on your own.


In the confidentiality project we’re aiming to gather today’s best practices for doing message authentication, message encryption and doing key exchange over an untrusted channel.

You can follow the project development on my GitHub. At the moment there is no stable release yet.

Go opensmtpd v52

16 October 2018

opensmtpd has been updated to reflect the changes in OpenSMTPD API version 52. The API is still not stable, and the filter API has been discontinued.


The only working plugin type are tables at the time of writing, on OpenSMTPD version 6.0.3p1.

Project sources at

`go get` on your domain

22 September 2016

I’m currently migrating my Github projects to the excellent self-hosted Gogs Gitea service at

Playing with the excellent service, I figured it would be awesome to use as the primary name space for the packages I’m building. As a start I setup a go organiation,


At first I played with go-import-redirector which serves as a simple metadata provider for the go get command. Its usage is fairly straight forward:

go-import-redirector [-addr address] [-vcs vcs] [-parts parts] <import> <repo>

So, in order to serve up my go organisation’s repository on the landing page of the domain, I can simply run:

go-import-redirector -addr /

To make this work in conjunction with the other content hosted on my site, we use the following piece of nginx configuration:

upstream go-import-redirector {

server {

  # ... other definitions ...

  location / {
    proxy_set_header Host $host;
    if ($args ~ "go-get") {
      proxy_pass http://go-import-redirector;

    # ... default location configuration ...

Let’s test go get:

% go get -v
Parsing meta tags from (status code 200)
get "": found meta tag main.metaImport{Prefix:"", VCS:"git", RepoRoot:""} at (download)

It worked! And as a bonus, the supervisord program definition:

command         = go-import-redirector -addr /
directory       = /tmp
priority        = 100
startretries    = 99999999
stdout_logfile  = /var/log/go-import-redirector.log
redirect_stderr = true

nota bene: The Go namespace is actually located at….