C语言伽罗华域乘法,伽罗瓦域上的乘法

一、前言

伽罗瓦域上的乘法在包括加/解密编码和存储编码中经常使用,常见的AES 和Reed-Solomon 编码就使用了伽罗瓦域GF(28) 中的运算。以2 或者2w 形式的伽罗瓦域来说,加减法都是异或运算,乘法相对较复杂一些,本文就GF(2w) 上有限域的乘法运算和优化进行分析。现代计算机是为二进制普通运算所设计,对伽罗瓦域计算最多仅有指令集上的优化,而且仅限于某些处理器,因此在更高层次上优化伽罗瓦域上的乘法显得尤为重要。

二、本原多项式

域中不可约多项式(primitive polynomial)是不能够进行因子分解的多项式,本原多项式是一种特殊的不可约多项式。当一个域上的本原多项式确定了,这个域上的运算也就确定了,本原多项式一般通过查表可得,同一个域往往有多个本原多项式。通过将域中的元素化为多项式的形式,可以将域上的乘法运算转化为普通的多项式乘法模以本原多项式的计算。比如g(x) = x3+x+1 是GF(23)上的本原多项式,那么GF(23) 域上的元素3*7 可以转化为多项式乘法:

3*7(in GF(23)) → (x+1)*(x2+x+1) mod g(x) = x3+1 mod x3+x+1 = x → 3*7 = 2 (in GF(23))

需要注意的是,系数为2 的整数倍会被约去。

三、乘二运算

无论是普通计算还是伽罗瓦域上运算,乘二计算是一种非常特殊的运算。普通计算在计算机上通过向高位的移位计算即可实现,伽罗瓦域上乘二也不复杂,一次移位和一次异或即可,并且2 是GF(28) 中的生成元。从多项式的角度来看,伽罗瓦域上乘二对应的是一个多项式乘以x,如果这个多项式最高指数没有超过本原多项式最高指数,那么相当于一次普通计算的乘二计算,如果结果最高指数等于本原多项式最高指数,那么需要将除去本原多项式最高项的其他项和结果进行异或,在硬件中是这样实现的(g(x) = x8+x4+x3+x2+1):

x7  ← x6 ← x5  ← x4 ← x3 ← x2  ← x1  ← x0

↓_____________↑___↑___↑_________↑

这里x0到x7 分别代表域中一个数的比特位,每次乘二除最高位不移位,其余各位向高位移一位,最高位和指定位进行异或(由本原多项式决定)。不难知道最高位异或的那几位对应着本原多项式系数为1 的几项。

用C 语言可以写成:

1: uint8_t c, cc;

2: cc = (c<<1)^((c&0x80)?0x1d:0)

c&0x80 可以判断数c 最高位是否为1,如果为1 则异或ox1d。

四、一个例子

本节通过一个例子来看看在有限域内做乘法有哪些方法,以GF(28) (g(x) = x8+x4+x3+x2+1)上15*15 为例:

4.1 多项式乘法

15*15 写成多项式乘法的形式:

(x3+x2+1)*(x3+x2+1) mod g(x)

=x6+x4+x2+1

x6+x4+x2+1 化成二进制表示形式1010101,即为1+4+16+64 = 85 。

4.2 移位乘法

15 写成二进制表示1111,15*15 = (1111*1111) 为

1 1 1 1

×       1 1 1 1

—————-

1 1 1 1

1 1 1 1 0

1 1 1 1 0 0

1 1 1 1 0 0 0

——————

=   1 0 1 0 1 0 1     → 1+ 4+16+64=85

4.3 乘二乘法

15 写成生成元指数和异或的形式 23 + 22 + 2 + 1,那么:

15*15 = 15*(23 + 22 + 2 + 1)

= 2*(2*(2*15 + 15) + 15) + 15

计算过程如下:

有限域内数                                          操作                                         二进制值                        十进制值

0                                                                                               0 0 0 0 0 0 0 0                        0

15                                                                                             0 0 0 0 1 1 1 1                       15

2*15                                                移位                                   0 0 0 1 1 1 1 0                       30

2*15+15                                          异或                                   0 0 0 1 0 0 0 1                       17

2*(2*15+15)                                    移位                                   0 0 1 0 0 0 1 0                       34

2*(2*15+15)+15                              异或                                   0 0 1 0 1 1 0 1                       45

2*(2*(2*15+15)+15)                        移位                                    0 1 0 1 1 0 1 0                       90

2*(2*(2*15+15)+15)+15                  异或                                    0 1 0 1 0 1 0 1                       85

五、伽罗瓦域上乘法的系统优化

本来这篇文章只想写这部分,但为了能够理解这部分内容,才瞎扯了下前四节的基础内容。下面针对真实系统中伽罗瓦域上乘法的实现和优化进行讨论和分析,现有的乘法有乘法表(Multiplication Table)、对数表(Log/AntiLog Table)、移乘(shift multiplication)和裂乘(split multiplication)四种实现方式。伽罗瓦域的大小为GF(2w)。

5.1 乘法表

乘法表是一个二维表,保存的是两个乘数伽罗瓦域上相乘的结果,表的大小为2w· 2w。比如m_table[2w][2w] 即是这样的乘法表,那么当计算a 乘以b 时,查表m_table[a][b] 即可。这样实现方式最简单,只需要一次查表操作(LOOK)即可;缺点就是当w 较大时,内存使用量大,当w = 8和 16 时,分别要使用64KB 和8GB 内存,因此GF(28)上乘法常用乘法表实现。

5.2 对数表

伽罗瓦域GF(2w) 的生成元g 指的是g0 g1……g2^w-2 都是域上不重复的元素,生成元的周期是域的大小减一(去掉零元素)。那么Log 表建立的是元素a 与以生成元为底的对数log a 的映射,iLog 表建立元素a 与其反对数antiLog a 的映射。那么乘法可以写成对数、反对数和异或的形式:

x·y = iLog(Log x·y) = iLog(Log x +Log y)

x·y = Log(iLog x·y) = Log(iLog x +iLog y)

这样需要保存2w大小的对数表和反对数表,每次计算需要三次查表(LOOKUP)和一次异或(AND/XOR)。内存的使用量也大大降低,当w = 8、16 和32  时,分别要使用0.5KB、256KB 和32 GB。不难看出w=32 时,对于一般的机器内存还是难以接受的。

5.3 移乘

移位乘法是这四种方法中唯一一个不需要保存表的方法,而是采用了上节谈到的乘二乘法的方法。以x 乘以y 为例,首先计算出y乘2i (i = 1~w-1)的结果,然后将x化为二进制形式,分别取出二进制中为1 的位置p 对应的值y*2p 进行异或得到最终结果。以GF(28) (g(x) = x8+x4+x3+x2+1)上15*85 为例,首先需要计算出15*2、15*22、……15*27的值,分别表示为a1-a7,a0 = 15,85 二进制表示形式为01010101,那么只需要将有1 位置的0、2、4、6 对应的a0、a2、a4、a6 异或即得到结果,原理如下:

15*85 = 15*(26 + 24 + 22 +20) = 15*26 + 15*24 + 15*22 + 15*20  = a0 + a2 + a4 + a6

这种方法的优势就在于内存实用量少。缺点是运算较为复杂,需要w 次乘二操作,w 次判断和少于w 次的异或操作。 用伪代码表示:

1: galois_shift_multiply(int x, int y, int w):

2: for i = 0 to w-1:

3: yy[i] = y*(2^i)

4: for j = 0 to w-1:

5: if(((1<

6: prod = prod^yy[j]

5.4 裂乘

了解上面了三种方法,可以看出前两种方法占用内存较多,步骤少,实现速度快,后一种方法,步骤较多,但节省内存,权衡两种方法的优缺点,裂乘方法诞生了。裂乘的思路是保存乘法表的一部分而不是全部,不能用乘法表直接得到结果的,通过移位到乘法表范围内后再查表得到结果。

以GF(232) 为例,x、y 分别是域内元素(uint32_t 类型),每个元素的高八位、低八位和中间两个八位数表示,那么x 和y 可以写成如下形式:

x = x0+ 28·x1 + 22*8·x2 + 23*8·x3

y = y0 + 28·y1 + 22*8·y2 + 23*8·y3

x0、x1、x2 和x3分别是x 按八比特位分割得到的四个uint8_t 类型数据。那么x*y 化为:

x*y = ( x0 + 28·x1 + 22*8·x2 + 23*8·x3 )*(y0 + 28·y1 + 22*8·y2 + 23*8·y3 )

= x0y0

+ 28·(x0y1 + x1y0)

+ 22*8·(x0y2 + x1y1+ x2y0)

+ 23*8·(x0y3 + x1y2 + x2y1 + x3y0)

+ 24*8·(x1y3 + x2y2+ x3y1)

+ 25*8·(x2y3 + x3y2)

+ 26*8·x3y3

结果共计7 项,各项系数分别为1、28、22*8、23*8、24*8、25*8和26*8,设α 是uint32_t 类型数中只有低八位有值的任意数字,那么根据x*y 可以归结为α * α 、α * (α<<8) 、 α * (α<<16) 、α * (α<<24) 、(α<<8) * (α<<24) 、(α<<16) * (α<<24) 和 (α<<8) * (α<<24) 七种运算。每种运算用一个乘法表表示,每个乘法表为28*28*4 Bytes 大小。下面是Jerasure 库中生成这七个表的C 语言函数:

1: int galois_create_split_w8_tables()

2: {

3: int p1, p2, i, j, p1elt, p2elt, index, ishift, jshift, *table;

4:

5: for (i = 0; i < 7; i++) {

6: galois_split_w8[i] = new int [( 1 << 16 )];

7: }

8:

9: for (i = 0; i < 4; i += 3) {

10: ishift = i * 8;

11: for (j = ((i == 0) ? 0 : 1) ; j < 4; j++) {

12: jshift = j * 8;

13: table = galois_split_w8[i+j];

14: index = 0;

15: for (p1 = 0; p1 < 256; p1++) {

16: p1elt = (p1 << ishift);

17: for (p2 = 0; p2 < 256; p2++) {

18: p2elt = (p2 << jshift);

19: table[index] = galois_shift_multiply(p1elt, p2elt, 32);

20: index++;

21: }

22: }

23: }

24: }

25: return 0;

26: }

相应的乘法函数为:

1: int galois_split_w8_multiply(int x, int y)

2: {

3: int i, j, a, b, accumulator, i8, j8;

4:

5: accumulator = 0;

6:

7: i8 = 0;

8: for (i = 0; i < 4; i++) {

9: a = (((x >> i8) & 255) << 8);

10: j8 = 0;

11: for (j = 0; j < 4; j++) {

12: b = ((y >> j8) & 255);

13: accumulator ^= galois_split_w8[i+j][a|b];

14: j8 += 8;

15: }

16: i8 += 8;

17: }

18: return accumulator;

19: }

当w=32,表大小分为28*28*4 Bytes ,7张表总计使用内存1.792MB。每次乘法需要6次移位,16次查表。

六、总结

伽罗瓦域上乘法步骤越简单,速度也就越快。第五节中介绍了系统实现伽罗瓦域上的四种算法,一些文献也还介绍了许多其他算法,往往是以上几种算法的变形。通常内存占用小的往往速度越慢,占用内存大的速度快。现实中采用合理的算法达到时间和空间使用率的权衡。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/565292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

主成分分析(PCA)及其可视化——python

可以看看这个哦python入门&#xff1a;Anaconda和Jupyter notebook的安装与使用_菜菜笨小孩的博客-CSDN博客 如果你学会了python 可以看看matlab的哦 主成分分析&#xff08;PCA&#xff09;及其可视化——matlab_菜菜笨小孩的博客-CSDN博客 目录 一、主成分分析的原理 二…

Emulator: PANIC: Cannot find AVD system path. Please define ANDROID_SDK_ROOT

我们安装完毕Android Studio之后&#xff0c;创建第一个项目&#xff0c;我们想要使用模拟器进行运行&#xff0c;但是当我们启动模拟器的时候却发现无法启动&#xff0c;而且出现了错误信息。 首先我们要知道错误信息是什么&#xff1f; 提示信息的意思是说“avd系统路径找不…

c语言结构体多门成绩排序,c语言结构体按学号排序求大神帮忙改一下吧

struct record{char code[LEN1]; /* 学号 */char name[LEN1]; /* 姓名 */int age; /* 年龄 */char sex[3]; /* 性别 */char time[LEN1]; /* 出生年月 */char add[30]; /* 家庭地址 */char tel[LEN1]; /* 电话号码 */char mail[30]; /* 电子邮件地址 */}stu[N];int k1,n,m; /* 定…

多元线性回归模型-数学建模类-matlab详解

如果本文有点小难理解的话&#xff0c;可以看看我之前的基础线性规划啥的&#xff0c;有lingo&#xff0c;matlab还有python 就不给大家放链接了&#xff0c;想看的话&#xff0c;点击头像即可&#xff01;&#xff01; 文章目录 &#xff08;1&#xff09;一元线性回归之旧…

Session 'app': Installation did not succeed.The application could not be installed: INSTALL FAILED I

在Android Studio中使用模拟器进行调试的时候&#xff0c;会出现错误信息无法进行模拟器调试 错误信息 Session app: Installation did not succeed.The application could not be installed: INSTALL FAILED INSUFFICIENT STORAGE Retry要想解决这个问题&#xff0c;我们首先…

c语言音像店程序,音像店管理程序_C 课程设计.pdf

课 程 设 计 报 告课程名称 C 语言课程设计课题名称 音像店管理程序专 业 信息安全班 级 信安1501学 号 1151290113姓 名 李浩东指导教师 姜力争2016 年 1 月 1 日 课题设计内容与主要功能音像店管理程序设计一个利用文件处理形式实现音像店基本功能的程序&#xff0c;具有增…

手把手教你爬虫requests实战演练——python篇

文章目录 一、前言 二、实战 1&#xff09;获取百度网页并打印 2&#xff09;获取帅哥图片并下载到本地 4) 获取美女视频并下载到本地 5&#xff09;搜狗关键词搜索爬取 6&#xff09;爬取百度翻译 7&#xff09;爬取豆瓣电影榜单 8&#xff09;JK妹子爬取 总结&#xff…

Android studio 3.x 安装genymotion插件

在日常的Android开发中&#xff0c;模拟器是必不可少的&#xff0c;下面就给大家讲解一下如何在Android studio 3.x 安装genymotion插件。 对于Android studio 3.x之前的版本&#xff0c;可以直接在插件那里在线安装genymotion插件。 Android studio 3.0版本之后就搜索不到了…

给定4个数字组合的C语言算法,leetcode 454. 四数相加 II c语言

如题&#xff1a;给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) &#xff0c;使得 A[i] B[j] C[k] D[l] 0。为了使问题简单化&#xff0c;所有的 A, B, C, D 具有相同的长度 N&#xff0c;且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - …

图片弹框

用js实现图片弹框的特效。 效果展示 代码展示 html内容 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title></title></head><body><img id"myImg" src"img/c_7…

最短路径和距离及可视化——matlab

文章目录 一、前言 二、最短路线 2.1 教程 2.1.1 sparse创建稀疏矩阵 2.1.2 有向图最短路径&#xff08;1&#xff09; 2.1.3 有向图最短路径&#xff08;2&#xff09; 2.1.4 无向图最短路径&#xff08;1&#xff09; 2.1.5无向图最短路径&#xff08;2&#xff09; …

c语言备忘录算法矩阵链乘,矩阵链乘法(备忘录法)

/** fileMemoMatrixchain.cpp* briefa solution of martrix chain with memorized way.* author/Univ.taoxiaoxiao/XMU* versionv1.0* date11-3-2013*///实例 A1-A6&#xff1a;30X35 35X15 15X5 5X10 10X20 20X25#include #include using namespace std;#define N 6#define IN…

没有bug队——加贝——Python 练习实例 1,2

目录 1.题目&#xff1a; 2.题目&#xff1a; 1.题目&#xff1a; 有四个数字&#xff1a;1、2、3、4&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;各是多少&#xff1f; 程序分析&#xff1a;可填在百位、十位、个位的数字都是1、2、3、4。组成所有的…

关闭线程 C语言,如何用C语言实现多线程

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼Windows操作系统&#xff0c;C语言实现多线程&#xff1a;#include #include DWORD APIENTRY ThreadOne ( LPVOID threadArg ){printf ( "线程开始啦&#xff0c;参数是&#xff1a;%s\n" , (char *)threadArg );return …

【OpenCV 例程300篇】250. 梯度算子的传递函数

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程300篇】250. 梯度算子的传递函数 1. 空间卷积与频域滤波 空间域图像滤波是图像与滤波器核的卷积&#xff0c;而空间卷积的傅里叶变换是频率域中相应变换的乘积&#xff0c;因此频率域图像滤波是频率域滤波器…

JS贪吃蛇

Js实现贪吃蛇小游戏。 程序解析&#xff1a; 画表格&#xff0c;画出相对应大小的表格速度的快慢调节随机生成事物的位置使用键盘的方向键控制移动位置当贪吃蛇碰到四周游戏结束&#xff0c;弹框显示效果演示 代码演示 html内容 <!DOCTYPE html> <html><he…

没有bug队——加贝——Python 练习实例 3,4

3.题目&#xff1a; 一个整数&#xff0c;它加上100后是一个完全平方数&#xff0c;再加上168又是一个完全平方数&#xff0c;请问该数是多少&#xff1f; 程序分析&#xff1a; 假设该数为 x。 1、则&#xff1a;x 100 n2, x 100 168 m2 2、计算等式&#xff1a;m2 …

lcd4linux 1602,详解一种LCD1602 的4线接法

描述虽然LCD1602的显示屏幕与显示字符都较小&#xff0c;实用性并不强&#xff0c;但是在一般的教学实验中&#xff0c;它仍不失为一个常用的输出显示设备。LCD1602与单片机连接的线路共有11条&#xff0c;其中有8条数据线&#xff0c;3条控制线。如果把它们都连接上&#xff0…

没有bug队——加贝——Python 练习实例 5,6

目录 5.题目&#xff1a; 6.题目&#xff1a; 5.题目&#xff1a; 输入三个整数x,y,z&#xff0c;请把这三个数由小到大输出。 程序分析&#xff1a;我们想办法把最小的数放到x上&#xff0c;先将x与y进行比较&#xff0c;如果x>y则将x与y的值进行交换&#xff0c;然后再…

android launcher 字体大小,Android6.0 Launcher3 修改app字体大小

在原生的Android6.0中&#xff0c;在修改了系统字体大小后&#xff0c;Launcher 3上的app字体大小没有改变&#xff0c;下面方法可以解决&#xff1a;--- a/packages/apps/Launcher3/src/com/android/launcher3/BubbleTextView.java b/packages/apps/Launcher3/src/com/android…