[v0.9.0] New node ID format

v0.9 introduces a new format for node ID:s. It’s quite similar to the old one. The old format:

P56IOI-7MZJNU-2IQGDR-EYDM2M-GTMGL3-BXNPQ6-W5BTBB-Z4TJXZ-WICQ

And the new format:

P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2

The differences are:

  1. There are four more characters (56 vs the old 52). The extra bits of data are check characters. When a node ID is input or loaded from configuration, the check characters are verified to make sure the node ID has been correctly copied.

  2. The grouping is changed to groups of seven. This nicely divides the new node ID into eight equal groups.

The placement of the check digits are as follows:

aaaaaaa-aaaaaaA-bbbbbbb-bbbbbbB-ccccccc-ccccccC-ddddddd-ddddddD

aaaaaaa-aaaaaa are data, checked by the immediately following A character, and similarly for b, c, and d. That is, each two seven-character groups contain their own check digit.

The GUI will provide some useful feedback (i.e. green/red letter groups) when entering a node ID, based on the correctness of the check digits.

The console logs and configuration now all contain the new format node ID:s (with the configuration accepting the old format as well).

Trivial copying errors (O to 0, I to 1 and B to 8) are corrected silently and automatically.

3 Likes

Does the API also provide the correct (grouped) format? This isn’t the case yet.

Also, could you document the checking? (or at least link to the implementation).

Related ticked is:

https://github.com/calmh/syncthing/issues/269

The API speaks new format (but accepts the old format as input), in v0.9 (i.e. master, currently). The checking uses the Luhn mod N algorithm with N being 32 and the digits being the base32 alphabet. The Go implementation is here. There’ll either be one in Javascript for the GUI or an API call to do the check in question.

Hi Jakob, I was implementing the Luhn mod N algorithm in Swift, and found a discrepancy between the Swift port and the Go original. When I calculate the first check digit for P56IOI7MZJNU2, I get an “S” instead of a “Y”.

I went through the Go code, and if I read it correctly you iterate through the string left-to-right, alternating between a factor of 1 and 2. However, in the wikipedia article about the Luhn Mode N algorithm it is specified that you should iterate right-to-left, alternating between a factor of 2 and 1.

Can you verify whether my conclusion is correct? And if it is indeed an error in the Go code, will you change it, or shall I adopt the ‘wrong’ implementation in Swift?

1 Like

You’re right - my implementation is wrong. The annoying thing is that I took the test cases (abcdef => check digit e) from that page, and that specific string works in either case since it contains an even number of characters. But on node IDs it checks on groups of 13 characters, where the difference matters. Doh! :grimacing:

Correcting the calculator is trivial, but renders all current node IDs invalid so that would need to handled carefully. I think we’ll leave it as is for the moment…

All right, I have adapted the Swift code to the current Go implementation.

In the following commit you can find some test cases that I used to derive the Swift algorithm. Might be useful should you one day decide to change the Go implementation.