Auth Lib – with DH Key Exchange Algorithm, MD5 Digest Algorithm and Helper APIs

Finally, I’ve got time to summaries the authentication work I’ve done for MGC:) This post gives a useful C lib on authentication focusing on DH key exchange algorithm and MD5 digest helper APIs. Please note this lib should be built/used with the MD5 implementation from RFC1321 (http://www.faqs.org/rfcs/rfc1321.html), including ‘global.h’, ‘md5.h’ and ‘md5c.c’ (‘mddriver.c’ is optional as being testing code). Some of the APIs have two versions – one is focusing on memory usage; the other pays attention to performance. Different system requirement should call different APIs. Any question/suggestion, please feel free to let me know. Enjoy:)

authlib

Project Name: authlib
Destination: A C lib providing helper APIs on authentication related, especially for md5 and DH algorithms
Language: C
IDE: vi
Project Web: http://kenai.com/projects/authlib
SVN address: https://svn.kenai.com/svn/authlib~authlib-src
Source Code: http://kenai.com/projects/authlib/sources/authlib-src/show

/*
* authUtils.h
* Header file for authLib with all related utils functions
* dave.tian@alcatel-lucent.com
* 2011/10/18
*/

#ifndef AUTHUTILS_H
#define AUTHUTILS_H

/* Diffie-Hellman key exchange algorithm */
unsigned long authDhKey( unsigned long, unsigned int, unsigned int);

/* MD5 algorithm with ASCII string as source input */
void authMD5String(char *, char *);

/* MD5 algorithm with ASCII string as source input with binary processing */
unsigned int authMD5Binary(char *, unsigned int, char *);

/* Conversion from binary format to hex format using table */
unsigned int authBin2HexTable( char *, unsigned int, char *);

/* Conversion from hex format to binary format using table */
unsigned int authHex2BinTable( char *, unsigned int, char *);

/* Conversion from binary format to hex format using bit operation */
int authBin2HexBit( char *, unsigned int, char *);

/* Conversion from hex format to binary format using bit operation */
int authHex2BinBit( char *, unsigned int, char *);

/* Conversion from unsigned long to char array (binary format) */
unsigned int authUlong2CharArrayBin( unsigned long, char *);

/* Concatenation function for binary format input */
unsigned int authConcatenateBinString( char *, unsigned int, char *);

/* hex digits checking wrapper */
int authHexDigitsChecking( char *);

#endif /* AUTHUTILS_H */

/home/daveti/authLib: ll
total 27
-rw-r–r–    1 daveti   daveti       2020 Oct 25 07:00 Makefile
-rw-r–r–    1 daveti   daveti        232 Oct 18 03:11 authDefs.h
-rw-r–r–    1 daveti   daveti      22869 Oct 25 06:18 authUtils.c
-rw-r–r–    1 daveti   daveti       1353 Oct 25 06:11 authUtils.h
-rw-r–r–    1 daveti   daveti        795 Oct 18 02:10 global.h
-rw-r–r–    1 daveti   daveti       1350 Oct 18 02:10 md5.h
-rw-r–r–    1 daveti   daveti      10031 Oct 18 02:15 md5c.c
-rw-r–r–    1 daveti   daveti       5004 Oct 24 09:29 mddriver.c
/home/daveti/authLib: make

#############################################
##### Building authLib source code….  #####
#############################################

gcc -c -DMD=5 mddriver.c
gcc -c -DMD=5 md5c.c
gcc -c -DMD=5 authUtils.c
gcc -DMD=5 -o auth  mddriver.o md5c.o authUtils.o
/home/daveti/authLib: make test
echo ‘MD5 test suite:’ > test.rfc
echo ‘MD5 (“”) = d41d8cd98f00b204e9800998ecf8427e’ >> test.rfc
echo ‘MD5 (“a”) = 0cc175b9c0f1b6a831c399e269772661’ >> test.rfc
echo ‘MD5 (“abc”) = 900150983cd24fb0d6963f7d28e17f72’ >> test.rfc
echo ‘MD5 (“message digest”) = f96b697d7cb7938d525a2f31aaf161d0’ >> test.rfc
echo ‘MD5 (“abcdefghijklmnopqrstuvwxyz”) = c3fcd3d76192e4007dfb496cca67e13b’ >> test.rfc
echo ‘MD5 (“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789”) = d174ab98d277d9f5a5611c2c9f419d9f’ >> test.rfc
echo ‘MD5 (“12345678901234567890123456789012345678901234567890123456789012345678901234567890”) = 57edf4a22be3c955ac49da2e2107b67a’ >> test.rfc
./auth  -x | diff – test.rfc > diffs 2>&1
*** MD5 Test Passed
rm -f diffs

Posted in Dave's Tools, Programming | Tagged , , , , | Leave a comment

Bug in g++ 3.X – invalid operands of types `A&’ and `int’ to binary `operator!=’

I am not sure if there is a bug declaration for g++ 3.X (have not checked the doc yet). On the other hand, g++ 4.X, however, could compile the example code below silently. Anyway, seems for g++ 3.X, reference operator ‘&’ and address operator ‘&’ would confuse the compiler when they are used the same time in one expression. There is also a workaround there to bypass the complain from older compiler.

/home/daveti/Ctest: cat reference.cpp
#include <stdio.h>

typedef struct _A
{
        int a;
        int b;
}A;

int main( void)
{
        A x;
        A &y = x;

        if ( &(y.a) || 1)
        {
                printf("Sounds goodn");
        }

        return 0;
}
/home/daveti/Ctest: g++ -o reference reference.cpp
reference.cpp: In function `int main()’:
reference.cpp:14: invalid operands of types `A&’ and `int’ to binary `
   operator!=’
/home/daveti/Ctest: g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure –prefix=/usr –mandir=/usr/share/man –infodir=/usr/share/info –enable-shared –enable-threads=posix –disable-checking –with-system-zlib –enable-__cxa_atexit –host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)

/home/daveti/Ctest: cat reference2.cpp
#include <stdio.h>

typedef struct _A
{
        int a;
        int b;
}A;

int main( void)
{
        A x;
        A &y = x;
        int p = y.a;

        if ( &(p) || 1)
        {
                printf("Sounds goodn");
        }

        return 0;
}
/home/daveti/Ctest: g++ -o reference2 reference2.cpp
/home/daveti/Ctest: ./reference2
Sounds good
/home/daveti/Ctest: g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure –prefix=/usr –mandir=/usr/share/man –infodir=/usr/share/info –enable-shared –enable-threads=posix –disable-checking –with-system-zlib –enable-__cxa_atexit –host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)

Posted in Programming, Stuff about Compiler | Tagged , | 1 Comment

Random in Shell

This post introduces the ‘$RANDOM’ in Shell including Ksh, Bash and Zsh and gives 2 examples using random processing in Shell. May it help:)

1. Number sequence random order generator

#
# Number sequence random order generator – nsrog
# Generate random order of number sequence based on the range.
# Version 0.0
# Aug 13, 2011
# dave.tian@alcatel-lucent.com
#
[[ -f $PWD/random.nsrog ]] && (rm -f $PWD/random.nsrog) > /dev/null 2>&1
typeset -i counter
counter=1
while (( counter <= 10 ))
do
        echo "$counter $RANDOM" >> random.nsrog
        (( counter++ ))
done
cat random.nsrog | sort -k2n | cut -d" " -f1 | xargs

/home/daveti/Shelltest: ./nsrog
6 1 2 4 3 5 7 9 8 10
/home/daveti/Shelltest: ./nsrog
3 9 2 10 8 1 4 7 5 6
/home/daveti/Shelltest: ./nsrog
10 4 7 2 1 8 6 9 3 5
/home/daveti/Shelltest:

2. Random line file generator

#
# Random line file generator – rlfg
# Generate random lines of the file.
# Version 0.0
# Aug 13, 2011
# dave.tian@alcatel-lucent.com
#
[[ -f $PWD/random.rlfg ]] && (rm -f $PWD/random.rlfg) > /dev/null 2>&1
while read i
do
        echo "$i $RANDOM" >> random.rlfg
done < input.rlfg
cat random.rlfg | sort -k2n | cut -d" " -f1

/home/daveti/Shelltest: cat input.rlfg
this_is_line_1
this_is_line_2
this_is_line_3
this_is_line_4
this_is_line_5
this_is_line_6
this_is_line_7
this_is_line_8
this_is_line_9
this_is_line_10
/home/daveti/Shelltest: ./rlfg
this_is_line_1
this_is_line_9
this_is_line_6
this_is_line_3
this_is_line_8
this_is_line_10
this_is_line_4
this_is_line_7
this_is_line_5
this_is_line_2
/home/daveti/Shelltest:

Posted in Programming | Tagged , | Leave a comment

Something about Coverity Modeling – for a friend’s question

This post is focusing on general idea of Coverity Modeling based on Coverity 4.5.1 and Coverity 5.4.1 including why and how to do Coverity Modeling. Of course, Coverity official document would always be a good reference to start with. More over, will this post could be a not too bad annex for official document for Coverity Modeling.

1. Why Modeling?

There are 2 destinations to do modeling: 1st is to find new defect (because of maximum path analyzing limitation, some of functions would not be analyzed. Then Modeling is forcing Coverity to do the analysis for these functions); 2nd is to remove the false alarm (because of some reason, like complex internal logic, certain function could not be analyzed correctly. In such case, then modeling is needed to help Coverity forget such a function).

2. How Modeling – to remove false positives?

// Coverity 4.5.1
// SIPia_clone is a very complex memory allocate function which could not be
// analyzed normally. However, to make sure the model.c could be built
// successfully, all the necessary structures used in this function needs to
// be declared explicitly.

// To find a new defect
// Create a stub C function that uses the standard C library function to
// emulate the behavior of that function – in such case is ‘malloc’.
/* Declaration of SIPia_Msg here */
SIPia_Msg *
SIPia_clone(SIPia_Msg *baseMsg_ptr, int addSize)
{
        int             msgBlkSize;
        SIPia_Msg*  newMsg_ptr;
        /*
         * Allocate a new block of system memory for cloned message.
         */
        msgBlkSize = baseMsg_ptr->blkMgr.blkSize + addSize;
        newMsg_ptr = (SIPia_Msg *)malloc(msgBlkSize);
        return(newMsg_ptr);
}

// To remove the false positives, we need to use Coverity primitives
// to rewrite – in such case below is ‘__coverity_alloc__’, although there is
// another option here – empty function.
/* Declaration of SIPia_Msg here */
SIPia_Msg *
SIPia_clone(SIPia_Msg *baseMsg_ptr, int addSize)
{
        int             msgBlkSize;
        SIPia_Msg*  newMsg_ptr;
        /*
         * Allocate a new block of system memory for cloned message.
         */
        msgBlkSize = baseMsg_ptr->blkMgr.blkSize + addSize;
        newMsg_ptr = (SIPia_Msg *)__coverity_alloc__(msgBlkSize);
        return(newMsg_ptr);
}

// Coverity 5.4.1
// There is a bit of difference between Coverity 4.5.1 and Coverity 5.4.1
// except more Coverity Modeling primitives. When compiling modeling for
// removing false postivite, some of the C library functions may cause build
// error like below:
// home/coverity/model_libs/msc/msc_all.c", line 211: error #20: identifier
//          "memcpy" is undefined
//           memcpy (( UBYTE *)((ULONG)newIMsg + sizeof(IMSG)),
// For such a case, ‘memcpy’ needsto rewrite based on the the follow source:
// cov-sa-linux-5.4.1/library/generic/common/mem.c
static void *escape;
void *memcpy(void *d, void *s, size_t n)
{
            __coverity_negative_sink__(n);
            if(n != 0) {
                        ((char *)d)[n-1] = ((char *)s)[n-1];
                        *(char*)d = *(char*)s;
                        __coverity_writeall__(d);
                        escape = *((void **)s);
                    }
            return d;
}

Posted in Stuff about Compiler | Tagged | 1 Comment

Encounter – 2/4 of being flawless

This may be my favorite song written all by myself, for  someone I’ve met on someday, for me and my shadow. Wonder if the wheels of fate have been started. Anyway, like Dr House said, “All people’s dying except the ones who’s already been dead…”. With the hint and instruction of God, just take it, feel it and make ourselves a little more better, which I think is the only way of being flawless:)

Try the rhythm mp3 file: [audio:http://daveti.blog.com/files/2011/05/meet2.mp3|titles=meet2]

Try the rhythm+solo mp3 file: [audio:http://daveti.blog.com/files/2011/05/meet4.mp3|titles=meet4]

Name: Encounter – 2/4 of being flawless
Tune: Dmaj7
Date: May 2, 2011
Originated: daveti
Rhythm: daveti
Solo: daveti
Synthesize: daveti
Equipment: Fender Squier STRAT 0932 (unplugged), Internal mac of ThinkPad T61
Software: Java Sound Demo, Winamp 5.2

Posted in Music Prose | Tagged , | 1 Comment

Diffie-Hellman key exchange algorithm – deeper and better

In my last post on D-H algorithm (http://daveti.blog.com/2011/04/21/diffiehellman-key-exchange-dh-algorithm-in-c/), we talked about 2 implementation using C. However, I’ve been thinking about one thing here these days – if there is any potential integer overflow risk in both functions (though for unsigned value, there is ‘over’ but no ‘flow’ indeed). Clearly, it would be perfect if a complete mathematic induction and deduction with formulas could be provided for D-H algorithm to find out the max value. But that is not the point here – we are going thru all the possible inputs given the certain ranges and rewrite a new dh4 function with better performance and integer overflow detection. We may need another post to talk about integer overflow with details. Anyway, check it out:)

/*
* dh4.c
* Example source file for D-H algorithm in key exchange
* Deeper into potential integer overflow detection
* Example fields: IPsec, MG<->MGC authentication
* Example usage: ./dh
* dhKey = g^a mod(p)
*      g – unsigned long, like 2-4294967295(0xffffffff)
*      a – unsigned int, like 2-65535(0xffff)
*      p – unsigned int, prime number, like 2-65535
* Destination: we will going thru all the possible values
* for g, a and p and try to figure out if there is potential
* integer overflow using dh2 implementation.
* Build cmd: gcc -o dh -lm dh.c
* 2011/04/28
* dave.tian@alcatel-lucent.com
*
http://daveti.blog.com
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/times.h>
#include <unistd.h>

unsigned long dh1( unsigned long, unsigned int, unsigned int);
unsigned long dh4( unsigned long, unsigned int, unsigned int);

int main( int argc, char **argv)
{
        // g: 2~0xffffffff
        // a: 2~0xffff
        // p: 2~0xffff
        // D-H algorithm: g^a mod(p);
        unsigned long gIdx = 0;
        unsigned int aIdx = 0;
        unsigned int pIdx = 0;
        unsigned int pRoot = 0;
        unsigned int pRootIdx = 0;
        unsigned long dhKey = 0;
        int isPrime = 0;

        // To accelerate the speed of the computation, it is good to
        // find out all the possible prime numbers and store them in
        // a array. Please note when the range of prime need to search
        // is very large (much larger than 0~0xffff in our case). Stack
        // size may not support this. Think about 2 ways here – either
        // static data area or link structure with malloc allocation.
        // daveti on 2011/04/28
        unsigned int primeArray[ 0xffff] = {0};
        unsigned int primeTotal = 0;
        unsigned int arrayIdx = 0;

        struct tms time_buf_head, time_buf_end;
        clock_t time_head, time_end;
        long tck = sysconf (_SC_CLK_TCK);
        time_head = times( &time_buf_head );
        // Find the prime numbers first and store them
        // Here we do not think 1 is a prime number!
        for ( pIdx = 2; pIdx <= 0xffff; pIdx++)
        {
                isPrime = 1;
                pRoot = (unsigned int)sqrt( pIdx);
                for ( pRootIdx = 2; pRootIdx <= pRoot; pRootIdx++)
                {
                        if ( pIdx%pRootIdx == 0)
                        {
                                // This is not a prime number!
                                isPrime = 0;
                                break;
                        }
                }
                if ( (isPrime == 1) && (arrayIdx < 0xffff))
                {
                        // This is a prime number. Store it!
                        primeArray[ arrayIdx] = pIdx;
                        primeTotal++;
                        arrayIdx++;
                }
        }
        time_end = times( &time_buf_end );
        printf("Prime searching: user time: %f, sys time: %f, child user time: %f, child sys time: %fn",
                ((time_buf_end.tms_utime – time_buf_head.tms_utime) / (double)tck),
                ((time_buf_end.tms_stime – time_buf_head.tms_stime) / (double)tck),
                ((time_buf_end.tms_cutime – time_buf_head.tms_cutime) / (double)tck),
                ((time_buf_end.tms_cstime – time_buf_head.tms_cstime) / (double)tck) );
        printf("Dump the first 10 prime numbers: ");
        for ( arrayIdx = 0; arrayIdx < 10; arrayIdx++)
        {
                printf("%u, ", primeArray[ arrayIdx]);
        }
        printf("nPrime found in total: %un", primeTotal);

        time_head = times( &time_buf_head );
        for ( gIdx = 2; gIdx <= 0xffffffff; gIdx++)
        {
                for ( aIdx = 2; aIdx <= 0xffff; aIdx++)
                {
                        for ( pIdx = 0; pIdx < primeTotal; pIdx++)
                        {
                                dhKey = dh4( gIdx, aIdx, primeArray[ pIdx]);
                        }
                }
        }
        time_end = times( &time_buf_end );

        printf("Loop: user time: %f, sys time: %f, child user time: %f, child sys time: %fn",
                ((time_buf_end.tms_utime – time_buf_head.tms_utime) / (double)tck),
                ((time_buf_end.tms_stime – time_buf_head.tms_stime) / (double)tck),
                ((time_buf_end.tms_cutime – time_buf_head.tms_cutime) / (double)tck),
                ((time_buf_end.tms_cstime – time_buf_head.tms_cstime) / (double)tck) );

        return 0;
}

unsigned long dh1( unsigned long g, unsigned int a, unsigned int p)
{
        // This is a recurssion version of D-H algorithm
        // implemented by daveti on 2011/04/20
        // Is there a way using C code to detect the potential
        // integer overflow here? I do not think so. Assembly
        // code may help here. Even if it does, the code is NOT
        // portable anymore – CPU architecture specified.
        // daveti on 2011/04/26

        if ( a == 0)
        {
                printf("Errorn");
                return 0;
        }

        if ( a == 1)
        {
                return g%p;
        }

        // (a*b)%c == ((a%c)*(b%c))%c
        return ((g%p)*(dh1( g, a-1, p)))%p;
}

unsigned long dh4( unsigned long g, unsigned int a, unsigned int p)
{
        // This is non-recurssion version of D-H algorithm
        // implemented by daveti on 2011/04/21
        // g^4%p = (g%p*((g%p*((g%p*(g%p))%p))%p))%p
        // let z = g%p
        // g^4%p = (z*((z*((z*z)%p))%p))%p
        //       = (((((z*z)%p)*z)%p)*z)%p
        // What about this function – any way to detect potential
        // integer overflow here? I think so:) Generally, we are
        // going back to the old question – how do we detect potential
        // integer overflow for ‘a+b’ and/or ‘a*b’…
        // daveti on 2011/04/26

        if ( a == 0)
        {
                printf("Errorn");
                return 0;
        }

        unsigned long z = g%p;
        // Check for possible zero value to fast the output
        // and to avoid floating exception during devision
        // computation in the overflow detection.
        // daveti on 2011/04/27
        if ( (a == 1) || (z == 0))
        {
                return z;
        }

        unsigned int idx = 0;
        unsigned long tmp = z;
        unsigned long overflow = 0;
        for ( idx = 2; idx <= a; idx++)
        {
                // tmp = (tmp*z)%p;
                // Add potential overflow detection for each loop
                // Isn’t this method clever:)
                overflow = tmp*z;
                if ( overflow/tmp != z)
                {
                        printf("Error: Integer overflow on ‘tmp*z’"
                                " – tmp=%lu, z=%lun", tmp, z);
                        return 0;
                }
                tmp = overflow%p;
        }

        return tmp;
}

Posted in Programming | Tagged , , , | Leave a comment

Diffie–Hellman key exchange (DH algorithm in C)

I am recently doing feature on authentication between MGC (Media Gateway Controller) and MG (Media Gateway). One important thing involved in Diffie-Hellman key exchange. Not sure if because the key formula ‘g^a mod(P)’ looks simple and stupid, it is hard for me to find any real, useful and practical code implementation for this (maybe it is a piece of cake for anybody else:) Anyway, I have implemented 2 different functions below for DH algorithm using C. May it help!

/*
* dh.c
* Example source file for D-H algorithm in key exchange
* Example fields: IPsec, MG<->MGC authentication
* Example usage: ./dh 10000 8888 523
* dhKey = g^a mod(p)
*      g – unsigned long, like 2-4294967295
*      a – unsigned int, like 2-65535
*      p – unsigned int, prime number, like 2-65535
* Build cmd: gcc -o dh -lm dh.c
* Input sequence: g a p
* 2011/04/20
* dave.tian@alcatel-lucentc.om
*
http://daveti.blog.com
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/times.h>
#include <unistd.h>

unsigned long dh1( unsigned long, unsigned int, unsigned int);
unsigned long dh2( unsigned long, unsigned int, unsigned int);

int main( int argc, char **argv)
{
if ( argc != 4)
{
printf(“Errorn”);
return 1;
}

// Get the input from cli
unsigned long g = strtoul( argv[ 1], NULL, 10);
unsigned int a = strtoul( argv[ 2], NULL, 10);
unsigned int p = strtoul( argv[ 3], NULL, 10);
printf(“g = %luna = %unp = %un”, g, a, p);

// Check if p is a prime number
// C++ may have a function called isPrime? – not sure of that:)
unsigned int i = 0;
unsigned int r = (unsigned int)sqrt( p);
for( i = 2; i <= r; i++)
{
if ( p%i == 0)
{
printf(“‘p’ is not a prime: %un”, p);
return 1;
}
}

// D-H algorithm: g^a mod(p);
// Time measurement could be added here to compare
// the different performance between the 2 implementations
// However, memory consideration comparison is missed here
// between the 2 functions…Personally I assume recurrsion
// function should consume more dynamic memory because of
// large number of stacks, which may cause memory overflow.

unsigned long dhKey = 0;
struct tms time_buf_head, time_buf_end;
clock_t time_head, time_end;
long tck = sysconf (_SC_CLK_TCK);
time_head = times( &time_buf_head );
dhKey = dh1( g, a, p);
time_end = times( &time_buf_end );
printf(“dh1(), user time: %f, sys time: %f, child user time: %f, child sys time: %fn”,
((time_buf_end.tms_utime – time_buf_head.tms_utime) / (double)tck),
((time_buf_end.tms_stime – time_buf_head.tms_stime) / (double)tck),
((time_buf_end.tms_cutime – time_buf_head.tms_cutime) / (double)tck),
((time_buf_end.tms_cstime – time_buf_head.tms_cstime) / (double)tck) );
printf(“dh1 = %lun”, dhKey);

time_head = times( &time_buf_head );
dhKey = dh2( g, a, p);
time_end = times( &time_buf_end );
printf(“dh2(), user time: %f, sys time: %f, child user time: %f, child sys time: %fn”,
((time_buf_end.tms_utime – time_buf_head.tms_utime) / (double)tck),
((time_buf_end.tms_stime – time_buf_head.tms_stime) / (double)tck),
((time_buf_end.tms_cutime – time_buf_head.tms_cutime) / (double)tck),
((time_buf_end.tms_cstime – time_buf_head.tms_cstime) / (double)tck) );
printf(“dh2 = %lun”, dhKey);

return 0;
}

unsigned long dh1( unsigned long g, unsigned int a, unsigned int p)
{
// This is a recurssion version of D-H algorithm
// implemented by daveti on 2011/04/20
if ( a == 0)
{
printf(“Errorn”);
return 0;
}

if ( a == 1)
{
return g%p;
}

// (a*b)%c == ((a%c)*(b%c))%c
return ((g%p)*(dh1( g, a-1, p)))%p;
}

unsigned long dh2( unsigned long g, unsigned int a, unsigned int p)
{
// This is non-recurssion version of D-H algorithm
// implemented by daveti on 2011/04/21
// g^4%p = (g%p*((g%p*((g%p*(g%p))%p))%p))%p
// let z = g%p
// g^4%p = (z*((z*((z*z)%p))%p))%p
//       = (((((z*z)%p)*z)%p)*z)%p
if ( a == 0)
{
printf(“Errorn”);
return 0;
}

unsigned long z = g%p;
if ( a == 1)
{
return z;
}

unsigned int idx = 0;
unsigned long tmp = z;
for ( idx = 2; idx <= a; idx++)
{
tmp = (tmp*z)%p;
}

return tmp;
}

Posted in Programming | Tagged , , | 2 Comments

smell of mango

Smell of rain, smell of the city, smell of somebody, smell of the memory……

Name: Smell of Mango
Tune: Am
Music: Dave
Solo:  Dave
Rhythm: Dave
Record: Dave
Equipment: an unnamed classical guitar with steel strings,
Lenovo ThinkPad T61 internal mac,
Winamp, Windows XP Sound Recorder
Date: Mar 19, 2011

Dowload wav: smell_of_mango


Posted in Music Prose | Tagged | 2 Comments

IA 32 CPU architecture – NetBurst

Please kindly note that the picture below takes a great reference from the book ‘Professional Assembly Language’ by Richard Blum – which is a very practical book and my first book on assembly programming. The other very useful and important reference is ‘Intel 64 and IA 32 Architecture Software Developer Manuals’, which also could be found on my blog – link collection – OS.

(pic took from web: http://www.pctechguide.com/21Architecture_Basic_structure.htm)

Posted in OS, Programming | Tagged , , | Leave a comment

x86 assembly programming with GNU – tool tips

1. coding pattern

# Pattern used by as and ld
.section .data
< initialized data here>
.section .bss
< uninitialized data here>
.section .text
.globl _start
_start:
< instruction code here>

———————————-
# Pattern used by gcc
.section .data
< initialized data here>
.section .bss
< uninitialized data here>
.section .text
.globl main
main:
< instruction code here>

———————————-

2. as

# common usage
as -o demo.o demo.s

# add debugging info for gdb
as -gstabs -o demo.o demo.s

3. ld

# common usage
ld -o demo demo.o

# C lib function is called instead of syscall
ld -dynamic-linker /lib/ld-linux.so.2 -o demo -lc demo.o

4. gcc

# common usage
gcc -o demo demo.s

# add debugging info for gdb
gcc -gstabs -o demo demo.s

# add statistic info for gprof
gcc -o demo demo.c -pg

# generate assembly source from C source
gcc -S demo.c

5. objdump

# disassemble object file into assemble source
objdump -d demo.o

6. gdb

# common usage
gdb demo
run

# add break point right after ‘_start’/’main’
add ‘nop’ as the first instruction code after the label
break *_start+1

# run the program step by step or continuously
next/step/cont

# check registers and stacks
info reg/frame
print/d/t/x $ebx
d: decimal
t: binary
x: hex

# check the memory
x/nyz &output
n: number of byte segment
y: format of output – c:char, d:decimal, x:hex
z: length of byte segment – b:byte, h:16-bit-byte, w:32-bit-byte

7. gprof

# common usage
gprof demo > gprof.log

Posted in Programming | Tagged , , , , , , , , | Leave a comment