A5/1加密算法介绍及实现

1.算法简介

  A5/1加密算法用于GSM中的数据机密性加密。该算法使用三个线性反馈位移寄存器,记为为X、Y和Z。其中X(x0, x1, …, x18)寄存器有19位,Y寄存器22位,Z寄存器23位。以下不讲原理,只讲密钥流生成算法。

  1. 定义X操作:
      temp = x13 ^ x16 ^ x17 ^ x18
      xi = xi-1 for i = 18, 17, 16, …, 1
      x0 = temp;(简单的说就是左移一位,然后第一位用没左移之前的x13 ^ x16 ^ x17 ^ x18填充,以下类似)
    定义Y操作:
      temp = y20 ^ y21
      yi = yi-1 for i = 21, 20, 19, …, 1
      y0 = temp;
    定义Z操作:
      temp = z7 ^ z20 ^ z21 ^ z22
      zi = zi-1 for i = 22, 21, 20, …, 1
      z0 = temp;
  2. 定义多数投票函数maj(x, y , z):若x、y、z中0的个数比较多,返回0;否则返回1。
  3. 令m = maj(x8, y10, z10),若x8 = m,则执行X操作;若y10 = m,则执行Y操作;若z10 = m,则执行Z操作。
  4. 密钥流位s = x18 ^ y21 ^ z22
  5. 重复上述步骤生成密钥流。

2.简单实现

  一下用C++简单实现了一下,比较简单就不多讲了。

#include 
#include 
#include 
#define _for(i,a,b) for(int i=(a); i<(b); ++i)
#define setbit(x,y)  x|=(1<
#define clrbit(x,y)  x&=~(1<
#define reversebit(x,y)  x^=(1<
#define getbit(x,y)   (x&=(1<
using namespace std;
typedef unsigned char uc;
bool x[19] = {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1};
bool y[22] = {1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1};
bool z[23] = {1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0};
int maj(bool x, bool y, bool z) {
	return x + y + z >= 2;
}
void X(bool x[]) {
	bool temp = x[13] ^ x[16] ^ x[17] ^ x[18];
	for(int i = 18; i >= 1; i--) {
		x[i] = x[i-1];
	}
	x[0] = temp;
}
void Y(bool y[]) {
	bool temp = y[20] ^ y[21];
	for(int i = 21; i >= 1; i--) {
		y[i] = y[i-1];
	}
	y[0] = temp;
}
void Z(bool z[]) {
	bool temp = z[7] ^ z[20] ^ z[21] ^ z[22];
	for(int i = 22; i >= 1; i--) {
		z[i] = z[i-1];
	}
	z[0] = temp;
}
uc* generateSecretKeyStream(int n) {
	bool temp[8]; 
	uc* secretKeyStream = (uc*)malloc(n/8 + 1);
	int cnt = 0, cnt1 = 0;
	_for(i, 0, n) {
		bool m = maj(x[8], y[10], z[10]);
		if(x[8] == m) {
			X(x);
		}
		if(y[10] == m) {
			Y(y);
		}
		if(z[10] == m) {
			Z(z);
		}
		bool s = x[18] ^ y[21] ^ z[22];
		temp[cnt++] = s;
		if(cnt == 8) {
			_for(j, 0, cnt) {
				if(temp[j] == 0) {
					clrbit(secretKeyStream[cnt1], j);
				} else {
					setbit(secretKeyStream[cnt1], j);
				}
			}
			cnt1++;
			cnt = 0;
		}
	}
	_for(j, 0, cnt) {
		if(temp[j] == 0) {
			clrbit(secretKeyStream[cnt1], j);
		} else {
			setbit(secretKeyStream[cnt1], j);
		}
	}
	return secretKeyStream;
}
int getFileSize(FILE *fp) {
	fseek(fp, 0L, SEEK_END);
    int size = ftell(fp);
    fseek(fp, 0L, 0);
    return size;
} 
uc* readFromFile(FILE *fp, int size) {
	uc *buffer = (uc *)malloc(sizeof(uc) * size);
	fread(buffer, size, 1, fp);
	return buffer;
}
void  encrypt(char* fileName) {
	FILE* fp = fopen(fileName, "rb");
	int fileSize = getFileSize(fp);
    uc *buffer = readFromFile(fp, fileSize);
    uc* secretKeyStream = generateSecretKeyStream(fileSize * 8);
    _for(i, 0, fileSize) {
    	buffer[i] ^= secretKeyStream[i];
	}
	FILE* fp1 = fopen("secret.a51", "wb");
	fwrite(buffer, fileSize, 1, fp1);
	_for(i, 0, fileSize) {
    	buffer[i] ^= secretKeyStream[i];
	}
	FILE* fp2 = fopen("_secret.a51", "wb");
	fwrite(buffer, fileSize, 1, fp2);
	fclose(fp);
	fclose(fp1);
	fclose(fp2);
	free(buffer);
}
int main(int argc, char const **argv) {
	char fileName[50] = "lenna.bmp";
	encrypt(fileName);
	return 0;
}

你可能感兴趣的:(课程设计,笔记)