Skip to content

Instantly share code, notes, and snippets.

@mad
Created May 17, 2011 22:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mad/977537 to your computer and use it in GitHub Desktop.
Save mad/977537 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby -wKU
class SimpleCipher
attr_accessor :P, :S, :IP
CYCLE_NUM = 4
BLOCK_SIZE = 32
SUB_BLOCK_SIZE = 4
SUB_BLOCK_NUM = BLOCK_SIZE/SUB_BLOCK_SIZE
S = [8, 1, 15, 4, 12, 11, 0, 9, 2, 14, 6, 3, 13, 5, 7, 10]
IS = [6, 1, 8, 11, 3, 13, 10, 14, 0, 7, 15, 5, 4, 12, 9, 2]
def initialize(key)
# XXX: normalize key
@key = key.to_i
permutation()
end
def permutation
@P = Array.new(32)
@IP = Array.new(32)
# i*(2k + 1) + 3 mod 32
# k is student number in list
k = 1
0.upto(31) do |i|
# Default permutation from book
# @P[i - 1] = 13*i%32
@P[i] = (i*(2*k + 1) + 3) % 32
# And make inverse substitution. WHAT?
@IP[@P[i]] = i
end
# Need for default permutation
# @P[31] = 32
end
def add_padding(block)
# Add leading padding if number of bits < BLOCK_SIZE
if block.size > BLOCK_SIZE
raise "Your block greater than #{BLOCK_SIZE} bits"
elsif block.size < BLOCK_SIZE
block.insert(0, "0" * (BLOCK_SIZE - block.size))
end
return block
end
def encrypt(block)
# Do main work
CYCLE_NUM.times do |cycle|
puts "Cycle #{cycle + 1}: #{block}"
block = block.to_i
# 1. XOR
block = block ^ @key
# XXX: make more simple and add test for it
# Convert to binary string
block = block.to_s(2)
block = add_padding(block)
# Convert binary string to array with sublocks for applying
# substitution
block = block.unpack(("a" + SUB_BLOCK_SIZE.to_s) * (SUB_BLOCK_NUM))
# 2. Apply substitution for all subblocks
SUB_BLOCK_NUM.times do |b|
block[b] = "%04b" % S[block[b].to_i(2)]
end
# Preparing for permutation. Concatinate sublocks and convert it
# to bits array.
block = block.collect {|b| b.unpack("a" * SUB_BLOCK_SIZE) }.flatten
# 3. Apply permutation
tmp = Array.new(32)
BLOCK_SIZE.times do |b|
tmp[@P[b]] = block[b]
end
block = tmp
# Convert back to bits string
block = block.pack("a" * BLOCK_SIZE).to_i(2)
end
# 4. XOR with key
block = block ^ @key
# puts add_padding(block.to_s(2)).unpack(("a" + SUB_BLOCK_SIZE.to_s) * (SUB_BLOCK_NUM)).inspect
return block
end
# All encrypt steps but inverse
def decrypt(block)
# 4. XOR with key
block = block ^ @key
# Do main work
CYCLE_NUM.times do |cycle|
puts "Cycle #{cycle + 1}: #{block}"
block = block.to_i
# XXX: make more simple and add test for it
# Convert to binary string
block = block.to_s(2)
block = add_padding(block)
# Preparing for permutation. Concatinate sublocks and convert it
# to bits array.
block = block.unpack("a" * BLOCK_SIZE)
# 3. Apply permutation
tmp = Array.new(32)
BLOCK_SIZE.times do |b|
tmp[@IP[b]] = block[b]
end
block = tmp
# Convert bits arrayt to sublocks array
block = block.pack("a" * BLOCK_SIZE)
block = block.unpack(("a" + SUB_BLOCK_SIZE.to_s) * (SUB_BLOCK_NUM))
# 2. Apply substitution for all subblocks
SUB_BLOCK_NUM.times do |b|
block[b] = "%04b" % IS[block[b].to_i(2)]
end
# Convert back to bits string
block = block.pack(("a" + SUB_BLOCK_SIZE.to_s) * (SUB_BLOCK_NUM)).to_i(2)
# 1. XOR
block = block ^ @key
end
return block
end
end
sc = SimpleCipher.new("9")
p0=0
c1=0
p1=0
c2=0
(2**32).times do |i|
p0=i
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment