#P6959. [NEERC 2017] Hack

[NEERC 2017] Hack

Description

Heidi 正在分析一个特殊的设备。该设备以一个 aa 作为输入,并使用以下伪代码和存储在设备中的一些整数 ddnn 计算 admodna^d \bmod n

modPow(a, d, n) {
  r = 1;
  for (i = 0; i < 60; ++i) {
    if ((d & (1 << i)) != 0) {
      r = r * a % n;
    }
  a = a * a % n;
  }
}

注意,伪代码假设整数可以是任意大小,<<<< 表示按位左移,& 表示按位与,% 表示取模。

设备不会告诉 Heidi 计算结果。然而,Heidi 可以测量计算所需的时间。她知道只有模 nn 的乘法(上述伪代码中的第 5 行和第 7 行)需要可测量的时间,其他所有行可以假设为 0 纳秒。

此外,她知道将 xxyynn 相乘需要 (bits(x)+1)(bits(y)+1)(\text{bits}(x) + 1) \cdot (\text{bits}(y) + 1) 纳秒,其中 bits(x)\text{bits}(x)xx 的二进制表示中不含前导零的位数,更正式地,bits(x)=log2(x+1)\text{bits}(x) = \lceil \log_2 (x + 1) \rceil

Heidi 知道整数 nn,但不知道整数 dd。她想通过将不同的整数 aa 作为输入提供给设备,并测量每个 aa 的计算时间来找到 dd

她知道 nndd 是通过以下方式选择的:首先,两个具有 30 位二进制表示的素数 ppqq(换句话说,在 2292^{29}23012^{30} - 1 之间)被独立且均匀地随机选择。然后计算 n=pqn = p \cdot q。然后计算 m=φ(n)=(p1)(q1)m = \varphi(n) = (p-1) \cdot (q-1)。然后在 11m1m - 1 之间均匀随机选择 dd,使其与 mm 互质。

交互协议

首先,测试系统写入整数 nn——设备使用的模数。注意,nn 和隐藏的数字 dd 保证是按照上述过程生成的。

你的解决方案应打印两种类型的请求:

  • “? a” 告诉设备以 aa 作为输入。aa 必须是 00n1n-1 之间的整数。测试系统会返回设备计算 modPow(a , d , n) 所需的时间(以纳秒为单位)。

  • “! d” 告诉你的程序已确定的 dd 值。

不要忘记在每次请求后刷新输出!

你的解决方案必须发出恰好一个第二种类型的请求,该请求必须是最后一个请求,并且解决方案在发出该请求后必须正常终止。

你的解决方案最多可以发出 30,00030,000 个第一种类型的请求。

你的解决方案将在 3030 个测试用例上运行,每次运行处理一个 (n,d)(n , d) 对。对于每个测试用例,数字 nndd 是固定的,并且是使用上述过程生成的。下面的例子不是以这种方式生成的,因此不会用于测试你的解决方案;它仅用于说明输入/输出格式并为计算时间的合理性检查提供一个 sanity check。

15
980
293
? 3
? 8
! 5

Hint

题面翻译由 ChatGPT-4o 提供。