Take the 2-minute tour ×
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It's 100% free, no registration required.

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: http://stackoverflow.com/questions/17785691/string-to-bignum-and-back-again-in-ruby-to-allow-circular-shift

share|improve this question
    
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? –  Thomas Jul 22 '13 at 11:33
    
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. –  Ben Pottier Jul 22 '13 at 11:47
    
@BenPottier Have you tried creating a decryption routine in C first and then porting that? –  nightcracker Jul 22 '13 at 13:13
    
@nightcracker no, but that's not a bad idea! :) –  Ben Pottier Jul 22 '13 at 13:15
add comment

1 Answer

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).

share|improve this answer
    
You wrote 196 in an error message where it should have been 192 –  CodesInChaos Jul 23 '13 at 11:26
    
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. –  Ben Pottier Jul 23 '13 at 12:24
    
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 :) –  Ben Pottier Jul 23 '13 at 12:25
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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