3
$\begingroup$

I've been trying to implement the new SIMON block cipher in Ruby as a personal challenge. The spec didn't include a pseudocode version of the decryption but I thought I had it figured out. The code I wrote is located at https://github.com/Rami114/Personal/blob/master/Simon/Simon.rb

I've based this on the spec available at http://eprint.iacr.org/2013/404.pdf

Currently my encryption does not work (at all I'd say) which may be due to code issues or do to math failure on my behalf. Could someone please help me validate if the decryption is correct. Most notably the inversion of the rounds:

# f(x) ((LCS(x,1) & LCS(x,8)) ^ LCS(x,2))

def self.f (x, block_size)
  ((lcs(x, block_size, 1) & lcs(x, block_size, 8)) ^ lcs(x, block_size, 2))
end

def self.round_inv (x, y, k1, k2)
  x ^= k2 
  x ^= f(y, N)
  y ^= k1
  y ^= f(x, N)
  return x, y
end

And the decryption function which I won't fully paste here as it's defined in the link above (the whole thing is only 200 lines long total so not a monster to read).

I have a stackoverflow question up at the moment which is specific to the way I'm currently converting strings to bignums and back (to accommodate the circular shift) but I didn't think that would be appropriate to this SE site.

Are there any glaring errors in my implementation? I'm by no means an expert in this.

E: the stackoverflow question I have up for code concerns: https://stackoverflow.com/questions/17785691/string-to-bignum-and-back-again-in-ruby-to-allow-circular-shift

$\endgroup$
4
  • $\begingroup$ I haven't read the spec in detail but one thing that often gets people with this type of algorithm is, for instance, in your line y = f(x, N), not realising that x is no longer the original one as it was modified above. This looks like a good candidate, so have you checked that? $\endgroup$
    – Thomas
    Jul 22, 2013 at 11:33
  • $\begingroup$ I believe that's the intention. I've simply reversed the steps from the encryption round which was provided in pseudocode and with a C sample. I could be incorrect, this is the first time I've implemented a cipher on which so little information has been published. $\endgroup$ Jul 22, 2013 at 11:47
  • $\begingroup$ @BenPottier Have you tried creating a decryption routine in C first and then porting that? $\endgroup$
    – orlp
    Jul 22, 2013 at 13:13
  • $\begingroup$ @nightcracker no, but that's not a bad idea! :) $\endgroup$ Jul 22, 2013 at 13:15

1 Answer 1

4
$\begingroup$

From a quick read, there are a couple of potential issues.

  1. decrypt_128_256 is iterating rounds in the same order as in encrypt_128_256, so the round keys are being applied in the wrong order on decrypt. decrypt_128_256 needs to iterate through the round keys starting from the last round and working backwards.
  2. 68 rounds are being used for Speck128/256 (should be 72) - this won't stop it being symmetric, but it will stop it passing test vectors.

A reference you can run against is a really good idea - I tend to instrument all of the intermediate calculations on the reference and new implementations, pipe both sets of output to files and diff the output to see where things need fixing up.

As you've discovered the Simon/Speck algorithms are a wee bit short of reference code - I managed to bootstrap off the Speck128/128 example at the end of the spec to a working implementation of the Speck variants, and Simon was straightforward after that.

I've just pushed my Java implementations of Simon (and Speck), which you can use for comparison or runtime reference (it's in a feature fork of Bouncy Castle, so you should be able to build from the root with little trouble).

$\endgroup$
3
  • $\begingroup$ You wrote 196 in an error message where it should have been 192 $\endgroup$ Jul 23, 2013 at 11:26
  • $\begingroup$ Thanks for taking the time @archie! I'm intending to do exactly as you said, work through each component at a time and check outputs against a base C implementation. $\endgroup$ Jul 23, 2013 at 12:24
  • $\begingroup$ I forgot to mention, on the decrypt, I'm running k = expand_key(key, 64).reverse so I'm flipping the expanded key which should work. Will feedback when I've got through some of my issues, but hopefully this will solve it for me :) $\endgroup$ Jul 23, 2013 at 12:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.