5G 3GPP USIM Tuak算法code

   日期:2021-03-29     浏览:116    评论:0    
核心提示:5G 3GPP USIM Tuak算法code每个函数的功能如下图:废话不说直接上code:typedef unsigned char uint8;static const uint8 A

5G 3GPP USIM Tuak算法code

每个函数的功能如下图:

废话不说直接上code:


typedef unsigned char	 uint8;
static const uint8	ALGONAME[] = "TUAK1.0";

uint8	TOP[32];				
uint8	KEY_sz;					
uint8	RES_sz;					
uint8	CK_sz;					
uint8	IK_sz;					
uint8	MAC_sz;					
uint8	KeccakIterations;		


void TUAK_ComputeTOPC(	uint8 *key,			
									uint8 *TOPC		
							   );

void TUAK_f1				(	uint8 *key,		
									uint8 *rand,		
									uint8 *sqn,		
									uint8 *amf,		
									uint8 *mac			
								);

void TUAK_f2345			(	uint8 *key,		
									uint8 *rand,		
									uint8 *res,		
									uint8 *ck,			
									uint8 *ik,			
									uint8 *ak			
								);

void TUAK_f1s				(	uint8 *key,		
									uint8 *rand,		
									uint8 *sqn,		
									uint8 *amf,		
									uint8 *mac			
								);

void TUAK_f5s				(	uint8 *key,		
									uint8 *rand,		
									uint8 *ak			
								);






#define KECCAK_VERSION_BITS 32


#if KECCAK_VERSION_BITS==64
	static uint64	INOUT[25];	
	extern void		Keccak_f_64(uint64 *s);
# define KECCAK_F Keccak_f_64
# define TUAK_ADD_PADDING() INOUT[12] = 0x1FULL, INOUT[16] = (0x01ULL<<63)
#elif KECCAK_VERSION_BITS==32
	static uint32	INOUT[50];	
	extern void		Keccak_f_32(uint32 *s);
# define KECCAK_F Keccak_f_32
# define TUAK_ADD_PADDING() INOUT[24] = 0x1FUL, INOUT[33] = 0x80000000
#elif KECCAK_VERSION_BITS==8
	static uint8		INOUT[200];	
	extern void		Keccak_f_8(uint8 s[200]);
# define KECCAK_F Keccak_f_8
# define TUAK_ADD_PADDING() INOUT[96] = 0x1F, INOUT[135] = 0x80
#else
# error The requested version of Keccak_f is not implemented!
#endif

static const uint8	ALGONAME[] = "TUAK1.0";

void TUAK_ComputeTOPC(uint8*, uint8*);


uint8	TOP[32];						
uint8	KEY_sz				= 16;	
uint8	RES_sz				= 8;	
uint8	CK_sz					= 32;	
uint8	IK_sz					= 32;	
uint8	MAC_sz				= 16;	
uint8	KeccakIterations	= 1;	


void PUSH_DATA(const uint8 * data, uint8 n, uint8 location)
{ 	while(n--)
#if KECCAK_VERSION_BITS==64
		INOUT[location>>3] |= ((uint64)data[n]) << ((location++ & 7)<<3);
#elif KECCAK_VERSION_BITS==32
		INOUT[location>>2] |= ((uint32)data[n]) << ((location++ & 3)<<3);
#elif KECCAK_VERSION_BITS==8
		INOUT[location++] = data[n];   
#endif
}

void PULL_DATA(uint8 * data, uint8 n, uint8 location)
{ 	while(n--)
#if KECCAK_VERSION_BITS==64
		data[n] = (uint8)(INOUT[location>>3] >> ((location++ & 7)<<3));
#elif KECCAK_VERSION_BITS==32
		data[n] = (uint8)(INOUT[location>>2] >> ((location++ & 3)<<3));
#elif KECCAK_VERSION_BITS==8
		data[n] = INOUT[location++];   
#endif
}


void TUAK_Main		(	uint8 instance,		
								uint8 *rand,			
								uint8 *amf,			
								uint8 *sqn,			
								uint8 *key				
							)
{ 	uint8 i, TOPC[32];
	TUAK_ComputeTOPC(key, TOPC);				
	memset((uint8*)INOUT	, 0, 200);			

	PUSH_DATA(TOPC		, 32,  0);			
	PUSH_DATA(&instance  , 1 , 32);			
	PUSH_DATA(ALGONAME   , 7 , 33);			
	PUSH_DATA(rand       , 16, 40);			
	if(amf) PUSH_DATA(amf, 2 , 56);			
	if(sqn) PUSH_DATA(sqn, 6 , 58);			
	PUSH_DATA(key, (instance & 1)?32:16, 64); 	

	TUAK_ADD_PADDING();						

	for(i=0; i<KeccakIterations; ++i)
		KECCAK_F(INOUT);
}


void TUAK_ComputeTOPC(	uint8 *key,			
									uint8 *TOPC			
								)
{ 	uint8 i, inst = KEY_sz>>5;
	memset(INOUT, 0, 200);
	PUSH_DATA(TOP      , 32, 0 );					
	PUSH_DATA(&inst    , 1 , 32);					
	PUSH_DATA(ALGONAME , 7 , 33);					
	PUSH_DATA(key  , KEY_sz, 64);					
	TUAK_ADD_PADDING();									

	for(i=0; i<KeccakIterations; ++i)
		KECCAK_F(INOUT);

	PULL_DATA(TOPC, 32, 0);							
}

void TUAK_f1			(	uint8 *key,				
								uint8 *rand,				
								uint8 *sqn,				
								uint8 *amf,				
								uint8 *mac					
							)
{ 	TUAK_Main( (KEY_sz>>5) | MAC_sz, rand, amf, sqn, key);
	PULL_DATA(mac, MAC_sz, 0);	
}

void TUAK_f2345		(	uint8 *key,				
								uint8 *rand,				
								uint8 *res,				
								uint8 *ck,					
								uint8 *ik,					
								uint8 *ak					
							)
{ 	TUAK_Main( (KEY_sz>>5) | ((IK_sz>>4)&0x02) | ((CK_sz>>3)&0x04) 
  | (RES_sz&0x38) | 0x40, rand, 0, 0, key);
	PULL_DATA(res, RES_sz, 0 );
	PULL_DATA(ck , CK_sz , 32);
	PULL_DATA(ik , IK_sz , 64);
	PULL_DATA(ak , 6     , 96);
}

void TUAK_f1s		(	uint8 *key,					
							uint8 *rand,					
							uint8 *sqn,					
							uint8 *amf,					
							uint8 *mac						
						)
{ 	TUAK_Main( (KEY_sz>>5) | MAC_sz | 0x80, rand, amf, sqn, key);
	PULL_DATA(mac, MAC_sz, 0);
}

void TUAK_f5s		(	uint8 *key,					
							uint8 *rand,					
							uint8 *ak						
						)
{ 	TUAK_Main( (KEY_sz>>5) | 0xc0, rand, 0, 0, key);
	PULL_DATA(ak, 6, 96);
}


typedef unsigned char			uint8;
typedef unsigned long			uint32;
typedef unsigned long long	uint64;

const uint8 Rho[25]		= { 0,1,62,28,27,36,44,6,55,20,3,10,43,25,39,41,45,
   15,21,8,18,2,61,56,14};

const uint8 Pi[25]		= { 0,6,12,18,24,3,9,10,16,22,1,7,13,19,20,4,5,11,17,
   23,2,8,14,15,21};

const uint8 Iota[24]	= { 1,146,218,112,155,33,241,89,138,136,57,42,187,203,
   217,83,82,192,26,106,241,208,33,120};

#define ROTATE64(value, n) \ ((((uint64)(value))<<(n)) | (((uint64)(value))>>(64-(n))))


void Keccak_f_64(uint64 *s)
{ 	uint64 t[5];	
	uint8 i, j, round;
	
	for(round=0; round<24; ++round)
	{ 	
		for(i=0; i<5; ++i)
			t[i] = s[i] ^ s[5+i] ^ s[10+i] ^ s[15+i] ^ s[20+i];
		for(i=0; i<5; ++i, s+=5)
		{ 	s[0] ^= t[4] ^ ROTATE64(t[1], 1);
			s[1] ^= t[0] ^ ROTATE64(t[2], 1);
			s[2] ^= t[1] ^ ROTATE64(t[3], 1);
			s[3] ^= t[2] ^ ROTATE64(t[4], 1);
			s[4] ^= t[3] ^ ROTATE64(t[0], 1);
		}
		s -= 25;

		
		for(i=1; i<25; ++i)
			s[i] = ROTATE64(s[i], Rho[i]);

		
		for(t[1] = s[i=1]; (j=Pi[i]) > 1; s[i]=s[j], i=j);
		s[i] = t[1];

		
		for(i=0; i<5; ++i, s += 5)
		{ 	t[0] = (~s[1]) & s[2];
			t[1] = (~s[2]) & s[3];
			t[2] = (~s[3]) & s[4];
			t[3] = (~s[4]) & s[0];
			t[4] = (~s[0]) & s[1];
			for(j=0; j<5; ++j) s[j] ^= t[j];
		}
		s -= 25;

		
		t[0] = Iota[round];
		*s ^= (t[0] | (t[0]<<11) | (t[0]<<26) | (t[0]<<57)) 
& 0x800000008000808BULL; 
	}
}



void Keccak_f_8(uint8 s[200])
{ 	uint8 t[40], i, j, k, round;

	for(round=0; round<24; ++round)
	{ 	
		for(i=0; i<40; ++i)
			t[i]=s[i]^s[40+i]^s[80+i]^s[120+i]^s[160+i];
		for(i=0; i<200; i+=8)
			for(j = (i+32)%40, k=0; k<8; ++k)
				s[i+k] ^= t[j+k];
		for(i=0; i<40; t[i] = (t[i]<<1)|j, i+=8)
			for(j = t[i+7]>>7, k=7; k; --k)
				t[i+k] = (t[i+k]<<1)|(t[i+k-1]>>7);
		for(i=0; i<200; i+=8)
			for(j = (i+8)%40, k=0; k<8; ++k)
				s[i+k] ^= t[j+k];

		
		for(i=8; i<200; i+=8)
		{ 	for(j = Rho[i>>3]>>3, k=0; k<8; ++k) 	
				t[(k+j)&7] = s[i+k];	
			for(j = Rho[i>>3]&7, k=7; k; --k) 	   
				s[i+k] = (t[k]<<j) | (t[k-1]>>(8-j));
			s[i] = (t[0]<<j) | (t[7]>>(8-j));
		}

		
		for(k=8; k<16; ++k) t[k] = s[k];		
		for(i=1; (j=Pi[i])>1; i=j)
			for(k=0; k<8; ++k)						
				s[(i<<3)|k] = s[(j<<3)|k];
		for(k=0; k<8; ++k)							
			s[(i<<3)|k] = t[k+8];

		
		for(i=0; i<200; i+=40)
		{ 	for(j=0; j<40; ++j)
				t[j]=(~s[i+(j+8)%40]) & s[i+(j+16)%40];
			for(j=0; j<40; ++j)	s[i+j]^=t[j];
		}
		
		
		k = Iota[round];			
		s[0] ^= k & 0x8B;			
		s[1] ^= (k<<3)&0x80;		
		s[3] ^= (k<<2)&0x80;		
		s[7] ^= (k<<1)&0x80;		

	} 
}


void Keccak_f_32(uint32 *s)
{ 	uint32 t[10];
	uint8 i, j, round, k;
	
	for(round=0; round<24; ++round)
	{ 	
		for(i=0; i<10; ++i)
			t[i] = s[i] ^ s[10+i] ^ s[20+i] ^ s[30+i] ^ s[40+i];
		for(i=0; i<5; ++i)
			for(j=8, k=2; ; j%=10, k=(k+2)%10)
			{ 	*s++ ^= t[j++] ^ ((t[k]<<1)|(t[k+1]>>31));
				*s++ ^= t[j++] ^ ((t[k+1]<<1)|(t[k]>>31));
				if(j==8) break;
			}
		s -= 50;

		
		for(i=2; i<50; i+=2)
		{ 	k = Rho[i>>1] & 0x1f;
			t[0] = (s[i+1] << k) | (s[i] >> (32-k));
			t[1] = (s[i] << k) | (s[i+1] >> (32-k));
			k = Rho[i>>1] >> 5;
			s[i] = t[1-k], s[i+1] = t[k];
		}

		
		for(i=2, t[0]=s[2], t[1]=s[3]; (j=(Pi[i>>1]<<1))>2; i=j)
			s[i]=s[j], s[i+1]=s[j+1];
		s[i]=t[0], s[i+1]=t[1];

		
		for(i=0; i<5; ++i, s+=10)
		{ 	for(j=0; j<10; ++j)
				t[j] = (~s[(j+2)%10]) & s[(j+4)%10];
			for(j=0; j<10; ++j) 
				s[j] ^= t[j];
		}
		s -= 50;

		
		t[0] = Iota[round];
		s[0] ^= (t[0] | (t[0]<<11) | (t[0]<<26)) & 0x8000808B; 
		s[1] ^= (t[0]<<25) & 0x80000000;
	}
}

算法原理参考3GPP文档(传送门)

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服