任务:
用C/C++实现对GF(2^8)的若干运算功能,包括:加法、乘法、求乘法逆元(给定x,求y,使得x*y == 1 )、求离散对数(即给定一个生成元g,输入x,求y使得g^y == x)。
首先分析一下思路:
加法思路:对每一位进行异或操作
乘法:
①(参照密码编码学与网络安全的书本还原的一个算法)首先计算数组a中的对数组b中每一位的乘法中间结果,然后根据数组b决定用来异或的中间结果,最后得出结果。
②利用无符号字符类型解释整形创建一个过度变量为result,然后根据字符b的最后一位决定结果值,如果b的最后一位是0则result等于上一个循环的result值,若b的最后一位是1,result值等于result异或a。需要做八次循环,每次循环一开始都要判断a是否大于127如果大于127则a需要左移一位并且异或1B,else a只需要左移一位。
乘法逆元思路:
首先规定生成元是3(00000011,当然用其他生成元也可以,随便)然后生成一个以3为生成元的逆元表,然后查询用户输入的x查询到x之后利用255减去x所在位置那个位置的元素即为x的乘法逆元y
离散对数思路:
用户输入生成元与X,多次调用乘法,调用乘法的次数则为所求的离散对数
我大概用到的函数定义(忽略界面函数,输入输出函数等与算法无关的函数):
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
void set_genrator(); //用于开始设置生成元数组
void set_Inverse(); //用于开始设置逆元表
unsigned char GFsum(unsigned char a, unsigned char b); //求和
unsigned char GFmul(unsigned char a, unsigned char b); //乘法
unsigned char inverse(unsigned char b); //乘法逆元
bool judge_genrator(unsigned char a); //判断用户输入的生成元是否为生成元
int logarithm(unsigned char a, unsigned char b); //离散对数
int Genrator[256]; //保存生成元信息
unsigned char Inverse[256]; //保存以3为生成元的逆元表
用于设置生成元数组用来判断用户输入的生成元是否为一个真实的生成元:
void set_genrator(){
memset(Genrator, 0, sizeof(Genrator));
string buf;
int a;
ifstream GEN("一个包含所有生成元的记录文件,可以自己生成也可以网上去找");
while (!GEN.eof()){
GEN >> buf;
a = change_int(buf);
Genrator[a] = 1;
}
GEN.close();
}
生成逆元表
void set_Inverse(){
unsigned char gen = 3;
Inverse[0] = 0;
Inverse[1] = 3;
for (int i = 2; i < 256; i++){
Inverse[i] = GFmul(Inverse[i-1], gen);
}
}