NAME

Crypt::SEED - Perl extension for SEED encryption/decryption algorithm.

SYNOPSIS

 use Crypt::SEED;

 my $seed = new Crypt::SEED();
 $seed->addKeys( @user_keys );
 # or
 my $seed = new Crypt::SEED( @user_keys );
 # Each key must be in 16 bytes in length
 my $seed = new Crypt::SEED( '0123456789ABCDEF' ); # userkey.

 my $cipher = $seed->encrypt( $source_data, '0123456789ABCDEF' );
 my $cipher = $seed->encrypt( $source_data, 3 );
 # 3 above is an user key index. starting from 0.
 my $recall = $seed->decrypt( $cipher, '0123456789ABCDEF' ); # by user key.
 my $recall = $seed->decrypt( $cipher, 3 ); # by index

 if( !$seed->hasAKey( $userKey ) ) {
 	$seed->addKey( $userKey );
 }
 my $index = $seed->replaceKey($userKey, $newKey);
 my $number_of_keys = $seed->count();
 my $idx = $seed->keyIndex($userKey);
 my $userKey = $seed->findUserKey($idx);

DESCRIPTION

This module provides the Perl community with the SEED encryption algorithm which has been made by Korean Information Security Agency(KISA, http://www.kisa.or.kr).

SEED encryption/decryption uses a 'round key' which translated from a user key. Whenever you add user keys to the module using new or addKey or addKeys, the module will translate them to round keys and store them inside the module with user keys. (Of course, in hash) And, whenever you use the user key with encrypt, decrypt methods, the module look for the matching round key from inside the module to do real job.

Important notes on Encoding

Please, <DO NOT use encoding 'blah';.> I could not figure out how to restore those decoded bytes into an SV variable in the script where 'use encoding...' inserted. Do you know ? Let me know, please.

EXPORT

None by default.

Subroutines

new
    my $seed = new Crypt::SEED();
    my $seed = new Crypt::SEED('0123456789ABCDEF');
    my $seed = new Crypt::SEED( LIST or Array );

    This will create an object of Crypt::SEED. It can accept any number of user keys as its parameter. An user key is consist of 16 characters exactly. Every objects have its own key set.

addKey
    my $idx = $seed->addKey( $userKey );
    my $cipher_data = $seed->encrypt($plain_text, $idx);
    ...
    print SOCKET "$idx:$cipher_data\n"; # Do not send user key !!

    You must add a key or more to the object before encryption or decryption. An user key must be a 16 bytes long string. Returns the index number of the key. You can use this index number as an 'index' :-) and then you can deliver it to the counter part who shares the same user key set. (And do not deliver the user key itself for the sake of security.) You can add user keys up to 99_999_999. (It is sufficient, isn't it? ;-) Index number starts from 0, not 1.

addKeys
    $seed->addKeys( a list of user keys );

    This method simply calls $seed->addKey as many as it has beed requested. Returns the number of user keys actually added.(including the keys which exists already)

removeKey
    $seed->removeKey($userKey) ne $userKey && warn "No such key";

    This method removes the user key given from its key set and returns the same user key string. If it does not find the key, returns undef. Do not user index number. It will accept only user key. If you don't know that, use findUserKey method as below;

    $seed->removeKey( $seed->findUserKey($idx) );
replaceKey
    $seed->replaceKey($oldKey, $newKey);

    This will change an old key with a new key if exists. Returns the index number or undef if it can not find the old key or if it find the `$newKey' exists already.

encrypt
    my $cipher = $seed->encrypt($plain_text, $userKey);
    or
    my $cipher = $seed->encrypt($plain_text, $userKeyIndex);

    Put the original data with a user key or index. You will get encrypted data. The $cipher's length will be n-times of 16 exactly. This can cause some confusion to the receiver outside because he can not figure out the original length of $plain_text. So, you should have to deliver the original length of $plain_text to the receiver of $cipher if you and the partner concern about it. Returns undef if the user key or index is wrong.

decrypt
    my $plain_text = $seed->decrypt($cipher, $userKey);
    or
    my $plain_text = $seed->decrypt($cipher, $userKeyIndex);

    Reverse of encrypt. Again, you may get some garbage (series of 0x00) at the end of $plain_text. If you know the original length of data, you can chop it (or them). Returns undef if the user key or index is wrong.

findUserKey
    my $userKey = $seed->findUserKey($idx);

    Converts a key index to the matching user key string. If it can not find the key, it will return undef value.

hasAKey
    if( !$seed->findUserKey($userKey) ) { ... }

    Check if the user key exists and returns 1 or undef.

keyIndex
    my $idx = $seed->keyIndex($userKey);

    Find the user key and returns matching index number.

userKeys
    my @userKeys = $seed->userKeys();

    Returns every user key strings in the order of index numbers.

count
    $seed->count();

    Returns the number of user keys added.

Rebuilding test set.

Test script test.pl uses SEED_VERIFY.txt for verification which has been made using make_test_set.c. You may want to rebuild the test set. If you want, you just compile the c source file and run it (but after you run `make' once);

$ vi make_test_set.c
$ gcc -c make_test_set.c
$ gcc -o make_test_set make_test_set.o SEED_KISA.o
$ ./make_test_set > SEED_VERIFY.txt

Open make_test_set.c file using your ascii editor and edit `printVerificationData' function call's second and third parameter. The second parameter is a user key and the third one is a string to encrypt. Please make sure both strings are exactly 16 characters long. Also keep the number of the function calls remains 5 times or more. (Now, there are 66 calls)

About SEED (Quoted from an old document)

SEED is a symmetric encryption algorithm developed by KISA (Korea Information Security Agency) and a group of experts since 1998. The input/output block size and key length of SEED is 128-bits. SEED has the 16-round Feistel structure. A 128-bit input is divided into two 64-bit blocks and the right 64-bit block is an input to the round function, with a 64-bit subkey generated from the key scheduling.

SEED is easily implemented in various software and hardware because it takes less memory to implement than other algorithms and generates keys without degrading the security of the algorithm. In particular, it can be effectively adopted in a computing environment with a restricted resources, such as mobile devices and smart cards.

SEED is robust against known attacks including DC (Differential cryptanalysis), LC (Linear cryptanalysis), and related key attacks. SEED has gone through wide public scrutinizing procedures. It has been evaluated and is considered cryptographically secure by credible organizations such as ISO/IEC JTC 1/SC 27 and Japan CRYPTREC (Cryptography Research and Evaluation Committees) [ISOSEED][CRYPTREC].

ENDIAN Matters...

This module contains codes affected by endian in SEED_KISA.c file, the bytes order of multibyte data type such as integer, long, short, etc. In almost all cases, the Makefile.PL file will handle this matter for you. But, test-failure cases are on which systems which have neither `Little Endian' nore `Big Endian'. In this cases, you may have to edit the SEED_KISA.c file by yourself to modify `EndianChange', `GetB0', `GetB1', `GetB2' and `GetB3' macros `#define'd. If you have tested on such a system, please let me know how-to.

AUTHOR

Jongpil Jeon, <blueabi@hanmail.net>. Copyright (C) 2008 Jongpil Jeon. Perl "Artistic License" applied.

SEE ALSO

perl. ISO/IEC 18033-3 : Information technology - Security techniques - Encryption algorithms - Part 3 : Block ciphers IETF RFC 4269 : The SEED Encryption Algorithm