Skip to content

NTRU Key Exchange for IOTA

David Hawig edited this page Jul 5, 2018 · 9 revisions

Why NTRU?

If you want to use the MAM Layer of IOTA you first need to exchange the channel keys in a quantum secure way. The most secure, but not very user-friendly way to do this is to exchange the keys in person. Another way is to use one of the available post-quantum key exchanges. Since RLWE has some problems if you keep reusing the same keys (https://eprint.iacr.org/2016/085.pdf), I decided to use NTRU for this, since it’s now also patent free (except U.S. patent 7,308,097 for signing messages).

How to use the NTRU Key Exchange in C#?

Since there is currently no NTRU NuGet package available, you first need to download CEX-NET by Steppenwolfe65. You can now add this code as an existing project to your code (Visual Studio: right click on you your solution Add => Existing Project).
Once you have added the project to your solution, you can add the following class to your solution:

https://github.com/Noc2/Chiota/blob/master/Chiota/Chiota/Services/NTRUKex.cs

Now you should be able to use the following code to encrypt and decrypt your MAM channel keys or something else:

var ntru = new NtruKex(keyExchangeParameters: true);
var testBytes = Encoding.UTF8.GetBytes("This could be a MAM channel key.");
var keyPair = ntru.CreateAsymmetricKeyPair(
        "For example a string based on a seed",
        "For example a string based on an address");
var encrypted = ntru.Encrypt(keyPair.PublicKey, testBytes);
var trytes = encrypted.ToTrytes();

// send trytes to other user
var backToBytes = trytes.ToBytes();
var decryptedBytes = ntru.Decrypt(keyPair, backToBytes);
var stringDecrypted = Encoding.UTF8.GetString(decryptedBytes);

Beware, that your message can only contain 105 characters (with the key exchange parameters) since this will result in 1022 bytes. The next 105 characters will result in an additional 1022 bytes and therefore will be too long for one IOTA message (of course you could bundle multiple IOTA transactions to send out longer texts). For a key exchange, you can store a public key on an address and then share the address of the public key. In Chiota not only the public key is stored on this address but also the request address to contact a user. This way you don’t have to use this address for the key exchange.

See https://github.com/Noc2/Chiota/blob/master/Chiota/Chiota/ViewModels/SetupViewModel.cs

Anyone with access to this address can now send you a decrypted message to the request address, which only you can read. To make sure you have the correct public key, in Chiota only one key is allowed per address. The app will automatically generate a new public key address combination if it finds more than one valid key on an address.

See https://github.com/Noc2/Chiota/blob/master/Chiota/Chiota/Services/Iota/UserDataOnTangle.cs#L24-L60

If you notice any security flaws with the current implementation, please open a GitHub issue.