c - 如何在不使用 C 语言中的整数类型的情况下将 2 uint8 模乘一个大数

标签 c cryptography

<分区>

如果 ABuint8_t 类型并且我想要结果 C=AxB % N 其中N 是 2^16,如果我不能使用整数,我该怎么做(所以我不能将 N 声明为整数,只能将 uint8_t) C 语言?

注意:ABC 存储在uint8 数组中,因此它们被“表达”如 uint8 但它们的值可以更大。

最佳答案

一般来说,没有简单的方法可以做到这一点。

首先,您需要为每个 uint8_t block 实现 A 和 B 之间的进位乘法。查看答案here .

2^16 划分实际上意味着“忽略”最后 16 位,“不要使用”最后两个 uint8_t(因为您使用 int 数组.).由于您有模数运算符,这意味着恰恰相反,因此您只需要获取最后两个 uint8_t

A 的最低两个 uint8(比如 a0a1)和 B(比如 b0b1):

将每个uint8分成高低部分

a0h = a0 >> 4;    ## the same as a0h = a0/16;
a0l = a0 % 16;    ## the same as a0l = a0 & 0x0f;
a1h = a1 >> 4;
a1l = a1 % 16;

b0h = b0 >> 4;
b0l = b0 % 16;
b1h = b1 >> 4;
b1l = b1 % 16;

首先将较低的部分相乘(x 是一个缓冲区变量)

x = a0l * b0l;

结果的第一部分是x的后四位,我们称它为s0l

s0l = x % 16;  

x 的最高位是进位。

c = x>>4;   

将第一个 uint8 的高位相乘并加进位。

x = (a0h * b0h) + c;

结果的第一部分是x的后四位,我们称它为s0h。我们需要再次携带。

s0h = x % 16;
c = x>>4;

我们现在可以合并 s0:

s0 = (s0h << 4) +  s0l;

对 s1 执行完全相同的操作(但不要忘记添加进位!):

x = (a1l * b1l) + c;
s1l = x % 16;
c = x>>4;
x = (a1h * b1h) + c;
s1h = x % 16;
c = x>>4;
s1 = (s1h << 4) +  s1l;

此时您的结果是cs1s0(下一次乘法需要进位,例如。s2, s3, s4,)。正如你的公式所说的 %(2^16) 你已经有了你的结果 - s1s2。如果你必须用别的东西除法,你应该做类似于上面代码的事情,但除法。在这种情况下,小心捕捉除以零,它会给你 NAN 或其他东西!

您可以将 A、B、C 和 S 放入数组中并通过索引对其进行循环以使代码更简洁。

关于c - 如何在不使用 C 语言中的整数类型的情况下将 2 uint8 模乘一个大数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34948934/

相关文章:

javascript - 使用 RSA OAEP 加密和解密

encryption - 标准加密文件格式有哪些?

java - 这两个代码的输出是什么?

c++ - 编译cpp文件时代码不并行,c是并行的

C 链表冒泡排序逻辑错误

c - libiptc : adding nat rule with mark based match?

c++ - 加密我的 C++ 应用程序发送和接收的数据?

java - java中boolean到int的高效恒定时间转换

java - 在另一台设备上使用 EasyCrypt 库完成密码时出错

用 C 比较两个数组