2021SC@SDUSC
gmssl/openssl中的模幂运算
1.第一种
下面函数可以进行更有效率的模乘和模除,假如在重复在同一模下重复进行模乘和模除计算,计算r=(a*b)%m 利用了recp=1/m
BN_RECP_CTX *BN_RECP_CTX_new(void);
void BN_RECP_CTX_init(BN_RECP_CTX *recp);
void BN_RECP_CTX_free(BN_RECP_CTX *recp);
int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *m, BN_CTX *ctx);
int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b,
BN_RECP_CTX *recp, BN_CTX *ctx);
2.第二种
下面函数采用蒙哥马利算法进行模幂计算,可以提高效率,他也主要应用于在同一模下进行多次幂运算
BN_MONT_CTX *BN_MONT_CTX_new(void);
void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
void BN_MONT_CTX_free(BN_MONT_CTX *mont);
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *m, BN_CTX *ctx);
BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
BN_MONT_CTX *mont, BN_CTX *ctx);
int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
BN_CTX *ctx);
int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
BN_CTX *ctx);
gmssl中的密文编码
GmSSL通过SM2_CIPHERTEXT_VALUE 对象来表示密文数据结构,函数SM2_do_encrypt() 和SM2_do_decrypt() 可以生成SM2_CIPHERTEXT_VALUE 对象及对其解密,函数SM2_CIPHERTEXT_VALUE_encode() 和SM2_CIPHERTEXT_VALUE_decode() 实现该对象的Plain编解码。
GmSSL的SM2_encrypt() 和SM2_decrypt() 在加解密的同时也完成SM2_CIPHERTEXT_VALUE 对象的Plain编解码。
libgpucrypto中的加解密
rsa_context.cc 公钥加密
void rsa_context::pub_encrypt(unsigned char *out, int *out_len,
const unsigned char *in, int in_len)
{
int bytes_needed = get_key_bits() / 8;
assert(*out_len >= bytes_needed);
assert(in_len <= max_ptext_bytes());
*out_len = RSA_public_encrypt(in_len, in, out, rsa, RSA_PKCS1_PADDING);
assert(*out_len != -1);
}
私钥解密
void rsa_context::priv_decrypt(unsigned char *out, int *out_len,
const unsigned char *in, int in_len)
{
#if 0
if (is_crt_available()) {
BIGNUM *c = BN_bin2bn(in, in_len, NULL);
assert(c != NULL);
assert(BN_cmp(c, rsa->n) == -1);
BIGNUM *m1 = BN_new();
BIGNUM *m2 = BN_new();
BIGNUM *t = BN_new();
BN_nnmod(t, c, rsa->p, bn_ctx);
BN_mod_exp(m1, t, rsa->dmp1, rsa->p, bn_ctx);
BN_nnmod(t, c, rsa->q, bn_ctx);
BN_mod_exp(m2, t, rsa->dmq1, rsa->q, bn_ctx);
BN_sub(t, m1, m2);
BN_mod_mul(t, t, rsa->iqmp, rsa->p, bn_ctx);
BN_mul(t, t, rsa->q, bn_ctx);
BN_add(t, m2, t);
int ret = remove_padding(out, out_len, t);
assert(ret != -1);
BN_free(c);
BN_free(m1);
BN_free(m2);
BN_free(t);
} else {
#endif
int bytes_needed = get_key_bits() / 8;
assert(*out_len >= bytes_needed);
*out_len = RSA_private_decrypt(in_len, in, out, rsa,
RSA_PKCS1_PADDING);
assert(*out_len != -1);
#if 0
}
#endif
}
|