Posts

    Ruby meta-programming

    2016-01-30 20:31:46 +0000

    #Ruby meta-programming

    Before starting with ruby meta-programming, one should clearly understand the ruby object model. Here are some great videos explaining the same:

    RubyMonk provides two courses on meta-programming.

    • Metaprogramming Ruby
    • Metaprogramming Ruby: Ascent

    Please go through the same if you are a beginner to meta-programming.

    ALL THE BEST!!!

    Ruby Koans

    2016-01-25 15:59:56 +0000

    RubyKoans is an excellant approach to learn the Ruby language, syntax, structure, and some common functions and libraries. This also teaches you a testing culture. This requires tests to be fixed in order to progress.

    My solutions are available here.

    ##Development Tweaks

    Real time updates

    To check the solution, one has to run rake command everytime to know progress status. Smells like there is a need for automation.

    I used kicker which is a lean, agnostic, flexible file-change watcher using OS X FSEvents.

    You may add this simple .kick file to the koans project.

    process do |files|
      		execute("rake")
    end
    

    To start,

    $ kick
    

    Now whenever you modify any test and save the file, kicker will show you the current status.

    Git

    To share solutions with everyone, I used git and pushed solutions to Github repo.

    Prefill commit message

    This project saves all the current progress in .path_progress file. Sample file:

    0,1,2,2,3,3,4,4,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,9,9,9,9,10,10,10,10,10,10,11,11,11,12,12,12,13,13,13,13,13,13,14,14
    

    Whenever a koan is finished, koan number is automatically appended to .path_progress.

    Now trick is to prefill git commit message with the current progress. I created this prepare-commit-msg hook to solve this problem.

    #!/bin/sh
    
    commitMessage=$(./`git rev-parse --git-dir`/get-progress)
    echo "Finish koan $commitMessage\n $(cat $1)" > $1
    

    This hook uses another script get-progress which prints the current progress(i.e. koan number).

    #!/usr/bin/env ruby
    
    PROGRESS_FILE_NAME = '.path_progress'
    
    contents = []
    if File.exists?(PROGRESS_FILE_NAME)
      		File.open(PROGRESS_FILE_NAME,'r') do |f|
    		contents = f.read.to_s.gsub(/\s/,'').split(',')
      		end
    end
    
    print contents.last
    

    Duplicates in .path_progress

    Everytime rake is run, current progress (i.e. koan number) is added to .path_progress which leads to unnecessary file changes. This creates further problems when .path_progress is added to git repo.

    Time to fix neo.rb. Add following code to add_progress method.

    def add_progress(prog)
    	@_contents = progress
    	# return if already added to progress
    	return if  prog.to_i == progress.last.to_i
    

    Bash Gmail Scripts

    2015-11-26 01:53:24 +0000

    Here’s my efforts on writing wrapper script to send mails from terminal. Looking forward to use this in other useful scripts.

    Gmail Scripts

    Automation

    2015-11-22 21:40:51 +0000

    This sunday’s challenge was to maintain a service which provides the latest version info of an iOS application.

    Previously, we used to update this info manually each time new version gets approved and released on appstore. But as one can easily guess, this leads to problems like delays, misses updating the same.

    “Mistakes tend to occur whenever work is manual”

    Here comes the savior…Fastlane’s Spaceship. Using this one can fetch iOS app info from iTunes connect and developer portal.

    Now lets automate:

    • Create a cron job to run our script everyday.
    • Script contains fetching app info from iTunes connect and update the same on our servers.

    By the way, this led me to explore cron jobs more and think about solving my day to day problems with cron jobs.

    • To start, I created a basic cron job which posts notification on mac osx every 20 minutes. Notification reminds user to take a break from work.

    • Also, a created a cron job to remind me continuously about informing team about standup status. Till I act on the notification, notification is continuously posted every 15 minutes in the morning for few hours. Once action is taken, notification is posted next day. BTW this makes sure it only reminds on weekdays.

    By the end of day, I again fell in love with cron jobs.

    AES

    2015-08-23 17:57:32 +0000

    AES-128-ECB and AES-128-CBC

    Here 128 refers to number of bits.

    128 bits = 16 bytes

    Block

    AES has to be applied on blocks of input data. Each block is of 16 bytes length.

    2D Matrix Representation

    16 bytes block can be represented in a 4 x 4 matrix. Example: “YELLOW SUBMARINE” can be represented as:

    'Y'	'O'	'U'	'R'
    'E'	'W'	'B'	'I'
    'L'		'M'	'N'
    'L'	'S'	'A'	'E'
    

    Note: Bytes has to be filled columnwise and not rowwise. Aim is to spread out the message. This is one of the ideas of crypto DIFFUSION.

    Operations

    Encryption			Decryption
    ----------			----------
    addRoundKey			addRoundKey
    subBytes			invSubBytes
    shiftRows			invShiftRows
    mixColumns			invMixColumns
    

    Details about these operations can be found in my friend’s blog here.

    Block Cipher Encryption + Decryption

    message = decrypt(encrypt(message))
    

    As it is clear from the expression, decryption is the reverse of encryption. Once you understand encryption, just reverse the steps you have done in encryption and you will get decryption.

    Key expansion

    Block cipher encryption/decryption consists of multiple rounds of operations. Each time you apply addRoundKey() operation, it needs a different key to be added. Given an initial key, say k of length 16 bytes, we can apply a procedure to get expanded keys. As we will see later, in block cipher operation addRoundKey() is applied 11 times. We will use key expansion procedure to get 10 new keys.

    key k
    key k1 = expandKey(k)
    key k2 = expandKey(k1)
    .
    .
    .
    key k10 = expandKey(k9)
    

    These keys k, k1, …, k10 has to be found in advance before starting with block cipher encryption and decryption process.

    Block cipher encryption

    begin = 
    	addRoundKey
    middle = 9 rounds
    	subBytes
    	shiftRows
    	mixColumns						
    	addRoundKey
    end =
    	subBytes
    	shiftRows
    	addRoundKey
    

    Block cipher decryption

    begin =
    	addRoundKey
    middle = 
    	invShiftRows
    	invSubBytes
    	addRoundKey
    	invMixColumns
    end =
    	invShiftRows
    	invSubBytes
    	addRoundKey
    

    Note: Following figure shows that block cipher decryption is just the reverse of block cipher encryption process.

    AES-128-ECB

    Encryption

    For each of the blocks, feed plaintext block and key to block cipher encryption and thats it. We will get ciphertext corresponding to each block of plaintext. Combine them and you are done!!!

    Decryption

    For each of the blocks, feed ciphertext block and key to block cipher decryption and thats it. We will get plaintext corresponding to each block of ciphertext. Combine them and you are done!!!

    Note: In ECB mode, operations on each block of plaintext is independent of other blocks. This means two different blocks of similar plaintext will give same ciphertext. This fact related to duplicates can be misused to crack AES-ECB.

    AES-128-CBC

    CBC overcomes the problem in ECB mode. While performing block cipher encryption/decryption on a block, it depends upon the ciphertext of the previous block operation.

    For the first block, we take initialization vector(IV). For rest of the blocks IV is the same as ciphertext of previous blocks.

    Encryption

    Before applying block cipher encryption process, perform plaintext xor IV.

    Decryption

    After applying block cipher decryption process, perform output xor IV to get plaintext.

    PKCS#7 Padding

    The message to be encrypted can be of any length. To make sure that the length is a multiple of block size(16 bytes here), we will add PKCS#7 padding. Example, “YELLOW SUBMAR” will be changed to “YELLOW SUBMAR\u0003\u0003\u0003”. More details here.

    Tools

    Use openssl command line tool to encrypt/decrypt as per ECB and CBC modes.
    Refer to post to understand usage.

    Further reading

subscribe via RSS