首页 > 编程语言 >[单片机] rsa2048签名算法

[单片机] rsa2048签名算法

时间:2022-10-31 23:03:00浏览次数:120  
标签:int MAX bn rsa2048 unsigned len char 单片机 算法


RSA-2048具有617个十进制数字,共2048bits。是目前最大的RSA数字,有20万美金的悬赏用于对RSA-2048的因式分解。
RSA-2048:为非对称成加密算法,发送方和接收方均各有一组公钥和私钥key。因存在幂运算,其计算速度远远小于AES-256。可用于对小量数据的加密,如用于对密钥key的加密。是密钥交换协议的重要组成部分。采用公钥进行加密,采用私钥进行解密。
SHA-256:不是加解密算法,是一个安全Hash算法。可用于确认数据的完整性。可称为one way encryption,不存在相应的解密算法。
AES-256:为对称块加密算法,用于消息的加解密。可对大量数据同时进行加解密。计算速度快于RSA。加密和解密使用相同的密钥key。

在文件传输中,为保证数据的完整性和安全性,常将RSA-2048、SHA-256和AES-256组合使用:

1) 生成随机AES-256 key;
2)计算文件明文的SHA-256摘要;
3)使用AES-256对文件进行加密;
4)对加密后的文件进行前置操作:
4.1)用接收方的RSA-2048公钥对AES-256 key进行加密,保证仅有指定的接收方才能恢复相应的AES-256 key;
4.2)SHA-256摘要,接收方可用于判断确认所接收解密的文件是正确的。

性能

openssl speed

Doing md5 for 3s on 16 size blocks: 8369385 md5’s in 2.99s
Doing md5 for 3s on 64 size blocks: 6858297 md5’s in 2.99s
Doing md5 for 3s on 256 size blocks: 4233567 md5’s in 2.98s
Doing md5 for 3s on 1024 size blocks: 1690176 md5’s in 2.99s
Doing md5 for 3s on 8192 size blocks: 249397 md5’s in 2.99s

Doing sha256 for 3s on 16 size blocks: 12672160 sha256’s in 3.00s
Doing sha256 for 3s on 64 size blocks: 7701824 sha256’s in 3.00s
Doing sha256 for 3s on 256 size blocks: 3407309 sha256’s in 2.99s
Doing sha256 for 3s on 1024 size blocks: 1031131 sha256’s in 2.99s
Doing sha256 for 3s on 8192 size blocks: 146562 sha256’s in 3.00s
Doing sha512 for 3s on 16 size blocks: 9915608 sha512’s in 3.00s
Doing sha512 for 3s on 64 size blocks: 9940546 sha512’s in 3.00s
Doing sha512 for 3s on 256 size blocks: 4044246 sha512’s in 2.98s
Doing sha512 for 3s on 1024 size blocks: 1468656 sha512’s in 2.99s
Doing sha512 for 3s on 8192 size blocks: 210842 sha512’s in 2.99s

Doing aes-128 cbc for 3s on 16 size blocks: 24631877 aes-128 cbc’s in 3.00s
Doing aes-128 cbc for 3s on 64 size blocks: 7235641 aes-128 cbc’s in 3.00s
Doing aes-128 cbc for 3s on 256 size blocks: 1872315 aes-128 cbc’s in 3.00s
Doing aes-128 cbc for 3s on 1024 size blocks: 1045226 aes-128 cbc’s in 3.00s
Doing aes-128 cbc for 3s on 8192 size blocks: 130959 aes-128 cbc’s in 2.97s

Doing aes-256 cbc for 3s on 16 size blocks: 18663671 aes-256 cbc’s in 3.00s
Doing aes-256 cbc for 3s on 64 size blocks: 5212481 aes-256 cbc’s in 3.00s
Doing aes-256 cbc for 3s on 256 size blocks: 1337117 aes-256 cbc’s in 2.99s
Doing aes-256 cbc for 3s on 1024 size blocks: 770637 aes-256 cbc’s in 3.00s
Doing aes-256 cbc for 3s on 8192 size blocks: 96435 aes-256 cbc’s in 3.00s

Doing 256 bit ecdh’s for 10s: 139884 256-bit ECDH ops in 10.00s

OpenSSL 1.0.2g 1 Mar 2016
built on: reproducible build, date unspecified
options:bn(64,64) rc4(16x,int) des(idx,cisc,16,int) aes(partial) blowfish(idx)
compiler: cc -I. -I… -I…/include -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,–noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
单位是每秒处理1000字节
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes

md5 44786.01k 146799.67k 363688.98k 578842.88k 683297.73k
hmac(md5) 38496.00k 131939.24k 338350.76k 559279.10k 693459.65k
sha1 54038.55k 173795.26k 427486.55k 683641.51k 869272.23k
rmd160 35412.38k 93993.66k 186110.20k 242997.59k 267111.08k
rc4 556793.34k 672976.85k 586886.49k 561559.21k 555128.15k
des cbc 79033.45k 81625.34k 82675.71k 83066.20k 83050.50k
des ede3 30488.91k 30828.20k 30903.57k 30969.86k 30949.38k
idea cbc 0.00 0.00 0.00 0.00 0.00
seed cbc 86164.67k 88289.69k 88873.64k 89335.81k 89118.04k
rc2 cbc 54197.02k 54979.61k 55342.17k 55942.49k 55943.17k
rc5-32/12 cbc 0.00 0.00 0.00 0.00 0.00
blowfish cbc 134291.30k 143944.43k 145858.65k 145807.73k 144321.19k
cast cbc 123520.78k 133543.98k 136479.40k 137401.69k 135989.93k
aes-128 cbc 131370.01k 154360.34k 159770.88k 356770.47k 361217.55k
aes-192 cbc 114160.41k 125246.85k 133861.80k 302379.35k 307565.91k
aes-256 cbc 99539.58k 111199.59k 114482.26k 263044.10k 263331.84k
camellia-128 cbc 109981.31k 175895.36k 202443.95k 210231.30k 209920.00k
camellia-192 cbc 94226.30k 136981.87k 152009.05k 156580.86k 155953.83k
camellia-256 cbc 93241.68k 136979.37k 150476.71k 156710.91k 158594.39k
sha256 67584.85k 164305.58k 291729.47k 353136.50k 400211.97k
sha512 52883.24k 212064.98k 347425.16k 502977.84k 577664.77k
whirlpool 37039.89k 82968.66k 139697.92k 169980.25k 180753.75k
aes-128 ige 135738.87k 148941.89k 150268.07k 150550.19k 152084.48k
aes-192 ige 116191.06k 125573.18k 126090.24k 127605.42k 127940.41k
aes-256 ige 101339.54k 108715.54k 109148.33k 110122.33k 108896.26k
ghash 587117.89k 2288623.02k 6443817.90k 8714195.29k 9610922.67k
sign verify sign/s verify/s
rsa 512 bits 0.000048s 0.000004s 20689.2 251830.8
rsa 1024 bits 0.000132s 0.000009s 7591.6 114929.3
rsa 2048 bits 0.000591s 0.000026s 1693.4 37923.3
rsa 4096 bits 0.006333s 0.000095s 157.9 10472.9

op      op/s

160 bit ecdh (secp160r1) 0.0003s 2985.3
192 bit ecdh (nistp192) 0.0004s 2510.7
224 bit ecdh (nistp224) 0.0001s 11520.2
256 bit ecdh (nistp256) 0.0001s 13988.4
384 bit ecdh (nistp384) 0.0013s 771.3
521 bit ecdh (nistp521) 0.0004s 2606.4
163 bit ecdh (nistk163) 0.0002s 4220.3
233 bit ecdh (nistk233) 0.0003s 3264.3
283 bit ecdh (nistk283) 0.0005s 1939.0
409 bit ecdh (nistk409) 0.0009s 1162.4
571 bit ecdh (nistk571) 0.0019s 525.6
163 bit ecdh (nistb163) 0.0002s 4053.4
233 bit ecdh (nistb233) 0.0003s 3159.8
283 bit ecdh (nistb283) 0.0005s 1826.0
409 bit ecdh (nistb409) 0.0009s 1097.7
571 bit ecdh (nistb571) 0.0020s 488.1

#include <string.h>

#include "rsa2048.h"
#include "bignum.h"
#include "keys.h"

#define PADDING_SIZE 11
#define KEY_M_BITS 2048

static unsigned char pkcs_block[RSA_MAX_MODULUS_LEN] = {0};
static int status;

static rsa_pk_t pk = {0};
static rsa_sk_t sk = {0};

static void rsa_load_key(rsa_pk_t *public_key, rsa_sk_t *private_key)
{
// copy keys.h message about public key and private key to the flash RAM
public_key->bits = KEY_M_BITS;
memcpy(&public_key->modulus [RSA_MAX_MODULUS_LEN-sizeof(key_m) ], key_m, sizeof(key_m ));
memcpy(&public_key->exponent [RSA_MAX_MODULUS_LEN-sizeof(key_e) ], key_e, sizeof(key_e ));
private_key->bits = KEY_M_BITS;
memcpy(&private_key->modulus [RSA_MAX_MODULUS_LEN-sizeof(key_m) ], key_m, sizeof(key_m ));
memcpy(&private_key->public_exponet [RSA_MAX_MODULUS_LEN-sizeof(key_e) ], key_e, sizeof(key_e ));
memcpy(&private_key->exponent [RSA_MAX_MODULUS_LEN-sizeof(key_ex)], key_ex, sizeof(key_ex));
memcpy(&private_key->prime1 [RSA_MAX_PRIME_LEN - sizeof(key_p1)], key_p1, sizeof(key_p1));
memcpy(&private_key->prime2 [RSA_MAX_PRIME_LEN - sizeof(key_p2)], key_p2, sizeof(key_p2));
memcpy(&private_key->prime_exponent1[RSA_MAX_PRIME_LEN - sizeof(key_e1)], key_e1, sizeof(key_e1));
memcpy(&private_key->prime_exponent2[RSA_MAX_PRIME_LEN - sizeof(key_e2)], key_e2, sizeof(key_e2));
memcpy(&private_key->coefficient [RSA_MAX_PRIME_LEN - sizeof(key_c) ], key_c, sizeof(key_c ));
}

static void generate_rand(unsigned char *block, unsigned int block_len)
{
unsigned int i;

for (i = 0; i < block_len; i++)
{
block[i] = i;
}
}

static int public_block_operation(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_pk_t *pk)
{
unsigned int edigits = 0, ndigits = 0;
static unsigned int c[BN_MAX_DIGITS] = {0}, e[BN_MAX_DIGITS] = {0};
static unsigned int m[BN_MAX_DIGITS] = {0}, n[BN_MAX_DIGITS] = {0};

bn_decode(m, BN_MAX_DIGITS, in, in_len);
bn_decode(n, BN_MAX_DIGITS, pk->modulus, RSA_MAX_MODULUS_LEN);
bn_decode(e, BN_MAX_DIGITS, pk->exponent, RSA_MAX_MODULUS_LEN);

ndigits = bn_digits(n, BN_MAX_DIGITS);
edigits = bn_digits(e, BN_MAX_DIGITS);

if (bn_cmp(m, n, ndigits) >= 0)
{
return ERR_WRONG_DATA;
}

bn_mod_exp(c, m, e, edigits, n, ndigits);

*out_len = (pk->bits) >> 3;
bn_encode(out, *out_len, c, ndigits);

// Clear potentially sensitive information
memset((unsigned char *)c, 0, sizeof(c));
memset((unsigned char *)m, 0, sizeof(m));

return 0;
}

static int private_block_operation(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_sk_t *sk)
{
unsigned int cdigits = 0, ndigits = 0, pdigits = 0;
static unsigned int c[BN_MAX_DIGITS] = {0}, cp[BN_MAX_DIGITS] = {0}, cq[BN_MAX_DIGITS] = {0};
static unsigned int dp[BN_MAX_DIGITS] = {0}, dq[BN_MAX_DIGITS] = {0};
static unsigned int mp[BN_MAX_DIGITS] = {0}, mq[BN_MAX_DIGITS] = {0};
static unsigned int n[BN_MAX_DIGITS] = {0}, t[BN_MAX_DIGITS] = {0};
static unsigned int p[BN_MAX_DIGITS] = {0}, q[BN_MAX_DIGITS] = {0}, q_inv[BN_MAX_DIGITS] = {0};


bn_decode(c, BN_MAX_DIGITS, in, in_len);
bn_decode(n, BN_MAX_DIGITS, sk->modulus, RSA_MAX_MODULUS_LEN);
bn_decode(p, BN_MAX_DIGITS, sk->prime1, RSA_MAX_PRIME_LEN);
bn_decode(q, BN_MAX_DIGITS, sk->prime2, RSA_MAX_PRIME_LEN);
bn_decode(dp, BN_MAX_DIGITS, sk->prime_exponent1, RSA_MAX_PRIME_LEN);
bn_decode(dq, BN_MAX_DIGITS, sk->prime_exponent2, RSA_MAX_PRIME_LEN);
bn_decode(q_inv, BN_MAX_DIGITS, sk->coefficient, RSA_MAX_PRIME_LEN);

cdigits = bn_digits(c, BN_MAX_DIGITS);
ndigits = bn_digits(n, BN_MAX_DIGITS);
pdigits = bn_digits(p, BN_MAX_DIGITS);

if (bn_cmp(c, n, ndigits) >= 0)
return ERR_WRONG_DATA;

bn_mod(cp, c, cdigits, p, pdigits);
bn_mod(cq, c, cdigits, q, pdigits);
bn_mod_exp(mp, cp, dp, pdigits, p, pdigits);
bn_assign_zero(mq, ndigits);
bn_mod_exp(mq, cq, dq, pdigits, q, pdigits);

if (bn_cmp(mp, mq, pdigits) >= 0)
{
bn_sub(t, mp, mq, pdigits);
}
else
{
bn_sub(t, mq, mp, pdigits);
bn_sub(t, p, t, pdigits);
}

bn_mod_mul(t, t, q_inv, p, pdigits);
bn_mul(t, t, q, pdigits);
bn_add(t, t, mq, ndigits);

*out_len = (sk->bits) >> 3;
bn_encode(out, *out_len, t, ndigits);

// Clear potentially sensitive information
memset((unsigned char *)c, 0, sizeof(c));
memset((unsigned char *)cp, 0, sizeof(cp));
memset((unsigned char *)cq, 0, sizeof(cq));
memset((unsigned char *)dp, 0, sizeof(dp));
memset((unsigned char *)dq, 0, sizeof(dq));
memset((unsigned char *)mp, 0, sizeof(mp));
memset((unsigned char *)mq, 0, sizeof(mq));
memset((unsigned char *)p, 0, sizeof(p));
memset((unsigned char *)q, 0, sizeof(q));
memset((unsigned char *)q_inv, 0, sizeof(q_inv));
memset((unsigned char *)t, 0, sizeof(t));

return 0;
}

int rsa_public_encrypt(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_pk_t *pk)
{
unsigned char byte;
unsigned int i, modulus_len;

modulus_len = (pk->bits) >> 3;
if (in_len + PADDING_SIZE > modulus_len)
{
return ERR_WRONG_LEN;
}

pkcs_block[0] = 0;
pkcs_block[1] = 2;
for (i = 2; i < modulus_len - in_len - 1; i++)
{
do
{
generate_rand(&byte, 1);
} while (byte == 0);
pkcs_block[i] = byte;
}

pkcs_block[i++] = 0;

memcpy((unsigned char *)&pkcs_block[i], (unsigned char *)in, in_len);
status = public_block_operation(out, out_len, pkcs_block, modulus_len, pk);

// Clear potentially sensitive information
byte = 0;
memset((unsigned char *)pkcs_block, 0, sizeof(pkcs_block));

return status;
}

int rsa_public_decrypt(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_pk_t *pk)
{
unsigned int i, modulus_len, pkcs_block_len;

modulus_len = (pk->bits) >> 3;
if (in_len > modulus_len)
return ERR_WRONG_LEN;

status = public_block_operation(pkcs_block, &pkcs_block_len, in, in_len, pk);
if (status != 0)
return status;

if (pkcs_block_len != modulus_len)
return ERR_WRONG_LEN;

if ((pkcs_block[0] != 0) || (pkcs_block[1] != 1))
return ERR_WRONG_DATA;

for (i = 2; i < modulus_len - 1; i++)
{
if (pkcs_block[i] != 0xFF)
break;
}

if (pkcs_block[i++] != 0)
return ERR_WRONG_DATA;

*out_len = modulus_len - i;
if (*out_len + PADDING_SIZE > modulus_len)
return ERR_WRONG_DATA;

memcpy((unsigned char *)out, (unsigned char *)&pkcs_block[i], *out_len);

// Clear potentially sensitive information
memset((unsigned char *)pkcs_block, 0, sizeof(pkcs_block));

return status;
}

int rsa_private_encrypt(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_sk_t *sk)
{
static unsigned char pkcs_block[RSA_MAX_MODULUS_LEN];
unsigned int i, modulus_len;

// Clear potentially sensitive information
memset((unsigned char *)pkcs_block, 0, sizeof(pkcs_block));

modulus_len = (sk->bits) >> 3;
if (in_len + PADDING_SIZE > modulus_len)
return ERR_WRONG_LEN;

pkcs_block[0] = 0;
pkcs_block[1] = 1;
for (i = 2; i < modulus_len - in_len - 1; i++)
{
pkcs_block[i] = 0xFF;
}

pkcs_block[i++] = 0;

memcpy((unsigned char *)&pkcs_block[i], (unsigned char *)in, in_len);

status = private_block_operation(out, out_len, pkcs_block, modulus_len, sk);

return status;
}

int rsa_private_decrypt(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_sk_t *sk)
{
unsigned int i, modulus_len = 0, pkcs_block_len = 0;

modulus_len = (sk->bits) >> 3;
if (in_len > modulus_len)
return ERR_WRONG_LEN;

status = private_block_operation(pkcs_block, &pkcs_block_len, in, in_len, sk);
if (status != 0)
return status;

if (pkcs_block_len != modulus_len)
return ERR_WRONG_LEN;

if ((pkcs_block[0] != 0) || (pkcs_block[1] != 2))
return ERR_WRONG_DATA;

for (i = 2; i < modulus_len - 1; i++)
{
if (pkcs_block[i] == 0)
break;
}

i++;
if (i >= modulus_len)
return ERR_WRONG_DATA;
*out_len = modulus_len - i;
if (*out_len + PADDING_SIZE > modulus_len)
return ERR_WRONG_DATA;
memcpy((unsigned char *)out, (unsigned char *)&pkcs_block[i], *out_len);
// Clear potentially sensitive information
memset((unsigned char *)pkcs_block, 0, sizeof(pkcs_block));

return status;
}

int rsa_decrypt(unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int *out_len)
{
rsa_load_key(&pk, &sk);
status = rsa_public_decrypt(out, out_len, in, in_len, &pk);
return status;
}

int rsa_encrypt(unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int *out_len)
{
rsa_load_key(&pk, &sk);
status = rsa_private_encrypt(out, out_len, in, in_len, &sk);
return status;
}
#ifndef __RSA_2048_H__
#define __RSA_2048_H__

// RSA key lengths
#define RSA_MAX_MODULUS_BITS 2048
#define RSA_MAX_MODULUS_LEN ((RSA_MAX_MODULUS_BITS) >> 3)
#define RSA_MAX_PRIME_BITS ((RSA_MAX_MODULUS_BITS) >> 1)
#define RSA_MAX_PRIME_LEN ((RSA_MAX_PRIME_BITS) >> 3)

// Error codes
#define ERR_WRONG_DATA 0x1001
#define ERR_WRONG_LEN 0x1002


typedef struct
{
unsigned int bits;
unsigned char modulus[RSA_MAX_MODULUS_LEN];
unsigned char exponent[RSA_MAX_MODULUS_LEN];
} rsa_pk_t;

typedef struct
{
unsigned int bits;
unsigned char modulus[RSA_MAX_MODULUS_LEN];
unsigned char public_exponet[RSA_MAX_MODULUS_LEN];
unsigned char exponent[RSA_MAX_MODULUS_LEN];
unsigned char prime1[RSA_MAX_PRIME_LEN];
unsigned char prime2[RSA_MAX_PRIME_LEN];
unsigned char prime_exponent1[RSA_MAX_PRIME_LEN];
unsigned char prime_exponent2[RSA_MAX_PRIME_LEN];
unsigned char coefficient[RSA_MAX_PRIME_LEN];
} rsa_sk_t;

int rsa_decrypt(unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int *out_len);
int rsa_encrypt(unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int *out_len);
#endif
#ifndef __KEY_RAS_H__
#define __KEY_RAS_H__

const static unsigned char key_m[] = {
0x82, 0x2A, 0xB8, 0xBD, 0x20, 0x9D, 0x30, 0x1F, 0xD9, 0x9A, 0x69, 0x75, 0xC4, 0xA9, 0x4D, 0x1B,
0x67, 0x80, 0x35, 0x85, 0x06, 0xE8, 0xF0, 0xE8, 0x88, 0xA4, 0xB8, 0xBF, 0xE7, 0xA3, 0x58, 0x80,
0x6F, 0xF9, 0x2D, 0xF7, 0x21, 0xF1, 0x7D, 0xB2, 0xDA, 0xE4, 0xE6, 0x02, 0xD2, 0x3C, 0x3B, 0xF6,
0x96, 0x30, 0xC2, 0x15, 0x35, 0x56, 0x3A, 0xC0, 0x69, 0x80, 0x47, 0xAF, 0xC3, 0x35, 0xC9, 0x61,
0x1A, 0x39, 0x3A, 0x7B, 0xBA, 0xE5, 0x47, 0x70, 0xB8, 0x15, 0x9E, 0xF3, 0xFF, 0x8F, 0xAB, 0x59,
0x34, 0xC1, 0x16, 0x0D, 0x1F, 0x66, 0x8D, 0x9C, 0xE6, 0x5F, 0x4A, 0x93, 0x93, 0x66, 0xDF, 0x64,
0x79, 0x72, 0xFB, 0x24, 0x47, 0x82, 0xE3, 0x83, 0xCB, 0x0D, 0xC8, 0xE8, 0x25, 0x96, 0x0C, 0x4B,
0x9C, 0xCB, 0xA0, 0x6F, 0x8C, 0x10, 0xEF, 0x0A, 0xE4, 0x76, 0x15, 0x84, 0xC2, 0xBE, 0x10, 0x37,
0x15, 0xA5, 0x88, 0x4F, 0xC3, 0x2F, 0xD6, 0x69, 0xF9, 0x6C, 0xBD, 0xEB, 0xB7, 0x87, 0x79, 0xC5,
0xB1, 0x00, 0xD8, 0x30, 0x5C, 0xAA, 0x24, 0xB8, 0x18, 0x23, 0x04, 0x1C, 0x8E, 0xFA, 0x94, 0xA2,
0x35, 0x99, 0xDE, 0x7F, 0xC7, 0xB9, 0xBC, 0x1E, 0xE5, 0x01, 0x27, 0xE7, 0x38, 0x75, 0x8B, 0x4B,
0x13, 0x13, 0x83, 0x93, 0xF3, 0x2C, 0xCB, 0xA9, 0x07, 0x45, 0xAB, 0x8D, 0x33, 0x78, 0xE2, 0xC7,
0x89, 0x53, 0x15, 0x9A, 0x40, 0x42, 0x8D, 0xBD, 0x37, 0xCC, 0x79, 0x0C, 0xBC, 0x53, 0x2A, 0x4F,
0xBA, 0xD3, 0xE1, 0xA2, 0x4F, 0x20, 0xAE, 0x2B, 0xD4, 0xF1, 0xF6, 0x94, 0xE9, 0xB9, 0xC3, 0xF7,
0x21, 0xDB, 0xC7, 0x79, 0xFD, 0xB6, 0x7E, 0xD0, 0x0C, 0xF4, 0x9E, 0x3C, 0x56, 0x15, 0x2E, 0xEF,
0x0A, 0x43, 0xDE, 0xD6, 0xD8, 0x6A, 0x4B, 0x78, 0x34, 0x34, 0xEA, 0x3C, 0xAD, 0xAF, 0xC6, 0x61};

const static unsigned char key_e[] = {
0x01, 0x00, 0x01};

const static unsigned char key_ex[] = {
0x70, 0x76, 0x56, 0xDC, 0xD9, 0x03, 0xD6, 0x63, 0x7E, 0x4F, 0xC2, 0x14, 0x45, 0x50, 0xFD, 0x54,
0xD3, 0x0C, 0xDB, 0xB0, 0xCE, 0xB2, 0x8E, 0x0A, 0x6A, 0x9C, 0xDF, 0x1E, 0xB7, 0x14, 0xD3, 0x4F,
0x4C, 0xEF, 0x5E, 0x7E, 0x6A, 0x2E, 0x4A, 0xAB, 0x30, 0x22, 0x9A, 0x74, 0x0F, 0x8E, 0x89, 0x44,
0x58, 0xA9, 0x51, 0xD6, 0x9F, 0x19, 0x9C, 0x73, 0x47, 0xF3, 0xD4, 0x7C, 0x10, 0x4E, 0x35, 0x6A,
0x97, 0x0C, 0xA0, 0xF1, 0xEC, 0x1D, 0x52, 0xA7, 0x19, 0xF5, 0x5C, 0x3B, 0x76, 0x2F, 0x7C, 0x1C,
0xFB, 0xCE, 0x63, 0xAD, 0xFC, 0xD6, 0x4F, 0x3E, 0x23, 0x70, 0x6B, 0x6F, 0xAB, 0xE8, 0x32, 0xD4,
0x8D, 0x76, 0x01, 0x74, 0x6B, 0xF0, 0xB3, 0x7F, 0xD7, 0xFD, 0x55, 0xFA, 0xF5, 0x16, 0x7A, 0x13,
0x0E, 0x2A, 0x84, 0xB8, 0x3B, 0xAD, 0x19, 0xCB, 0x30, 0x6E, 0xB1, 0xD2, 0xDD, 0xAA, 0xF7, 0x38,
0x4E, 0x68, 0x8D, 0xAC, 0xAD, 0x34, 0x8F, 0xC2, 0x62, 0xD4, 0x52, 0x4A, 0xB0, 0xAC, 0x06, 0x78,
0xF6, 0x27, 0x13, 0x97, 0xB7, 0xDE, 0xED, 0xFD, 0x2D, 0xB3, 0x62, 0xF0, 0xF6, 0xCA, 0x0C, 0xC8,
0x57, 0x8D, 0x41, 0xBA, 0x76, 0xEE, 0x51, 0x61, 0x94, 0xF2, 0x32, 0xB7, 0x4B, 0xB3, 0x03, 0xF6,
0xFD, 0x38, 0x81, 0xC2, 0x6B, 0x2F, 0x9A, 0x38, 0xB4, 0x20, 0x78, 0xD5, 0x8B, 0xEA, 0xAE, 0x52,
0x08, 0xFA, 0x92, 0xD1, 0x24, 0x84, 0x59, 0x91, 0x28, 0x37, 0x80, 0xCF, 0x73, 0x8A, 0x46, 0x18,
0xD2, 0xB8, 0x04, 0x96, 0x09, 0xE4, 0xD8, 0x54, 0xE8, 0x8C, 0xD7, 0x9A, 0x8F, 0x83, 0x2A, 0xB9,
0xA4, 0x11, 0x0F, 0xD9, 0x99, 0x83, 0x9D, 0xBF, 0x2A, 0x17, 0x0F, 0xEB, 0x87, 0xEB, 0x2A, 0xC5,
0x9C, 0x89, 0x34, 0x84, 0x24, 0xD3, 0x00, 0xAE, 0xE1, 0x4E, 0x47, 0x68, 0x1F, 0x47, 0x01, 0xD1};

const static unsigned char key_p1[] = {
0xE0, 0x5D, 0x3B, 0xE3, 0xE9, 0xF9, 0xBB, 0xD8, 0xA3, 0x5C, 0x18, 0x2E, 0x33, 0x89, 0xFF, 0x03,
0xC7, 0xFC, 0x03, 0x42, 0xE7, 0xDD, 0xDD, 0x39, 0xCE, 0xE0, 0xD5, 0x1D, 0xFF, 0x75, 0xFE, 0x12,
0xA1, 0x4A, 0xF9, 0x37, 0xDF, 0x6B, 0x80, 0xAE, 0xB5, 0x6E, 0x27, 0x50, 0x1F, 0xE5, 0x73, 0xE5,
0xD2, 0xBF, 0xC7, 0x8F, 0x93, 0x4B, 0x61, 0x67, 0xFA, 0xCF, 0x87, 0x75, 0xEB, 0xF5, 0x0C, 0x7D,
0x70, 0x74, 0xFF, 0xF5, 0xB9, 0x9D, 0x48, 0x4F, 0xE7, 0x18, 0x9A, 0x10, 0x80, 0x6F, 0x68, 0x1D,
0x02, 0x37, 0xB8, 0x51, 0xD2, 0xFA, 0xD5, 0xEF, 0x73, 0x9B, 0xF7, 0x98, 0x8F, 0x86, 0x59, 0x55,
0x5E, 0xC6, 0x96, 0x29, 0xB7, 0x3C, 0xD3, 0x4E, 0x1F, 0x8C, 0x80, 0x99, 0xDA, 0x37, 0xBB, 0x54,
0x17, 0x25, 0x2B, 0x35, 0x25, 0x62, 0xF7, 0x24, 0x4A, 0x41, 0xDD, 0xAA, 0x89, 0xE3, 0xD3, 0xB5};

const static unsigned char key_p2[] = {
0x94, 0x85, 0x4A, 0xEF, 0xF3, 0xB3, 0x17, 0x31, 0xF8, 0x24, 0xF5, 0xD7, 0x53, 0xAE, 0xE3, 0x57,
0x1F, 0x70, 0x86, 0xB7, 0xAA, 0x8F, 0x71, 0x8D, 0x8A, 0xB7, 0xA9, 0x89, 0xBD, 0x86, 0x5F, 0x13,
0x65, 0x5A, 0x81, 0x2F, 0x2E, 0xD3, 0xC2, 0x02, 0x98, 0xBE, 0xEA, 0xE6, 0x6E, 0x4E, 0x00, 0xC5,
0x91, 0x90, 0xA6, 0xF9, 0xE0, 0x70, 0x54, 0xA7, 0xBF, 0xC5, 0xF5, 0x0B, 0x41, 0x18, 0x0D, 0x5F,
0x25, 0x6B, 0x81, 0xA6, 0x35, 0xF9, 0x0A, 0xF8, 0x94, 0xA3, 0x7F, 0xF9, 0x53, 0x45, 0x0A, 0x99,
0x5D, 0x7D, 0xE9, 0xE4, 0x47, 0x4F, 0x55, 0x85, 0xA4, 0x23, 0x02, 0xB3, 0x46, 0xDB, 0x2D, 0x31,
0xF2, 0x45, 0x6B, 0x7F, 0x5E, 0xC9, 0xF7, 0xF4, 0xD1, 0xAF, 0xC6, 0x90, 0x67, 0x92, 0x30, 0x91,
0x23, 0x2F, 0x55, 0xAE, 0x53, 0x47, 0x8A, 0x6D, 0x9C, 0xAD, 0x94, 0x26, 0x12, 0x9A, 0x2B, 0x7D};

const static unsigned char key_e1[] = {
0xB5, 0x29, 0xD3, 0x50, 0x26, 0xFF, 0x25, 0xB4, 0xB9, 0xC3, 0x85, 0x2A, 0xD9, 0x26, 0xD6, 0x29,
0x81, 0x73, 0x76, 0x56, 0xB1, 0xCE, 0xAD, 0xF1, 0x1D, 0xA0, 0xE1, 0xB4, 0xC5, 0x2F, 0xCB, 0x25,
0xD3, 0xE3, 0x2B, 0xF4, 0xF7, 0x8C, 0x60, 0x6D, 0xB1, 0xC5, 0xEE, 0x2C, 0x7E, 0x74, 0xD1, 0xEE,
0x83, 0x0B, 0xA3, 0xE1, 0xC4, 0xB7, 0x9B, 0x41, 0x50, 0x7D, 0xFE, 0x0D, 0x33, 0xA7, 0xBC, 0x9C,
0x15, 0x10, 0x04, 0x15, 0xAF, 0xF8, 0xD6, 0x08, 0xDE, 0xBB, 0x38, 0xBB, 0x96, 0x59, 0x5E, 0xA1,
0xFD, 0xC6, 0x6C, 0x28, 0x75, 0xC9, 0x60, 0xB1, 0x66, 0x92, 0x4B, 0x8C, 0x7E, 0x67, 0xA6, 0xFE,
0x8D, 0xF6, 0xA0, 0x0D, 0xB3, 0x0D, 0x84, 0x39, 0x92, 0xB3, 0xEA, 0xAB, 0x50, 0x4E, 0xAC, 0x0E,
0x2C, 0x5A, 0x30, 0xD7, 0x4B, 0x06, 0xEC, 0x33, 0xFB, 0x59, 0xCF, 0xD9, 0x02, 0x5A, 0x59, 0xF9};

const static unsigned char key_e2[] = {
0x01, 0x41, 0xFB, 0xB7, 0x7A, 0x7D, 0xDA, 0xC5, 0x6E, 0x8F, 0x89, 0x91, 0x70, 0x40, 0xFB, 0xE5,
0xE1, 0xFB, 0x46, 0xF8, 0xC9, 0x35, 0xFB, 0xC5, 0x32, 0x16, 0x8A, 0x16, 0x03, 0x87, 0xDE, 0xC8,
0x40, 0x44, 0x7A, 0xF1, 0x96, 0x58, 0xEE, 0xBC, 0xAC, 0xE4, 0x79, 0x02, 0xC8, 0x8E, 0x5A, 0x8D,
0x51, 0xC5, 0x42, 0xD4, 0xBC, 0xE4, 0xD6, 0xA2, 0xB1, 0x0A, 0x11, 0x20, 0x2E, 0x45, 0xF0, 0xDF,
0x0C, 0x67, 0x13, 0xAA, 0xFF, 0xAC, 0x03, 0x3E, 0xC5, 0xAB, 0x78, 0xCA, 0xF8, 0xBC, 0x8D, 0xF1,
0x6C, 0x8C, 0x43, 0x6D, 0xCE, 0x78, 0xCA, 0x85, 0x9E, 0x35, 0x39, 0xB1, 0xA0, 0xF8, 0xFC, 0x31,
0xFF, 0x16, 0x3D, 0x69, 0xCF, 0xB8, 0xB0, 0x23, 0xDF, 0x9E, 0xB8, 0x74, 0xC2, 0x9B, 0xC7, 0x53,
0x83, 0x53, 0xC4, 0x4A, 0xFC, 0xA3, 0x8F, 0x75, 0x8C, 0x2D, 0x20, 0x23, 0x0E, 0x67, 0x45, 0xD5};

const static unsigned char key_c[] = {
0x45, 0x10, 0xB7, 0x07, 0x38, 0x22, 0x5C, 0xC8, 0xC1, 0x53, 0x23, 0x9A, 0x8A, 0xA9, 0x29, 0x8F,
0x68, 0xB5, 0x76, 0xBF, 0x86, 0x2C, 0x02, 0xA9, 0xEF, 0x6F, 0xF5, 0x61, 0x2D, 0xE2, 0x16, 0x31,
0x66, 0x41, 0xC9, 0xD8, 0x14, 0x19, 0xA0, 0x5B, 0xC0, 0x57, 0x7F, 0x22, 0x16, 0xA0, 0x29, 0x8C,
0x3C, 0x1F, 0xB9, 0x31, 0x1B, 0xDA, 0xFD, 0x5F, 0xF8, 0x22, 0x87, 0xF1, 0x9E, 0x8D, 0xAE, 0x3D,
0xC7, 0x99, 0x9F, 0xD4, 0x39, 0x58, 0x40, 0x33, 0xFC, 0x6A, 0x50, 0xF1, 0xA1, 0x69, 0xF4, 0x02,
0x2C, 0x7D, 0x5E, 0xDA, 0xA8, 0x37, 0x29, 0x91, 0x72, 0x72, 0x10, 0x7D, 0xA5, 0xFB, 0xF3, 0x2D,
0x00, 0xBF, 0xDD, 0x76, 0x6C, 0xD2, 0x1B, 0x8D, 0x75, 0x4A, 0x57, 0x8E, 0x13, 0x51, 0xB1, 0xFD,
0xDD, 0xFA, 0xE5, 0xF2, 0xF5, 0xA4, 0xDD, 0x53, 0xD6, 0x2B, 0xD3, 0x3F, 0xB5, 0xBD, 0xA4, 0x48};

#endif
/*****************************************************************************
* @file bignum.c
* @author jianqiang.xue
* @version v1.0.0
* **************************************************************************/

#include <string.h>

#include "bignum.h"

#define BN_MAX_DIGIT 0xFFFFFFFF
#define BN_DIGIT_BITS 32 // For unsigned int
#define DIGIT_2MSB(x) (unsigned int)(((x) >> (BN_DIGIT_BITS - 2)) & 0x03)
#define BN_ASSIGN_DIGIT(a, b, digits) \
{ \
bn_assign_zero(a, digits); \
a[0] = b; \
}


static unsigned int bn_sub_digit_mul(unsigned int *a, unsigned int *b, unsigned int c,
unsigned int *d, unsigned int digits)
{
static unsigned long long result;
unsigned int borrow, rh, rl;
unsigned int i;

result = 0;
if (c == 0)
return 0;

borrow = 0;
for (i = 0; i < digits; i++)
{
result = (unsigned long long)c * d[i];
rl = result & BN_MAX_DIGIT;
rh = (result >> BN_DIGIT_BITS) & BN_MAX_DIGIT;
if ((a[i] = b[i] - borrow) > (BN_MAX_DIGIT - borrow))
{
borrow = 1;
}
else
{
borrow = 0;
}
if ((a[i] -= rl) > (BN_MAX_DIGIT - rl))
{
borrow++;
}
borrow += rh;
}

return borrow;
}

static unsigned int bn_digit_bits(unsigned int a)
{
unsigned int i;

for (i = 0; i < BN_DIGIT_BITS; i++)
{
if (a == 0)
break;
a >>= 1;
}

return i;
}

static unsigned int bn_add_digit_mul(unsigned int *a, unsigned int *b, unsigned int c,
unsigned int *d, unsigned int digits)
{
static unsigned long long result;
unsigned int carry, rh, rl;
unsigned int i;

result = 0;
if (c == 0)
return 0;

carry = 0;
for (i = 0; i < digits; i++)
{
result = (unsigned long long)c * d[i];
rl = result & BN_MAX_DIGIT;
rh = (result >> BN_DIGIT_BITS) & BN_MAX_DIGIT;
if ((a[i] = b[i] + carry) < carry)
{
carry = 1;
}
else
{
carry = 0;
}
if ((a[i] += rl) < rl)
{
carry ++;
}
carry += rh;
}

return carry;
}

void bn_decode(unsigned int *bn, unsigned int digits, unsigned char *hexarr,
unsigned int size)
{
unsigned int t;
int j;
unsigned int i, u;

for (i = 0, j = size - 1; i < digits && j >= 0; i++)
{
t = 0;
for (u = 0; j >= 0 && u < BN_DIGIT_BITS; j--, u += 8)
{
t |= ((unsigned int)hexarr[j]) << u;
}
bn[i] = t;
}

for (; i < digits; i++)
{
bn[i] = 0;
}
}

void bn_encode(unsigned char *hexarr, unsigned int size, unsigned int *bn,
unsigned int digits)
{
unsigned int t;
int j;
unsigned int i, u;

for (i = 0, j = size - 1; i < digits && j >= 0; i++)
{
t = bn[i];
for (u = 0; j >= 0 && u < BN_DIGIT_BITS; j--, u += 8)
{
hexarr[j] = (unsigned char)(t >> u);
}
}

for (; j >= 0; j--)
{
hexarr[j] = 0;
}
}

// a = b
static void bn_assign(unsigned int *a, unsigned int *b, unsigned int digits)
{
unsigned int i;

for (i = 0; i < digits; i++)
{
a[i] = b[i];
}
}

// a = 0
void bn_assign_zero(unsigned int *a, unsigned int digits)
{
unsigned int i;

for (i = 0; i < digits; i++)
{
a[i] = 0;
}
}

unsigned int bn_add(unsigned int *a, unsigned int *b, unsigned int *c,
unsigned int digits)
{
unsigned int ai, carry;
unsigned int i;

carry = 0;
for (i = 0; i < digits; i++)
{
if ((ai = b[i] + carry) < carry)
{
ai = c[i];
}
else if ((ai += c[i]) < c[i])
{
carry = 1;
}
else
{
carry = 0;
}
a[i] = ai;
}

return carry;
}

unsigned int bn_sub(unsigned int *a, unsigned int *b, unsigned int *c,
unsigned int digits)
{
unsigned int ai, borrow;
unsigned int i;

borrow = 0;
for (i = 0; i < digits; i++)
{
if ((ai = b[i] - borrow) > (BN_MAX_DIGIT - borrow))
{
ai = BN_MAX_DIGIT - c[i];
}
else if ((ai -= c[i]) > (BN_MAX_DIGIT - c[i]))
{
borrow = 1;
}
else
{
borrow = 0;
}
a[i] = ai;
}

return borrow;
}

void bn_mul(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int digits)
{
static unsigned int t[2 * BN_MAX_DIGITS] = {0};
unsigned int bdigits = 0, cdigits = 0, i = 0;

// Clear potentially sensitive information
memset((unsigned char *)t, 0, sizeof(t));

bn_assign_zero(t, (2 * digits));
bdigits = bn_digits(b, digits);
cdigits = bn_digits(c, digits);

for (i = 0; i < bdigits; i++)
{
t[i + cdigits] += bn_add_digit_mul(&t[i], &t[i], b[i], c, cdigits);
}

bn_assign(a, t, 2 * digits);
}

// a = b << c (a = b * 2^c)
static unsigned int bn_shift_l(unsigned int *a, unsigned int *b, unsigned int c,
unsigned int digits)
{
unsigned int bi, carry;
unsigned int i, t;

if (c >= BN_DIGIT_BITS)
return 0;

t = BN_DIGIT_BITS - c;
carry = 0;
for (i = 0; i < digits; i++)
{
bi = b[i];
a[i] = (bi << c) | carry;
carry = c ? (bi >> t) : 0;
}

return carry;
}

// a = b >> c (a = b / 2^c)
static unsigned int bn_shift_r(unsigned int *a, unsigned int *b, unsigned int c,
unsigned int digits)
{
unsigned int bi, carry;
int i;
unsigned int t;

if (c >= BN_DIGIT_BITS)
return 0;

t = BN_DIGIT_BITS - c;
carry = 0;
i = digits - 1;
for (; i >= 0; i--)
{
bi = b[i];
a[i] = (bi >> c) | carry;
carry = c ? (bi << t) : 0;
}

return carry;
}

// a = b / c, d = b % c
static void bn_div(unsigned int *a, unsigned int *b, unsigned int *c,
unsigned int cdigits, unsigned int *d, unsigned int ddigits)
{
static unsigned long long tmp;;
static unsigned int cc[2 * BN_MAX_DIGITS + 1] = {0}, dd[BN_MAX_DIGITS] = {0};
int i;
unsigned int ai, t, dddigits, shift;

tmp = 0;
// Clear potentially sensitive information
memset((unsigned char *)cc, 0, sizeof(cc));
memset((unsigned char *)dd, 0, sizeof(dd));

dddigits = bn_digits(d, ddigits);
if (dddigits == 0)
return;

shift = BN_DIGIT_BITS - bn_digit_bits(d[dddigits - 1]);
bn_assign_zero(cc, dddigits);
cc[cdigits] = bn_shift_l(cc, c, shift, cdigits);
bn_shift_l(dd, d, shift, dddigits);
t = dd[dddigits - 1];

bn_assign_zero(a, cdigits);
i = cdigits - dddigits;
for (; i >= 0; i--)
{
if (t == BN_MAX_DIGIT)
{
ai = cc[i + dddigits];
}
else
{
tmp = cc[i + dddigits - 1];
tmp += (unsigned long long)cc[i + dddigits] << BN_DIGIT_BITS;
ai = tmp / (t + 1);
}

cc[i + dddigits] -= bn_sub_digit_mul(&cc[i], &cc[i], ai, dd, dddigits);
while (cc[i + dddigits] || (bn_cmp(&cc[i], dd, dddigits) >= 0))
{
ai++;
cc[i + dddigits] -= bn_sub(&cc[i], &cc[i], dd, dddigits);
}
a[i] = ai;
}

bn_assign_zero(b, ddigits);
bn_shift_r(b, cc, shift, dddigits);
}

// a = b mod c
void bn_mod(unsigned int *a, unsigned int *b, unsigned int bdigits,
unsigned int *c, unsigned int cdigits)
{
static unsigned int t[2 * BN_MAX_DIGITS] = {0};

// Clear potentially sensitive information
memset((unsigned char *)t, 0, sizeof(t));

bn_div(t, a, b, bdigits, c, cdigits);
}

void bn_mod_mul(unsigned int *a, unsigned int *b, unsigned int *c,
unsigned int *d, unsigned int digits)
{
static unsigned int t[2 * BN_MAX_DIGITS]={0};

// Clear potentially sensitive information
memset((unsigned char *)t, 0, sizeof(t));

bn_mul(t, b, c, digits);
bn_mod(a, t, (2 * digits), d, digits);
}

void bn_mod_exp(unsigned int *a, unsigned int *b, unsigned int *c,
unsigned int cdigits, unsigned int *d, unsigned int ddigits)
{
static unsigned int bpower[3][BN_MAX_DIGITS] = {0}, t[BN_MAX_DIGITS] = {0};
int i;
unsigned int ci = 0, ci_bits = 0, j, s;

// Clear potentially sensitive information
memset((unsigned char *)bpower, 0, sizeof(bpower));
memset((unsigned char *)t, 0, sizeof(t));

bn_assign(bpower[0], b, ddigits);
bn_mod_mul(bpower[1], bpower[0], b, d, ddigits);
bn_mod_mul(bpower[2], bpower[1], b, d, ddigits);

BN_ASSIGN_DIGIT(t, 1, ddigits);

cdigits = bn_digits(c, cdigits);
i = cdigits - 1;

for (; i >= 0; i--)
{
ci = c[i];
ci_bits = BN_DIGIT_BITS;

if (i == (int)(cdigits - 1))
{
while (!DIGIT_2MSB(ci))
{
ci <<= 2;
ci_bits -= 2;
}
}

for (j = 0; j < ci_bits; j += 2)
{
bn_mod_mul(t, t, t, d, ddigits);
bn_mod_mul(t, t, t, d, ddigits);
if ((s = DIGIT_2MSB(ci)) != 0)
{
bn_mod_mul(t, t, bpower[s - 1], d, ddigits);
}
ci <<= 2;
}
}
bn_assign(a, t, ddigits);
}

int bn_cmp(unsigned int *a, unsigned int *b, unsigned int digits)
{
int i;

for (i = digits - 1; i >= 0; i--)
{
if (a[i] > b[i])
return 1;
if (a[i] < b[i])
return -1;
}

return 0;
}

unsigned int bn_digits(unsigned int *a, unsigned int digits)
{
int i;

for (i = digits - 1; i >= 0; i--)
{
if (a[i])
break;
}

return (i + 1);
}
/*****************************************************************************
* @file bignum.h
* @author jianqiang.xue
* @version v1.0.0
****************************************************************************/

#ifndef __BIGNUM_H__
#define __BIGNUM_H__

#define BN_MAX_DIGITS 65 // RSA_MAX_MODULUS_LEN + 1


void bn_decode(unsigned int *bn, unsigned int digits, unsigned char *hexarr, unsigned int size);
void bn_encode(unsigned char *hexarr, unsigned int size, unsigned int *bn, unsigned int digits);

// a = 0
void bn_assign_zero(unsigned int *a, unsigned int digits);

// a = b + c, return carry
unsigned int bn_add(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int digits);
// a = b - c, return borrow
unsigned int bn_sub(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int digits);
// a = b * c
void bn_mul(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int digits);

// a = b mod c
void bn_mod(unsigned int *a, unsigned int *b, unsigned int bdigits, unsigned int *c, unsigned int cdigits);
// a = b * c mod d
void bn_mod_mul(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d, unsigned int digits);
// a = b ^ c mod d
void bn_mod_exp(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int cdigits, unsigned int *d, unsigned int ddigits);

// returns sign of a - b
int bn_cmp(unsigned int *a, unsigned int *b, unsigned int digits);

// returns significant length of a in digits
unsigned int bn_digits(unsigned int *a, unsigned int digits);

#endif // __BIGNUM_H__

使用例子伪代码 main.c

#include <stdio.h>
#include <string.h>
#include "rsa2048.h"

unsigned char ciphertext[256];
unsigned char plaintext[50]; // 根据明文实际长度定义
unsigned int plaintext_len = 0; // 得到解密后的明文长度
int ciphertext_len = 0; //密文长度
int ret = 0;
strcpy((char *)plaintext, "xjqlisun9527");

ret = rsa_encrypt(plaintext, strlen((char *)plaintext), ciphertext, (unsigned int *)&ciphertext_len);
printf("私钥加密后(%d):\n明文=%s, p_len=%ld, \n密文=%s, c_len=%d\n", ret, plaintext, strlen((char *)plaintext),
ciphertext, ciphertext_len);

memset(plaintext, 0, 50);
plaintext_len = 0;
ret = rsa_decrypt(ciphertext, 256, plaintext, &plaintext_len);
printf("公钥解密后(%d):\n明文=%s, p_len=%d, \n密文=%s, c_len=%ld\n", ret, plaintext, plaintext_len,
ciphertext, strlen((char *)ciphertext));

[单片机] rsa2048签名算法_c语言

​​工程下载​​


标签:int,MAX,bn,rsa2048,unsigned,len,char,单片机,算法
From: https://blog.51cto.com/xuejianqiang/5811363

相关文章