国密算法全栈安全能力系统化提升 - 第3节
双线性对:SM9的数学心脏
双线性对,说白了就是一种特殊的映射。它能把两个群里的元素,映射到第三个群里去。而且这个映射有个神奇的性质——它能把加法变成乘法。
我记得刚接触这个概念时,也觉得挺抽象的。直到我在一个实际项目中,需要设计基于身份的加密方案,才真正体会到它的威力。没有双线性对,SM9这类算法根本跑不起来。
Weil对与Tate对
双线性对有两大经典实现:Weil对和Tate对。它们都是定义在椭圆曲线上的。
Weil对:
- 输入两个n阶点P、Q
- 输出一个n次单位根
- 计算复杂度较高
Tate对:
- 输入一个n阶点P和一个任意点Q
- 输出一个扩域元素
- 计算效率更高,SM9用的就是它
核心区别:Tate对比Weil对少一次幂运算,效率提升约30%。在实际工程中,这30%可能就是能不能上线的分水岭。
双线性对的三个性质
为什么双线性对这么重要?因为它同时满足三个性质:
- 双线性:e(aP, bQ) = e(P, Q)^(ab)
- 非退化性:存在P、Q使得e(P, Q) ≠ 1
- 可计算性:存在高效算法计算e(P, Q)
你想想看,有了双线性,我们就能在椭圆曲线上做"乘法"了。这在以前是不可能的——椭圆曲线只有加法群结构。
我的经验:在实现SM9时,我建议优先选择Tate对。虽然Weil对在理论上更优美,但Tate对在实际工程中更友好。我曾经在两个方案之间犹豫,最后用Tate对把签名验证时间从200ms降到了120ms。
Miller算法:双线性对的计算引擎
双线性对的理论很美,但怎么算呢?Miller算法就是答案。
Miller算法的核心思想,说白了就是"边计算标量乘,边累积函数值"。它把双线性对的计算,分解成一系列椭圆曲线上的点加和点倍操作。
算法流程
我习惯把Miller算法分成三步:
- 初始化:设置f = 1,T = P
- 主循环:按Q的二进制展开,逐位处理
- 每次先做倍点:T = 2T,更新f
- 如果当前位为1:T = T + P,更新f
- 最终幂:对f做一次幂运算,得到最终结果
// Miller算法伪代码
function Miller(P, Q, n):
f = 1
T = P
n_bits = binary(n)
for bit in n_bits[1:]: // 从次高位开始
f = f^2 * line(T, T, Q) // 倍点
T = 2T
if bit == 1:
f = f * line(T, P, Q) // 点加
T = T + P
return f^( (q^k - 1) / n ) // 最终幂
避坑指南:我曾经在实现Miller算法时,忽略了line函数的计算顺序。结果调试了整整两天,才发现是坐标系的选取问题。建议使用雅可比坐标系,可以减少求逆运算。
SM9中的双线性对应用
SM9是我国基于身份的密码标准。它用双线性对做了三件事:
| 功能 | 使用的对运算 | 计算次数 |
|---|---|---|
| 密钥封装 | e(Ppub, Qid) | 1次 |
| 签名验证 | e(S, P) = e(H, Ppub) | 2次 |
| 密钥交换 | e(P1, P2) | 2次 |
嗯,这里要注意。SM9用的是256位的BN曲线,Tate对的计算在普通PC上大约需要5-10ms。这个速度对大多数应用来说已经够用了。
关键点:SM9的安全性依赖于q-ABDHE假设。这个假设比传统的CDH假设更强,但换来了基于身份的便利性。在实际部署中,我建议优先使用SM9而不是自己设计基于身份的方案——标准化的东西,坑少。
扩展欧几里得算法与大数运算
双线性对的计算离不开大数运算。而扩展欧几里得算法,就是大数运算的基石之一。
扩展欧几里得算法
这个算法能同时求出:
- 两个数的最大公约数gcd(a, b)
- 一组整数解x, y,使得ax + by = gcd(a, b)
在SM9中,它主要用于:
- 计算模逆元
- 求解中国剩余定理
- 密钥生成时的参数计算
// 扩展欧几里得算法
function extended_gcd(a, b):
if b == 0:
return (a, 1, 0)
else:
g, x1, y1 = extended_gcd(b, a % b)
x = y1
y = x1 - (a // b) * y1
return (g, x, y)
大数运算的工程要点
我个人习惯在实现大数运算时,注意以下几点:
- 使用无符号整数:避免符号位带来的麻烦
- 注意进位传播:用汇编级的多精度加法
- 预计算优化:比如Montgomery模乘,能省掉除法
我的经验:在嵌入式设备上实现SM9时,大数运算往往是性能瓶颈。我建议用查表法优化模逆运算,能把速度提升2-3倍。另外,尽量用固定长度的数组,避免动态内存分配。
知识体系总览
下面这张图,把本章的核心知识点串起来了:
从这张图能看出来,双线性对是整个SM9的数学基础。而Miller算法和扩展欧几里得算法,则是把这个数学变成可执行代码的关键。
重要提醒:在实际工程中,千万不要自己实现双线性对。直接用OpenSSL或GMSSL的接口。我曾经见过一个团队自己手写Miller算法,结果在边界条件下出了bug,导致签名验证偶尔失败。这种问题极难排查。
好了,双线性对的内容就讲到这里。记住一句话:双线性对让椭圆曲线从"只能加"变成了"能加能乘",这就是SM9能实现基于身份密码的根本原因。