上周想找一些关于加密算法实现的参考资料,在《BigNum Math - Implementing Cryptographic Multiple Precision Arithmetic》这本书里提到了用LibTomMath这么个东西,可以表示大整数以及进行密码学中的一些常用运算,于是下载来试了试。发现里面数据结构设计就相当不错,也包含了所有需要的运算,说明文档也还不错。
1. 生成静态库文件
无论是说明文档(bn.pdf)还是网络上的资料,都说到了需要生成静态库,然后在工程中加入这个静态库方可使用LibTomMath的高精度整数和运算。vs2008中创建LibTomMath静态库的步骤:
1) 下载LibTomMath的压缩包,解压;
2)vs2008中新建项目->win32->静态库、取消预编译头;
3)工程中加入所有.c和.h文件;
4)工具->选项->项目和解决方案->VC++目录->包含文件,加入LibTomMath源文件所在目录;
5)编译工程即可生成.lib文件。
bn.pdf里面还讲了linux下的使用方法,我就没有试过了。
2.使用静态库文件
把生成的.lib文件拷到其他工程目录下,项目->属性->配置属性->链接器->输入->附加依赖性,加入该.lib文件。还要在工程的代码中加入#include<tommath.h>,这样就可以用了。
3.LibTomMath的大整数数据结构mp_int
大整数的存储方式相当不错,通过整形字符串拼接表示。mp_digit就是unsigned long,dp是unsigned long类型的指针,其实更应该是数组,alloc为分配的空间,used为已使用的空间,sign为正负号。假设x= unsigned long最大值+1,一个mp_int类型变量所代表的数字大小为dp[used-1] + dp[used-2]*x^2 + …+ dp[1] *x^(used-2) + dp[0] *x^(used-1),注意big_endian
1 |
typedef struct { |
2 |
int used, alloc, sign; |
3 |
mp_digit *dp; |
4 |
} mp_int; |
4.示例,RSA算法实现,具体某个函数的功能可以查看bn.pdf。里面有段求e的代码比较土,以后改进
01 |
#include<tommath.h> |
02 |
#include<stdio.h> |
03 |
#include<time.h> |
04 |
int rsa_rng(unsigned char *dst, int len, void *dat) |
05 |
{ |
06 |
int x; |
07 |
for (x = 0; x < len; x++) |
08 |
dst[x] = rand () & 0xFF; |
09 |
return len; |
10 |
} |
11 |
|
12 |
int main() |
13 |
{ |
14 |
mp_int p,q,n,φ,e,t,d,m,c; |
15 |
mp_init( &p ); |
16 |
mp_init( &q ); |
17 |
mp_init( &n ); |
18 |
mp_init( &φ ); |
19 |
mp_init( &e ); |
20 |
mp_init( &t ); |
21 |
mp_init( &d ); |
22 |
mp_init( &m ); |
23 |
mp_init( &c ); |
24 |
|
25 |
//1.Choose two distinct prime numbers p and q (128bits) |
26 |
srand ((unsigned int ) time (NULL)); |
27 |
mp_prime_random_ex( &p, 20, 128, LTM_PRIME_2MSB_ON|LTM_PRIME_SAFE, rsa_rng, NULL ); |
28 |
mp_prime_random_ex( &q, 20, 128, LTM_PRIME_2MSB_ON|LTM_PRIME_SAFE, rsa_rng, NULL ); |
29 |
|
30 |
|
31 |
//2.Compute n = pq |
32 |
mp_mul( &p, &q, &n ); |
33 |
|
34 |
//3.Compute φ(n) = (p − 1)(q − 1) |
35 |
mp_sub_d( &p, 1, & p); |
36 |
mp_sub_d( &q, 1, &q ); |
37 |
mp_mul( &p, &q, &φ ); |
38 |
|
39 |
//4.Choose an integer e such that 1 < e < φ(n) and gcd(e,φ(n)) = 1 |
40 |
mp_set( &e, 127 ); |
41 |
retry_e: |
42 |
mp_gcd( &e, &φ, &t ); |
43 |
if ( ( mp_cmp_d(&t, 1) ) > 0 ){ |
44 |
mp_add_d( &e, 2, &e ); |
45 |
goto retry_e; |
46 |
} |
47 |
//5.Determine de ≡ 1 (mod φ(n)) |
48 |
mp_invmod( &e, &φ, &d ); |
49 |
|
50 |
mp_clear( &p ); |
51 |
mp_clear( &q ); |
52 |
|
53 |
|
54 |
//明文 |
55 |
char str[100] = "AA7B0BF4AAE8B7C2ECC485ACFA5" ; |
56 |
printf ( "明文:%s/n" ,str); |
57 |
|
58 |
//加密, 密文 c = m^e mod n |
59 |
mp_read_radix( &m, str, 16 ); |
60 |
mp_exptmod( &m, &d, &n, &c ); |
61 |
mp_toradix( &c, str, 16 ); |
62 |
printf ( "密文:%s/n" ,str); |
63 |
|
64 |
//解密, 明文 m = c^d mod n |
65 |
mp_exptmod( &c, &e, &n, &m ); |
66 |
mp_toradix( &m, str, 16 ); |
67 |
printf ( "解密:%s/n" ,str); |
68 |
|
69 |
return 0; |
70 |
} |
自来的网络参考资料:
http://hiliang.blog.hexun.com/57837642_d.html
http://www.cnblogs.com/linxr/archive/2010/11/10/1927003.html
原文:http://www.cnblogs.com/todsong/archive/2011/01/17/1937861.html
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。