rpp0 / gr-lora

GNU Radio blocks for receiving LoRa modulated radio messages using SDR
GNU General Public License v3.0
537 stars 115 forks source link

Whitening polynomial #112

Closed jgromes closed 4 years ago

jgromes commented 4 years ago

Hi,

I'm trying to decode whitened FSK packets transmitted from SX127x, and I was wondering whether you could share the whitening polynomial? The one in the datasheet (x^9 + x^5 + 1) seems incorrect, and I only found pre-computed PRNG sequences in this repo (https://github.com/rpp0/gr-lora/blob/master/lib/tables.h).

Thanks!

rpp0 commented 4 years ago

I determined the pre-computed PRNG sequence by transmitting an all-zero payload with a real LoRa device, since I also don't know how to find the whitening polynomial. The one in the datasheet appears indeed not the same as what is used in practice.

jgromes commented 4 years ago

Dammit, I was hoping to get the polynomial the easy way here :)

I assume there's no way to derive the polynomial from the PRNG - other than brute force perhaps?

EDIT: BTW, you have different sequences for different coding rates. From that I assume FEC is applied before whitening, right?

jgromes commented 4 years ago

So it turns out SX127x and SX126x do actually use the x^9 + x^5 + 1 polynomial, as advertised. However, Semtech kinda forgot to mention they also reverse the bit order, once before whitening and once afterwards.

I can now decode whitened SX127x/6x FSK packets using URH - it might be worth some investiagtion to see if the same bit flipping takes place for LoRa packets, as I doubt they would implement separate LFSRs for FSK and for LoRa.

rpp0 commented 4 years ago

Interesting! Do you have a source for that information? Thanks for sharing; this is very useful.

jgromes commented 4 years ago

I don't have any source other than my own experiments, but if you have an SX127x/6x, some MCU to control it and an SDR, it's pretty easy to verify ;) I can also send you a couple of recordings for the Universal Radio Hacker program (don't have much experience with GNUradio - sorry). URH has built-in de-whitener for CC1101, which supposedly uses the same whitening polynomial as SX127x/6x. After reversing bit order, it will decode the FSK packet.

Here's a sample (preamble 0x5555, sync word 0x2d01, fixed packet length mode, no CRC):

sent:        0x55552d010123456789abcdefaa
demodulated: 0x55552d01fea4fd3e3e0a01cbfd
decoded:     0x55552d010123456789abcdefaa

Another sample, this time sending just 8 null bytes. Presumably, this is the output from the LSFR without any FEC and only with inverted bit order (since FEC is only done in LoRa and not in FSK).

sent:        0x55552d010000000000000000
demodulated: 0x55552d01ff87b859b7a1cc24
decoded:     0x55552d010000000000000000

BTW I can't take much credit for this, it was @andynoack who noticed that the whitening PRNG on SX127x has reversed bit order when compared to CC1101. This was originally discussed in https://github.com/jopohl/urh/issues/749.

rpp0 commented 4 years ago

This is great, thanks again! If you would like to implement the PRNG yourself in this project to get some more experience with GNU Radio I can assign this task to you if you want? It would be nice to finally remove the precomputed PRNG sequence from the code.

jgromes commented 4 years ago

Seems it should be fairly straight-forward, though I'll have to see how FEC affects things. Probably won't have the time for a while unfortunately :(

rpp0 commented 4 years ago

No problem :)!

On Wed, 25 Mar 2020, 18:27 Jan Gromeš, notifications@github.com wrote:

Seems it should be fairly straight-forward, though I'll have to see how FEC affects things. Probably won't have the time for a while unfortunately :(

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/rpp0/gr-lora/issues/112#issuecomment-603976725, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB7AOCHO3GJE4W36I5CJCCTRJI5HHANCNFSM4LRIN67A .

rpp0 commented 4 years ago

Hi again! I did some testing and it seems that indeed a different LFSR is used for FSK and LoRa. Actually I noticed that the implementation I made based on the datasheet a few years ago matches your result (ff87b859b7a1cc24...). The closest for LoRa I could find is the "interleaved" LFSR described in https://github.com/myriadrf/LoRa-SDR/blob/52ec64dddf03eefe17cbb36f34377ab097d0abda/LoRaCodes.hpp, but it's not entirely correct; some bits are wrong. I tried to ask the author of this repository how he reverse engineered the init values and polynomial, but he does not respond unfortunately. This LFSR has a 128-bit state, so it is not feasible to brute force.

rpp0 commented 4 years ago

Okay actually I'm just stupid. The starting values are trivial to reverse engineer. If I then use the LFSR from https://github.com/myriadrf/LoRa-SDR/blob/52ec64dddf03eefe17cbb36f34377ab097d0abda/LoRaCodes.hpp with my init values, I get the same output as my precomputed LFSR, so it finally works! The question is now still how the guys at MyriadRF found out that it's an interleaving LFSR though... :)

Edit: it seems they perform the "deshuffling" simultaneously with Hamming decoding, which explains the different starting values.