用libtommath实现RSA算法

简介: RSA算法描述:1) 选择两个大素数 p、q, 计算 n = p*q;2) 产生 e, d 使:    e*d = 1mod(p-1)(q-1)    e 与 (p-1)(q-1) 互质[公钥] e、n[私钥] d、n3) 加密:    c = m^d mod n4) 解密:    m = c^e mod n--------------------------------------------------------------------------------------libtommath是一个大数算法库。

RSA算法描述:

1) 选择两个大素数 p、q, 计算 n = p*q;

2) 产生 e, d 使:

    e*d = 1mod(p-1)(q-1)

    e 与 (p-1)(q-1) 互质

[公钥] e、n

[私钥] d、n

3) 加密:

    c = m^d mod n

4) 解密:

    m = c^e mod n

--------------------------------------------------------------------------------------

libtommath是一个大数算法库。以下的代码是用这个库中的函数实现的,相当简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <tommath.h>
typedef  struct  {
     int  bits;           /* bits in key */
     mp_int n;           /* modulus */
     mp_int e;           /* public exponent */
     mp_int d;           /* private exponent */
}rsa_key;
int  rsa_rng(unsigned char  *dst, int  len, void  *dat)
{
     int  x;
     for  (x = 0; x < len; x++)   dst[x] = rand () & 0xFF;
     return  len;
}
int  rsa_preme_random( mp_int *a, int  bits )
{
     int  err = mp_prime_random_ex( a, 8, bits, LTM_PRIME_2MSB_ON|LTM_PRIME_SAFE, rsa_rng, NULL );
     if  (err != MP_OKAY) {
         return  -1;
     }
     return  0;
}
int  rsa_gen_key( rsa_key *key, int  bits )
{
     mp_int p, q;
     mp_int sp, sq;
     mp_int n, m;
     mp_int e, d;
     mp_int t;
     //init mp_ints
     mp_init( &p );  mp_init( &q );  mp_init( &sp ); mp_init( &sq );
     mp_init( &n );  mp_init( &m );  mp_init( &e );  mp_init( &d );  mp_init( &t );
     //genarate p & q
     rsa_preme_random( &p, bits/2 );
     rsa_preme_random( &q, bits/2 );
     //make n & m
     mp_sub_d( &p, 1, &sp );
     mp_sub_d( &q, 1, &sq );
     mp_mul( &p, &q, &n );
     mp_mul( &sp, &sq, &m );
     
     //make e & d
     mp_set( &e, 127 );
     retry_e:
     mp_gcd( &e, &m, &t );
     if ( ( mp_cmp_d(&t, 1) ) > 0 ){
         mp_add_d( &e, 2, &e );
         goto  retry_e;
     }
     mp_invmod( &e, &m, &d );
     //copy n d e to key struct
     mp_init( &key->n );
     mp_init( &key->d );
     mp_init( &key->e );
     key->bits = bits;
     mp_copy( &n, &key->n );
     mp_copy( &d, &key->d );
     mp_copy( &e, &key->e );
     
     mp_clear( &p ); mp_clear( &q ); mp_clear( &sp );mp_clear( &sq );
     mp_clear( &n ); mp_clear( &m ); mp_clear( &e ); mp_clear( &d ); mp_clear( &t );
     return  0;
}
/*set rsa key by string */
int  rsa_set_key( rsa_key *key, char  *sn, char  *se, char  *sd, int  bits, int  radix )
{
     key->bits = bits;
     mp_init( &key->n );
     mp_init( &key->d );
     mp_init( &key->e );
     if ( sn )    mp_read_radix( &key->n, sn, radix );
     if ( se )    mp_read_radix( &key->e, se, radix );
     if ( sd )    mp_read_radix( &key->d, sd, radix );
     
     return  0;
}
/*encrypt by private key */
int  rsa_encrypt(mp_int *c, mp_int *m, rsa_key *key)
{
     mp_exptmod( c, &key->d, &key->n, m );
     return  0;
}
/*decrypt by public key */
int  rsa_decrypt(mp_int *m, mp_int *c, rsa_key *key)
{
     mp_exptmod( m, &key->e, &key->n, c );
     return  0;
}
int  rsa_test()
{
     mp_int  c, m;
     rsa_key key;
     char  sn[] = "BB7F51983FD8707FD6227C23DEF5D5377A5A737CEF3C5252E578EFE136DF87B50473F9341F1640C8D258034E14C16993FCE6C6B8C3CEEB65FC8FBCD8EB77B3B05AC7C4D09E0FA1BA2EFE87D3184DB6718AE41A7CAD89B8DCE0FE80CEB523D5D647F9DB58A31D2E71AC677E67FA6E75820736C9893761EE4ACD11F31DBDC349EF" ;
     char  se[] = "010001" ;
     char  sm[] = "AA7B0BF4AAE8B7C2ECC485ACFA57770E50BB9207233E4278654717E470691981C187F81FFC3B90895063EF98C0D86B5297B655399309E6699FEE2270B0F3431B5ABAD7E516261926C35BF6BBFEFB49366EBE96DC510E9CBD915337E8188D517D15DCF90298C40233EEEAFD5A9459F5D3410E6B89B44DF6E818FA3594EF935534" ;
     char  sc[1024];
     mp_init( &c );
     mp_init( &m );
     rsa_set_key( &key, sn, se, NULL, 128, 16 );
     mp_read_radix( &m, sm, 16 );
     rsa_decrypt( &m, &c, &key );
     mp_toradix( &c, sc, 16 );
     printf ( "%s\n" , sc);
     return  0;
}
相关文章
|
11月前
|
存储 关系型数据库 MySQL
mysql8.0中的mysql.ibd
`mysql.ibd`文件在MySQL 8.0中扮演着重要角色,负责存储InnoDB表的数据和索引。通过了解其结构和管理方法,可以有效维护数据库的性能和数据完整性。希望本文对 `mysql.ibd`文件的深入解析能帮助您更好地理解和管理MySQL数据库。
700 1
|
12月前
|
机器学习/深度学习 编解码 数据可视化
转置卷积-清晰易懂
转置卷积(Transpose Convolution)是一种用于图像上采样的技术,常用于图像分割、生成对抗网络(GAN)等领域。与传统的上采样方法不同,转置卷积通过学习参数来实现更优的插值效果。本文介绍了转置卷积的背景、应用、与标准卷积的区别以及数学推导,帮助读者深入理解其原理和应用场景。
1026 1
|
12月前
|
搜索推荐 应用服务中间件 PHP
php如何开启COM组件
请注意,上述步骤可能根据您的具体环境(如操作系统版本、PHP版本或服务器类型)有所变化。在操作过程中遇到困难时,建议直接咨询您的托管服务提供商或查阅等专业平台提供的详尽文档与解决方案,以获取个性化的技术支持。
141 1
|
存储 缓存 负载均衡
数据库性能优化(查询优化、索引优化、负载均衡、硬件升级等方面)
数据库性能优化(查询优化、索引优化、负载均衡、硬件升级等方面)
|
缓存 监控 Java
日志服务接入方式之loghub log4j appender
使用Loghub Log4j Appender,您可以控制日志的输出目的地为阿里云日志服务,使用Loghub Log4j Appender的好处 客户端日志不落盘:既数据生产后直接通过网络发往服务端。 对于已经使用log4j记录日志的应用,只需要简单修改配置文件就可以将日志传输到日志服务。 异
12283 0
|
存储 消息中间件 关系型数据库
Kafka端到端审计
概述 Kafka端到端审计是指生产者生产的消息存入至broker,以及消费者从broker中消费消息这个过程之间消息个数及延迟的审计,以此可以检测是否有数据丢失,是否有数据重复以及端到端的延迟等。
1619 0
|
11天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
10天前
|
存储 人工智能 搜索推荐
终身学习型智能体
当前人工智能前沿研究的一个重要方向:构建能够自主学习、调用工具、积累经验的小型智能体(Agent)。 我们可以称这种系统为“终身学习型智能体”或“自适应认知代理”。它的设计理念就是: 不靠庞大的内置知识取胜,而是依靠高效的推理能力 + 动态获取知识的能力 + 经验积累机制。
359 131