免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1660 | 回复: 0
打印 上一主题 下一主题

[算法] 大家能不能给一个f8、f9的最快算法,文档中提供的算法效率很低,狂占CPU [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-08-01 12:41 |只看该作者 |倒序浏览
Simulation Program Listing
Header file

/*---------------------------------------------------------
*                                        Kasumi.h
*---------------------------------------------------------*/

typedef unsigned  char   u8;
typedef unsigned short  u16;
typedef unsigned  long  u32;

/*----- a 64-bit structure to help with endian issues -----*/

typedef union {
        u32 b32[2];
        u16 b16[4];
        u8  b8[8];
} REGISTER64;

/*------------- prototypes --------------------------------*/

void KeySchedule( u8 *key );
void Kasumi( u8 *data );
u8 * f9( u8 *key,int count,int fresh, int dir,u8 *data,int length );
void f8( u8 *key,int count,int bearer,int dir,u8 *data,int length );

Function f8
/*-------------------------------------------------------------------
*                                F8 - Confidentiality Algorithm
*-------------------------------------------------------------------
*
*        A sample implementation of f8, the 3GPP Confidentiality algorithm.
*
*        This has been coded for clarity, not necessarily for efficiency.
*
*        This will compile and run correctly on both Intel (little endian)
*  and Sparc (big endian) machines. (Compilers used supported 32-bit ints)
*
*        Version 1.0                05 November  1999
*
*-------------------------------------------------------------------*/

#include "kasumi.h"
#include <stdio.h>

/*---------------------------------------------------------
* f8()
*                Given key, count, bearer, direction,  data,
*                and bit length  encrypt the bit stream
*---------------------------------------------------------*/
void f8( u8 *key, int count, int bearer, int dir, u8 *data, int length )
{
        REGISTER64 A;                /* the modifier                        */
        REGISTER64 temp;                /* The working register        */
        int i, n;
        u8  ModKey[16];                /* Modified key                */
        u16 blkcnt;                        /* The block counter */

        /* Start by building our global modifier */

        temp.b32[0]  = temp.b32[1]  = 0;
        A.b32[0]     = A.b32[1]     = 0;

        /* initialise register in an endian correct manner*/

        A.b8[0]  = (u (count>>24);
        A.b8[1]  = (u (count>>16);
        A.b8[2]  = (u (count>>;
        A.b8[3]  = (u (count);
        A.b8[4]  = (u (bearer<<3);
        A.b8[4] |= (u (dir<<2);

        /* Construct the modified key and then "kasumi" A */

        for( n=0; n<16; ++n )
                ModKey[n] = (u(key[n] ^ 0x55);
        KeySchedule( ModKey );

        Kasumi( A.b8 );        /* First encryption to create modifier */

        /* Final initialisation steps */

        blkcnt = 0;
        KeySchedule( key );

        /* Now run the block cipher */

        while( length > 0 )
        {
                /* First we calculate the next 64-bits of keystream */

                /* XOR in A and BLKCNT to last value */

                temp.b32[0] ^= A.b32[0];
                temp.b32[1] ^= A.b32[1];
                temp.b8[7] ^= (u  blkcnt;
                temp.b8[6] ^= (u (blkcnt>>8);

                /* KASUMI it to produce the next block of keystream */

                Kasumi( temp.b8 );

                /* Set <n> to the number of bytes of input data        *
                 * we have to modify.  (=8 if length <= 64)                */

                if( length >= 64 )
                        n = 8;
                else
                        n = (length+7)/8;

                /* XOR the keystream with the input data stream */

                for( i=0; i<n; ++i )
                        *data++ ^= temp.b8;
                length -= 64;        /* done another 64 bits        */
                ++blkcnt;                /* increment BLKCNT                */
        }
}

/*-----------------------------------------------------------
*                        e n d    o f    f 8 . c
*-----------------------------------------------------------*/

Function f9
/*-------------------------------------------------------------------
*                                F9 - Integrity Algorithm
*-------------------------------------------------------------------
*
*        A sample implementation of f9, the 3GPP Integrity algorithm.
*
*        This has been coded for clarity, not necessarily for efficiency.
*
*        This will compile and run correctly on both Intel (little endian)
*  and Sparc (big endian) machines. (Compilers used supported 32-bit ints)
*
*        Version 1.1                05 September  2000
*
*-------------------------------------------------------------------*/

#include "kasumi.h"
#include <stdio.h>

/*---------------------------------------------------------
* f9()
*                Given key, count, fresh, direction, data,
*                and message length, calculate the hash value
*---------------------------------------------------------*/
u8 *f9( u8 *key, int count, int fresh, int dir, u8 *data, int length )
{
        REGISTER64 A;        /* Holds the CBC chained data                        */
        REGISTER64 B;        /* Holds the XOR of all KASUMI outputs        */
        u8  FinalBit[8] = {0x80, 0x40, 0x20, 0x10, 8,4,2,1};
        u8  ModKey[16];
        static u8 mac_i[4];        /* static memory for the result */
        int i, n;

        /* Start by initialising the block cipher */

        KeySchedule( key );

        /* Next initialise the MAC chain.  Make sure we        *
         * have the data in the right byte order.                        *
         * <A> holds our chaining value...                                *
         * <B> is the running XOR of all KASUMI o/ps                */

        for( n=0; n<4; ++n )
        {
                A.b8[n]   = (u8)(count>>(24-(n*8)));
                A.b8[n+4] = (u8)(fresh>>(24-(n*8)));
        }
        Kasumi( A.b8 );
        B.b32[0] = A.b32[0];
        B.b32[1] = A.b32[1];

        /* Now run the blocks until we reach the last block */

        while( length >= 64 )
        {
                for( n=0; n<8; ++n )
                        A.b8[n] ^= *data++;
                Kasumi( A.b8 );
                length -= 64;
                B.b32[0] ^= A.b32[0];        /* running XOR across */
                B.b32[1] ^= A.b32[1];        /* the block outputs         */
        }

        /* Process whole bytes in the last block */

        n = 0;
        while( length >=8 )
        {
                A.b8[n++] ^= *data++;
                length -= 8;
        }


        /* Now add the direction bit to the input bit stream        *
         * If length (which holds the # of data bits in the        *
         * last byte) is non-zero we add it in, otherwise                *
         * it has to start a new byte.                                                */

        if( length )
        {
                i = *data;
                if( dir )
                        i |= FinalBit[length];
        }
        else
                i = dir ? 0x80 : 0;

        A.b8[n++] ^= (u8)i;

        /* Now add in the final '1' bit.  The problem here        *
         * is if the message length happens to be n*64-1.                *
         * If so we need to process this block and then                *
         * create a new input block of 0x8000000000000000.        */

        if( (length==7) && (n==8 ) )        /* then we've filled the block */
        {
                Kasumi( A.b8 );
                B.b32[0] ^= A.b32[0];        /* running XOR across        */
                B.b32[1] ^= A.b32[1];        /* the block outputs        */

                A.b8[0] ^= 0x80;                        /* toggle first bit */
                i = 0x80;
                n = 1;
        }
        else
        {
                if( length == 7 )                /* we finished off the last byte */
                        A.b8[n] ^= 0x80;                /* so start a new one.....                */
                else
                        A.b8[n-1] ^= FinalBit[length+1];
        }


        Kasumi( A.b8 );
        B.b32[0] ^= A.b32[0];        /* running XOR across        */
        B.b32[1] ^= A.b32[1];        /* the block outputs                */

        /* Final step is to KASUMI what we have using the        *
         * key XORd with 0xAAAA.....                                                */

        for( n=0; n<16; ++n )
                ModKey[n] = (u8)*key++ ^ 0xAA;
        KeySchedule( ModKey );
        Kasumi( B.b8 );

        /* We return the left-most 32-bits of the result */

        for( n=0; n<4; ++n )
                mac_i[n] = B.b8[n];

        return( mac_i );
}

/*-----------------------------------------------------------
*                        e n d    o f    f 9 . c
*-----------------------------------------------------------*/

[ 本帖最后由 晨雨 于 2006-8-1 12:43 编辑 ]

35201-610.zip

49.7 KB, 下载次数: 37

f8 ,f9

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP