1)域的概念
参考《密码编码学与网络安全》这书的有限域一章。形象地说,域有这样一个性质:在加法和乘法上具有封闭性。也就是说对域中的元素进行加法或乘法运算后的结果仍然是域中的元素。有一点要注意,域里面的乘法和加法不一定是我们平常使用的乘法和加法。可以把C语言中的与运算和异或运算分别定义成加法和乘法。但习惯上,仍然使用符号+ 和 * 表示加法和乘法运算。
2) 域中单位元和逆元两个概念
加法和乘法运算都有对应的单位元(这两个单位元一般不同,但都用符号e表示)。单位元就像线性代数的单位矩阵。一个矩阵乘以单位矩阵等于本身。对应地,在域中的单位元有:对于加法单位元,所有元素加上单位元e,等于其本身。对应乘法单位元,所有元素乘上单位e,等于其本身。
逆元就像数学上的倒数,两个元素互为对方的逆元。如果元素a和b互为加法逆元,那么就有 a + b = e。若互为乘法逆元,那么就有a * b = e。如果元素a在域中找不到另外一个元素b,使得a+b=e(a*b=e),那么a就没有加法(乘法)逆元。
逆元有什么用呢?其实逆元是用于除法运算的。小学的时候老师都会教:除于一个分数就等于乘以该分数的倒数(分数的倒数就是该分数的乘法逆元)。所以要想除于某个数,可以乘以该数的逆元。
一个集合有加法单位元和乘法单位元,以及每一个元素都对应有加法逆元和乘法逆元,是成为域的必要条件。需要注意:即使集合里面有元素0,并且0没有对应的乘法逆元,那么该集合也可能是一个域。因为并不要求0有乘法逆元。
例子:
一个域的例子就是我们平时熟悉的有理数集合,相应的加法和乘法就是我们平时用的加法和乘法。其中,加法的单位元为0,有理数a的加法逆元就是其相反数。因为a + (-a) = 0(单位元)。乘法的单位元为1,a的乘法逆元是其倒数。因为a * (1/a) = 1。注意这里的元素0并没有乘法逆元。
有理数是整数(正整数、0、负整数)和分数的统称,是整数和分数的集合。一般用黑体字母Q表示。
3)有限域
有限域,是指域中的元素个数是有限的。
4)有限域GF(p):
伽罗华域(Galois Field)
Évariste Galois ,伽罗华(也译作伽瓦罗),法国数学家,群论的创立者。用群论彻底解决了根式求解代数方程的问题,而且由此发展了一整套关于群和域的理论。
在密码学中,有限域GF(p)是一个很重要的域,其中p为素数。简单来说,GF(p)就是 mod p,因为一个数 模p后,结果在[0, p -1]之间,即该域中有p个元素。对于元素a和b,那么(a+b) mod p和(a*b)mod p,其结果都是域中的元素。GF(p)里面的加法和乘法都是平时用的加法和乘法。GF(p)的加法和乘法单位元分别是0和1,元素的加法和乘法逆元都很容易理解和求得,这里就不展开讲了,《密码编码学与网络安全》书中有详讲的。
求乘法逆元的实现代码如下面所示,具体是使用了类似辗转相除法的方法。
//g_prime就是 GF(p)中的p int g_prime = 251; int calculateInverse(int x) { int a1 = 1, a2 = 0, a3 = g_prime; int b1 = 0, b2 = 1, b3 = x; while( 1 ) { if( b3 == 0 ) throw std::logic_error("should not be 0"); if( b3 == 1 ) break; int q = a3 / b3; int t1 = a1 - q*b1, t2 = a2 - q*b2, t3 = a3 - q*b3; a1 = b1; a2 = b2; a3 = b3; b1 = t1; b2 = t2; b3 = t3; } return (b2 + g_prime)%g_prime; }