内存依赖推测会阻止BN_consttime_swap为常数吗?

前端之家收集整理的这篇文章主要介绍了内存依赖推测会阻止BN_consttime_swap为常数吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
上下文

OpenSSL中的function BN_consttime_swap是一件美丽的事情。在此片段中,条件已计算为0或(BN_ULONG)-1:

#define BN_CONSTTIME_SWAP(ind) \
    do { \
            t = (a->d[ind] ^ b->d[ind]) & condition; \
            a->d[ind] ^= t; \
            b->d[ind] ^= t; \
    } while (0)
…
    BN_CONSTTIME_SWAP(9);
…
    BN_CONSTTIME_SWAP(8);
…
    BN_CONSTTIME_SWAP(7);

其目的是为了确保更高层次的运作需要持续的时间,这个功能可以互换两个bignum,或者在一段时间内将它们留在原位。当它将它们留在原位时,它实际上读取每个bignum的每个单词,计算一个与旧单词相同的新单词,并将该结果写回原始位置。

意图是,这将需要同样的时间,如果bignums被有效地交换。

在这个问题中,我假设一个现代的,广泛的架构,如Agner Fog在他的optimization manuals中所描述的那样。将C代码直接翻译成汇编(没有C编译器解除程序员的努力)。

我试图了解上面的构造是否是“尽力而为”的定时执行,或者是完美的常时执行。

特别地,我关心当函数BN_consttime_swap被调用时,bignum a已经在L1数据高速缓存中的情况,并且刚刚函数代码立即开始在bignum上工作。在现代处理器上,足够的指令可以同时在飞行中,以便在使用bignum a时不会在技术上完成复印。允许在调用BN_consttime_swap之后执行指令的机制是内存依赖性推测。让我们假设naive memory dependence speculation为了争论。

这是什么问题似乎归结为:

当处理器最终检测到BN_consttime_swap之后的代码从内存中读取时,与推测相反,已经写入函数内部,一旦它检测到地址被写入,或者它允许,它就会取消推测性执行当它检测到已写入的值与已经存在的值相同时,它本身保留它?

在第一种情况下,BN_consttime_swap看起来像是实现了完美的恒定时间。在第二种情况下,只有最常用的时间是:如果bignums没有被交换,那么调用BN_consttime_swap之后的代码的执行速度将比它们被交换的速度快得多。

即使在第二种情况下,在可预见的未来,这可能会被修复(只要处理器保持天真),对于每个两个bignum的每个单词,写出一个不同于两个可能的最终的值在再次写入旧值或新值之前的值。可能需要在某一点涉及易失性类型限定符,以防止普通编译器过度优化序列,但仍然可能。

注意:我知道store forwarding,但商店转发只是一个捷径。它不会阻止在写入之前执行读取。而在某些情况下,这种情况就会失败,尽管在这种情况下人们不会期待。

Straightforward translation of the C code to assembly (without the C compiler undoing the efforts of the programmer) is also assumed.

我知道这不是你问题的主旨,而且我知道你知道这一点,但是我需要忍受一分钟。这甚至不能成为提供定时执行的“尽力而为”的尝试。编译器被许可以检查条件的值,如果条件为零,则跳过整个事情。混淆条件的设置使得这种情况不太可能发生,但不能保证。

据称“常时”代码不应该写在C中,停止。即使今天是不变的时间,在你测试的编译器上,一个更智能的编译器会一起来打败你。您的其中一位用户在使用之前将使用此编译器,并且他们不会意识到您已经暴露了它们的风险。有三种方式可以实现我所知道的恒定时间:专用硬件,组装或DSL生成机器代码以及持续执行的证明。

抛在一边,就在手边的实际架构问题上:假设一个愚蠢的天真的编译器,这个代码是在我很熟悉的μarches中是不断的时间来评估这个问题,我期望一个简单的原因是广泛的:功率。我希望在存储队列或缓存中检查存储的值是否与已存在的值相匹配,并有条件地使存储器短路或避免使每个商店的高速缓存行脏污,消耗的能量比您获得的罕见场合节省的能量避免一些工作。但是,我不是cpu设计师,不要假设代表他们说话,所以把它放在几汤匙的盐上,请先考虑一下,然后再假设这是真的。

猜你在找的设计模式相关文章