BigNum

什么是BigNum
作为开发者,你很可能已经意识到了你所喜欢的数据类型的大小限制。例如,在C语言中,int数据类型在可移植的情形下,最大可以表示32 767。即使在某些平台上它也许是32位或者64位的长度,但你不能总是依靠这一点。
大部分程序设计语言在它们的设置中,最多有一种64位的数据类型。如果我们不得不直接在这些约束下生存,那么我们的公钥算法会非常不安全。例如,分解64位的数字是一种很简单的任务。
为了解决这些问题,我们使用通常叫做多(multiple)精度或者固定(fixed)精度的算法。这些算法构造了大整数的表示,通过使用已支持的数据类型(例如unsigned long)作为一个数字(digit)—很像我们以十进制的形式在0~9的范围内追加更多的数字来构造大整数一样。
这些数字(在不同的库中也有叫做零件(limb)的)形成了所有运算的基础。在目标平台上,它们的选择通常是高效的。例如,如果你的机器能够高效地执行unsigned long数据类型的操作,那么它很可能是你的数字类型。我们所要执行的数学计算非常类似于我们在学校里所学的十进制运算。惟一的区别是基数(radix)不是10,而是一个2的幂,例如232。
固定的和多精度算法在理论上稍有不同,并且大部分体现在实现上。在多精度算法中,我们通过分配所需的新内存来表示运算的结果,试图容纳任意大小的整数。这对于处理未知大小的数字很有用。但是,它有在计算过程中执行堆操作的开销,这可能会相当慢。固定精度算法只有一个有限的(固定的)空间来存储一个数的表示。正因为如此,它在计算过程中不需要堆操作。固定精度非常适合用于输入的大小是事先已知的任务中。例如,如果你准备实现ECC P-192,你知道最大的数为384位(2×192)并且你可以相应地进行调整。
在本文中,我们关注固定精度的实现细节,因为它们更加高效。我们会更多地讨论BigNum数学而不是让读者直接去看各种源代码。
更多的资源
对于想要了解更多内容的读者,可以参考各种其他的在更深层次上描述BigNum数学的资源。BigNum Math这本书通过介绍一个公开的数学算法库LibTomMath来讲述这一主题。对于刚接触这个方面知识的读者来说,很值得一读。The Art of Computer Programming Volume 2也从理论的角度讲述了这一主题,并讲解了高效的算法背后关键的数学概念。读者也应该看一看可以免费获得的LibTomMath和TomsFastMath包的源代码,它们分别实现了多精度和固定精度运算。它们的源代码都有很好的说明文档,而且可以免费用于各种目的。
关键算法
当正确地实现了某些关键的算法时,一个BigNum算法库可以执行得相当好。即使一个问题会有多种算法,例如椭圆曲线的点加,但只有4种算法是最重要的:乘法(multiplication),平方(squaring)、约简(reduction)和模逆(modular inversion)。
当执行典型的公钥操作时,处理器时间的用量通常由最多到最少的顺序是约简、乘法、平方和模逆—这让你知道在优化的时候应该在哪里多花些时间。
实际上,我们所讨论的和教给小孩子们的算法是一样的,例如乘法。关键的区别是它们是怎样实现的。像累加器的结构、循环拆分和操作码的选择都可以造成这些不同。我们将使用适用于x86、PPC和ARM处理器的代码来讲解这4种算法,并使用GCC作为我们所选择的开发工具。

你可能感兴趣的:(C++学习)