我正在实施RSA加密,需要生成随机的1024位素数。
由于限制,我无法使用INTEGER
信号,因此当我需要执行算术运算时,我使用STD_LOGIC_VECTOR
并将其转换为UNSIGNED
UNIFORM
生成32个随机32位数字,然后将其复制到1024位STD_LOGIC_VECTOR
。function GEN_1024_PRIME return STD_LOGIC_VECTOR is
VARIABLE s1, s2 : POSITIVE;
VARIABLE random : REAL;
VARIABLE small_random : STD_LOGIC_VECTOR (31 downto 0);
VARIABLE large_random : STD_LOGIC_VECTOR (1023 downto 0);
VARIABLE prime : STD_LOGIC := '0';
begin
while prime /= '1' loop
for I in 0 to 31 loop
UNIFORM(s1, s2, random);
small_random := STD_LOGIC_VECTOR(to_unsigned(INTEGER(TRUNC(random * REAL(2147483647))), 32));
large_random (I*32 + 31 downto I*32) := small_random;
end loop;
large_random(0) := '1';
large_random(1023) := '1';
prime := MILLER_RABIN (large_random);
end loop;
return large_random;
end function;
function MILLER_RABIN (prime : STD_LOGIC_VECTOR (1023 downto 0)) return STD_LOGIC is
VARIABLE t : INTEGER := 4;
VARIABLE temp, r, a, x, j, n: UNSIGNED (1023 downto 0);
VARIABLE small_random : UNSIGNED (31 downto 0);
VARIABLE large_random : UNSIGNED (1023 downto 0);
VARIABLE s1, s2 : POSITIVE;
VARIABLE random : REAL;
begin
n := UNSIGNED(prime);
if n MOD 2 = 0 OR n MOD 3 = 0 then
return '0';
else
-- calculate n - 1 = 2^s * r such that r is odd
r := n - 1;
while r MOD 2 = 0 loop
r := r / 2;
end loop;
for I in 1 to t loop
-- choose random a, 2 <= a <= n-2
for I in 0 to 31 loop
UNIFORM(s1, s2, random);
small_random := to_unsigned(INTEGER(TRUNC(random * REAL(2147483647))), 32);
large_random (I*32 + 31 downto I*32) := small_random;
end loop;
a := large_random;
temp := r;
x := MOD_3(a, temp, n);
while (temp /= (n - 1) AND x /= 1 AND x /= (n - 1)) loop
x := (x * x) MOD n;
temp := temp * 2;
end loop;
if x /= (n - 1) AND temp MOD 2 = 0 then
return '0';
end if;
end loop;
return '1';
end if;
end function;
function MOD_3 (a, b, c : UNSIGNED (1023 downto 0)) return UNSIGNED is
VARIABLE x : UNSIGNED (1023 downto 0) := TO_UNSIGNED(1, 1024);
VARIABLE y : UNSIGNED (1023 downto 0) := a;
VARIABLE b_temp : UNSIGNED (1023 downto 0) := b;
begin
while b_temp > 0 loop
if b_temp MOD 2 = 1 then
x := (x * y) MOD c;
end if;
y := (y * y) MOD c;
b_temp := b_temp / 2;
end loop;
return x MOD c;
end function;
我将输入转换为UNSIGNED
以执行算术运算,看起来它会起作用,直到我意识到将存在2个值的乘积大于1024位的实例。例如,在这个while循环中:
while (temp /= (n - 1) AND x /= 1 AND x /= (n - 1)) loop
x := (x * x) MOD n;
temp := temp * 2;
end loop;
temp := temp * 2;
的结果是2048位。
我觉得我可以通过搞乱UNSIGNED
变量的大小来解决这个问题,但我认为它变得比它需要的更加混乱,所以我想知道我是不是接近这个错误的方式? 是否有更简单的方法来生成1024位素数?是否有另一种素性测试更适合我的问题?