Showing posts with label silly. Show all posts
Showing posts with label silly. Show all posts

Pea whistle steganography

[Image: Acme Thunderer 60.5 whistle]

Would anyone notice if a referee's whistle transmitted a secret data burst?

I do really follow the game. But every time the pea whistle sounds to start the jam I can't help but think of the possibility of embedding data in the frequency fluctuation. I'm sure it's alternating between two distinct frequencies. Is it really that binary? How random is the fluctuation? Could it be synthesized to contain data, and could that be read back?

I found a staggeringly detailed Wikipedia article about the physics of whistles – but not a single word there about the effects of adding a pea inside, which is obviously the cause of the frequency modulation.

To investigate this I bought a metallic pea whistle, the Acme Thunderer 60.5, pictured here. Recording its sound wasn't straightforward as the laptop microphone couldn't record the sound without clipping. The sound is incredibly loud indeed – I borrowed a sound pressure meter and it showed a peak level of 106.3 dB(A) at a distance of 70 cm, which translates to 103 dB at the standard 1 m distance. (For some reason I suddenly didn't want to make another measurement to get the distance right.)

[Image: Display of a sound pressure meter showing 106.3 dB max.]

Later I found a microphone that was happy about the decibels and got this spectrogram of a 500-millisecond whistle.

[Image: Spectrogram showing a tone with frequency shifts.]

The whistle seems to contain a sliding beginning phase, a long steady phase with frequency shifts, and a short sliding end phase. The "tail" after the end slide is just a room reverb and I'm not going to need it just yet. A slight amplitude modulation can be seen in the oscillogram. There's also noise on somewhat narrow bands around the harmonics.

The FM content is most clearly visible in the second and third harmonics. And seems like it could very well fit FSK data!

Making it sound right

I'm no expert on synthesizers, so I decided to write everything from scratch (whistle-encode.pl). But I know the start phase of a sound, called the attack, is pretty important in identification. It's simple to write the rest of the fundamental tone as a simple FSK modulator; at every sample point, a data-dependent increment is added to a phase accumulator, and the signal is the cosine of the accumulator. I used a low-pass IIR filter before frequency modulation to make the transitions smoother and more "natural".

Adding the harmonics is just a matter of measuring their relative powers from the spectrogram, multiplying the fundamental phase angle by the index of the harmonic, and then multiplying the cosine of that phase angle by the relative power of that harmonic. SoX takes care of the WAV headers.

Getting the noise to sound right was trickier. I ended up generating white noise (a simple rand()), lowpass filtering it, and then mixing a copy of it around every harmonic frequency. I gave the noise harmonics a different set of relative powers than for the cosine harmonics. It still sounds a bit too much like digital quantization noise.

Embedding data

There's a limit to the amount of bits that can be sent before the result starts to sound unnatural; nobody has lungs that big. A data rate of 100 bps sounded similar to the Acme Thunderer, which is pretty much nevertheless. I preceded the burst with two bytes for bit and byte sync (0xAA 0xA7), and one byte for the packet size.

Here's "OHAI!":

Sounds legit to me! Here's a slightly longer one, encoding "Help me, I'm stuck inside a pea whistle":

Homework

  1. Write a receiver for the data. It should be as simple as receiving FSK. The frequency can be determined using atan2, a zero-crossing detector, or FFT, for instance. The synchronization bytes are meant to help decode such a short burst; the alternating 0s and 1s of 0xAA probably give us enough transitions to get a bit lock, and the 0xA7 serves as a recognizable pattern to lock the byte boundaries on.
  2. Build a physical whistle that does this! (Edit: example solution!)

Visualizing hex dumps with Unicode emoji

Memorizing SSH public key fingerprints can be difficult; they're just long random numbers displayed in base 16. There are some terminal-friendly solutions, like OpenSSH's randomart. But because I use a Unicode terminal, I like to map the individual bytes into characters in the Miscellaneous Symbols and Pictographs block.

This Perl script does just that:


@emoji = qw( 🌀  🌂  🌅  🌈  🌙  🌞  🌟  🌠  🌰  🌱  🌲  🌳  🌴  🌵  🌷  🌸
             🌹  🌺  🌻  🌼  🌽  🌾  🌿  🍀  🍁  🍂  🍃  🍄  🍅  🍆  🍇  🍈
             🍉  🍊  🍋  🍌  🍍  🍎  🍏  🍐  🍑  🍒  🍓  🍔  🍕  🍖  🍗  🍘
             🍜  🍝  🍞  🍟  🍠  🍡  🍢  🍣  🍤  🍥  🍦  🍧  🍨  🍩  🍪  🍫
             🍬  🍭  🍮  🍯  🍰  🍱  🍲  🍳  🍴  🍵  🍶  🍷  🍸  🍹  🍺  🍻
             🍼  🎀  🎁  🎂  🎃  🎄  🎅  🎈  🎉  🎊  🎋  🎌  🎍  🎎  🎏  🎒
             🎓  🎠  🎡  🎢  🎣  🎤  🎥  🎦  🎧  🎨  🎩  🎪  🎫  🎬  🎭  🎮
             🎯  🎰  🎱  🎲  🎳  🎴  🎵  🎷  🎸  🎹  🎺  🎻  🎽  🎾  🎿  🏀
             🏁  🏂  🏃  🏄  🏆  🏇  🏈  🏉  🏊  🐀  🐁  🐂  🐃  🐄  🐅  🐆
             🐇  🐈  🐉  🐊  🐋  🐌  🐍  🐎  🐏  🐐  🐑  🐒  🐓  🐔  🐕  🐖
             🐗  🐘  🐙  🐚  🐛  🐜  🐝  🐞  🐟  🐠  🐡  🐢  🐣  🐤  🐥  🐦
             🐧  🐨  🐩  🐪  🐫  🐬  🐭  🐮  🐯  🐰  🐱  🐲  🐳  🐴  🐵  🐶
             🐷  🐸  🐹  🐺  🐻  🐼  🐽  🐾  👀  👂  👃  👄  👅  👆  👇  👈
             👉  👊  👋  👌  👍  👎  👏  👐  👑  👒  👓  👔  👕  👖  👗  👘
             👙  👚  👛  👜  👝  👞  👟  👠  👡  👢  👣  👤  👥  👦  👧  👨
             👩  👪  👮  👯  👺  👻  👼  👽  👾  👿  💀  💁  💂  💃  💄  💅 );

while (<>) {
  if (/[a-f0-9:]+:[a-f0-9:]+/) {
    ($b, $m, $a) = ($`, $&, $');
    print $b.join("  ", map { $emoji[$_] } map hex, split /:/, $m)." ".$a;
  }
}

What's happening here? First we create a 256-element array containing a hand-picked collection of emoji. Naturally, they're all assigned an index from 0x00 to 0xff. Then we'll loop through standard input and look for lines containing colon-separated hex bytes. Each hex value is replaced with an emoji from the array.

Here's the output:

[Image: Terminal screenshot showing a PGP key fingerprint and the same with all hex numbers replaced with emoji.]

The script could easily be extended to support output from other hex-formatted sources as well, such as xxd:

[Image: Terminal screenshot showing a hex dump of a poem and the same with all hex numbers replaced with emoji. kissofoni; tassun kynsi neulana / musa korvista kajahtaa]

Some additional methods for visualizing hex dumps and key fingerprints, from the comments section:

Reader challenge explained

As I promised, here's a brief explanation of the reader challenge I posted earlier. (Deadlines in the summer? Baaad idea.) I will leave decoding as homework though.

Spoiler alert!

I. Almost trivial

This is a simple substitution cipher using my haxor handle (repeated characters removed) as the key:

WINDYTABCEFGHJKLMOPQRSUVXZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Reversal is almost trivial due to the distinct pattern it leaves in the letter frequency spectrum. "Almost", because there is an added challenge in the language used.

II. Shouldn't be very hard either

This message was transformed into audio with the Hellschreiber teleprinter. There's no further encryption. Some people noticed that there's a hint in the audio metadata; this was unintentional.

III. Might take some effort

A visual encryption scheme. A message is encoded in the difference of these two random dot patterns. I tried to add noise into the encoded message to make the resulting similarities in the patterns less obvious to the eye.

IV. NSA-grade

Okay, it's not really NSA-grade. But it's a Playfair cipher, using the following key:

$square =
  "WINDY".
  "ABCEF".
  "GHKLM".
  "OPQRS".
  "TUVXZ";

Whitespaces and punctuation was removed, and full stops were converted to "STOP".

I was surprised at how many people actually reversed this!

Reader challenge: Obfuscated messages

I'm under the impression that some people are actually reading this blog. So, for the amusement of my readers, here are some little puzzles to be solved.

Send your solutions to windyoona at gmail dot com and I'll post your name or handle under the puzzle(s) you solved!

The challenge is over now. For more problems like this, take a look at Oona's puzzle corner in PoC||GTFO 0x09.

. Almost trivial

"Wjd bwpq qbkr pgwcj qby Ewiiyouknf?
Nkhy qk hx wohp, hx iywhcpb ikx!
K towiekrp dwx! Nwggkkb! Nwggwx!"
By nbkoqgyd cj bcp ekx.

'Quwp iocggca, wjd qby pgcqbx qksyp
Dcd axoy wjd achigy cj qby uwiy;
Wgg hchpx uyoy qby ikokaksyp,
Wjd qby hkhy owqbp krqaowiy.

II. Shouldn't be very hard either

III. Might take some effort

[Image: A seemingly random pattern of black and white pixels, around a hundred thousand pixels in total, with a horizontal cut in the middle.]

IV. NSA-grade

UGYPY PCTLX ISRLF OCWZG LDAXN DMAPS LFHYR ZQFWD UGWBO ZPQUG YPYPS FRGYE PDXLD YGSYQ
DBXPQ PDPTW IGSGB PCTCD TWRFD LYCPS DFEOR ZOZPQ PGDAQ CTAGS YQDBX BSQPW SPZOB WNEWD
UGWBO GDHFZ WTUHV UBPEW WQNYF BLBAG OFESD BDYSA WSXPR ZRZWT SIFRN DELDL YRBWI RPWSP
ZOLXW PZPMD OZPQN HWQYG EWFLP WRFRD RLFNW VPBFO GWPQW UYPFI UGFEG BPDZW SAUGG WOTTR
YLSOZ RWTUB WKRLU GPSOU GBUWF GLBXL OZTWO ULBWC PYGRT RLCWE UGYHN DPVDP NDHMD ZDFZS
FMPDC DYRLB GBNLN DERDF ZUCDE LLEGP OQWUE GWUWZ POCXC DSASF AQVIX OISAR RHADG PEGFO
EOLXF ATHLD FRESS GUGXA DPWCU WXCGE DYOZP QDACF MHWBY QINRD GEGDF WOSFL FLCFP LLXIN
UGLOG WWUXI XBOZP QURPW SPWAF OCWLD XOGTX ENDEO DMRTQ GNDHM WUZUR LGFYQ WTUPA DFOGB
XEMDM GPSAX GBYCN UFALD AXASX PNDBK FRHIV AEODX DBILY HRFME INUGL OFBXW WHDNZ WZFWT
UPYPL BEWAG RFTEA VMDUG FRGBR BSACW ALTLC WILFB GDFWO QLXBK LEWUE GWUZU XMARW QDCPY
ELOZP QPBZS PTOZB ELBAG QZLXF ZUWEZ ABDYH YHDWG SDOZP QUGCD FBAZD CRZOP BMYPG WZUDP
ADFOE GGSOZ NDEQL EBHRL OZPQB HLRDB XCFOR BKQSA IXOZA WPTRE GBXCE BZPLE PBLZG SXLOB
NDUGC WBCXH DRAXA TVIYR WTSIA XZUPB ORTBN DXWEW DYFMD BERWU ZURLG FDIGP NIFOZ RPSDX
WZPOL DCDTA HDHSL ECBER IMEWC FDLDN IKYPZ OYHAR DCSAU GFLPO VALRF COEXA YLFLC FSOSA
UGFCL RHWCW QPHDE FOZPQ FOEWA XFFAV NUBLY PEMBW PLEWC FDLDC ZUOEP SYNWC SDCWI LBLEW
BEPBC XLEXO BIHSM PFIHI DQCTL RDRND MOSGA RAZLB GSOZC BEZEM NDKAF OFRSA UGLEF WOZPQ
LBQPN DXAWR TPUZW TLFUG LRWUZ URLGP ZPBDI KBCWU LEFIP BGFDY PBZML RDRTA CFMHW BYQCW
YNQSP OHYRF WXTOT GDYRF DLPBG FWGDC EOMDW EXAOZ PQUGC DLBOE YPLEP BPMGW INUGB AGEPT
PDPMW TFNWV PBETC WYILE SPXCG AFWOZ PQLBO FELEO HDUZX GFLCW OFNYF NWVPB OBOZP QNYWQ
NYFBW SVHDC IGYHO ZPQWS VXFCL DCDCD XAOXB WDNWK BELRF CPDZW VITBA GXLPY XLRHD BYRWT
OBDYA SOXLB XLOZS AUGAD FWGPL FDPFE WULEW TUGFL UGBLT CPDPT RFURG RWUOF DYXOB IHSMP
SALBQ EXHBR PWSPZ OWTOU

Update: Explanations are in another post, so this is kind of closed.

Scoreboard

IIIIIIIV
Alpak HD
Ben
Claude Vaillancourt
Denis Liliom
Hans Van Ingelgom
inquisitas
JasonD
Karim
Ken Arthur
Liwei
Miguel Lechón
Nicolas Vanderavero
Ole Andre Noss
Shaun Hey
Stefano
Steve Pordon
Tim James
Zac Watts

The laser-equipped Lego train

In a previous post I was not very happy with the results of my opto-acoustic capture of the miniature gramophone record, so today I thought I'd try to illuminate the record surface more evenly.

Of course, the straightforward solution is to build a circular LEGO® railroad track around the record and have a laser-hauled train run around the track, illuminating the record surface with coherent light at a constant tangential angle, while a camera captures the image at long exposure.

[Image: A LEGO train engine chassis on a curved LEGO track, with a little laser pointer attached to it using blu-tack and cable ties. The laser is emitting red light.]

This time I didn't want to go through the trouble of positioning the high-resolution camera and only got this:

[Image: A vinyl record illuminated very unevenly with laser beams projected radially, towards the center.]

I learned that Lego is not very good for laser work in general; specifically the trains don't run very smoothly, as you can see in the above pic. Updates with audio will follow, anyway. In the meantime, here's a video.

Bonus points if you can hear what's happening in the background.

Update: I didn't post an audio update, because the audio was useless. And the whole laser thing was a dead end anyway. Instead, I edited the high-res photo I took earlier, removing the extreme shadows using Gimp's Dodge/Burn tool. Then changed my Perl code a bit so that it actually stays on track; the record turned out to contain two interleaved tracks. The result is this:

Now I can put the robot back together and close this case.

Update 7/2017: The saga continues in Gramophone audio from photograph, revisited.

Case modding, the polish way

If you're still using CD-Rs like me, and you store them in cardless "slim" jewel cases, you've probably noticed that text written on the spine is pretty invisible:

[Image: CD jewel cases with text labels hand-written on the backs but mostly invisible because of the lack of contrast between the black ink and the black plastic showing through the transparent case.]

But fortunately there's always that bright-colored nail polish you never actually use.

[Image: The above jewel case backs being painted on the inside with a pink glitter nail polish called 'Maybelline New York Mini Colorama 03 Tutti Frutti'.]

Text appears! It's magic!

[Image: All the jewel cases painted, with the text clearly showing against the now pink glittery background.