【问题标题】:How to write a constant time function to copy the most significant bit to all bits如何编写恒定时间函数以将最高有效位复制到所有位
【发布时间】:2013-11-18 22:38:34
【问题描述】:

我想用 C 语言编写一个函数,它采用uint8_t 的 MSB,如果已设置,则返回 0xFF,否则返回 0x00。简而言之,它返回一个整数,其中所有位都设置为与 MSB 相同的值。

但我想以完全恒定的时间方式进行,没有分支,没有数组偏移,只是保证始终触及相同位数的数学运算。理想情况下,没有任何未定义的行为。如何做到这一点?

【问题讨论】:

  • 在 C# 中,我使用 (uint8_t)((int8_t)x >> 7) 的等价物,但我不确定这在 C 中是否明确定义。
  • @CodesInChaos:不是;右移有符号值的结果是实现定义的,尽管在实践中你很难找到没有将其编译为算术移位的实现。 (基本上,C 标准没有定义它的原因是因为它不假设有符号算术必须使用 2 的补码来完成。)

标签: c cryptography bit-manipulation


【解决方案1】:

怎么样:

#define uint8_msb_to_all_bits(x) (0xFF * ((x) >> 7))

甚至更好:

#define uint8_msb_to_all_bits(x) (-((x) >> 7))

这两者的工作方式是,如果x 是一个 8 位无符号整数,则如果设置了x 的 MSB,则x >> 7 为 1,否则为 0。剩下的就是将 1 映射到 0xFF,这可以通过乘法来完成,或者在这种特殊情况下,只需将数字取反即可。

(是的,negating an unsigned number is well defined in C。)

【讨论】:

  • 在现代 CPU 上否定无符号是否需要恒定的时间?
  • @AlexGaynor:如果没有,我会感到非常惊讶;它很可能会编译为单个恒定时间汇编指令。
  • 仅仅因为某事是一条指令并不意味着所有输入都需要相同的时间(例如 IDIV 是可变时间,任何涉及内存的东西也是如此)。
  • 好吧,在 x86 平台上,它可能编译为 negsub(除非聪明的编译器将其优化为 sar),两者都不是执行时间应该取决于输入。但是,当然,人们永远无法真正提前知道某些疯狂的编译器(或 CPU 设计者!)可能会做什么,因此唯一确定的方法是首先检查程序集,然后对其进行基准测试。
  • 请注意,第二个选项将返回 -1 类型为 int - 如果您想要 0xFF,最好将结果显式转换为 uint8_t
【解决方案2】:

怎么样

- (x >> 7)

?

仅保留 MSB,并使用数学求反将其复制到所有位。

【讨论】:

    【解决方案3】:

    鉴于您的uint8_t声明:

    uint8_t x = // MSB is either 1 or 0 if `x` depending on the signed value of `x`
    

    假设有符号整数的 2 补码的作弊:

    return (((uint16_t)(int8_t)x) >> 8) & 0xff;
    

    【讨论】:

    • 在使用 2 的补码算法的系统上,您可能不需要 (uint16_t) 强制转换,因为只需将有符号值右移即可编译为 arithmetic shift。当然,从技术上讲,所有这些(从 (int8_t) 演员表开始)都是实现定义的行为,因此无法保证。
    • @IlmariKaronen 没错...演员只是为了安全。不过,感谢您指出这一点。
    • @JensGustedt 为什么应该是 6?
    • @H2CO3 - 一个问题 - 为什么要添加 & 0xff?强制转换为 (int8_t)x 允许 x 稍后被 (uint16_t) 符号扩展为 16 位。现在(uint16_t)(int8_t)x 只是将x's 位#7 复制到位#8..#15 的16 位值。无符号值的右移会将 0 放入 msbs,因此在>>8 位之后 #8..#15 将为 0,而不管 x's msb。
    • @Artur 只是为了安全。安全总比后悔好。
    猜你喜欢
    • 1970-01-01
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 1970-01-01
    • 2020-09-07
    相关资源
    最近更新 更多