1. 引言
量子计算机可破解现有的公钥算法,如:
- 离散对数
- RSA
- 椭圆曲线。
在 NIST PQC 数字评估的第一轮中,Rainbow PQC签名的原始规范中设置的参数,在一台八核笔记本电脑上耗时约 50 小时即可被破解(详情见2022年2月26日 Breaking A (Crypto) Rainbow)。总体而言,Rainbow 采用多变量密码学方法,但缺乏强大的安全证明和较弱的参数集。
PROV(PRovable unbalanced Oil and Vinegar)(详情见:2023年 PROV: PRovable unbalanced Oil and Vinegar Specification v1.0 – 06/01/2023)使用基于多变量密码学的方法来创建后量子稳健 (Post Quantum Robust,PQC) 数字签名。虽然最近有针对多变量方法的攻击,但 PROV 提供了安全性证明。该证明类似于 MAYO 签名方案,其具有比 UOV(Unbalanced Oil and Vinegar)更大的oil space。UOV 方法最初由 Kipnis、Patarin 和 Goubin 定义(详情见:1999年论文 Unbalanced Oil and Vinegar Signature Schemes - Extended Version -),并将hash-and-sign 签名方案集成到 GPV 框架 (详情见:2008年论文 How to Use a Short Basis: Trapdoors for Hard Lattices and New Cryptographic Constructions) 中,在2022年论文 Probabilistic hash-and-sign with retry in the quantum random oracle model中被改编为多变量密码学方法。
PROV PQC签名方案,相关开源代码实现见:
一般来说,多变量密码学生成的签名相对较短,但公钥和私钥相对较长。
2. The Round 1 Additional Signatures
目前,Dilithium、FALCON 和 SPHINCS+ 已成为 NIST 数字签名标准,旨在取代 RSA、ECDSA 和 EdDSA。但是,NIST 希望有这些方法的替代方案,尤其是为了让不会过于依赖lattice-based算法(如 Dilithium 和 FALCON)。详情见Post-Quantum Cryptography: Digital Signature Schemes – Round 1 Additional Signatures:
- 多变量签名(10 个):3WISE、DME-Sign、HPPC(Hidden Product of Polynomial Composition)、MAYO、PROV(PRovable unbalanced Oil and Vinegar)、QR-UOV、SNOVA、TUOV(Triangular Unbalanced Oil and Vinegar)、UOV(Unbalanced Oil and Vinegar)和VOX。
- MPC-in-the-Head签名(7个):Biscuit、MIRA、MiRitH(MinRank in the Head)、MQOM(MQ on my Mind)、PERK、RYDE 和 SDitH(Syndrome Decoding in the Head)。
- Lattice-based签名(6个):EagleSign、EHTv3 和 EHTv4、HAETAE、HAWK、HuFu(Hash-and-Sign Signatures From Powerful Gadgets)和 SQUIRRELS(Square Unstructured Integer Euclidean Lattice Signature)。
- Code-based 签名(5个):CROSS(Codes and Restricted Objects Signature)、Enhanced pqsigRM、FuLeeca、LESS(Linear Equivalence)、MEDS(Matrix Equivalence Digital Signature)。
- Symmetric-based签名(4个):AIMer、Ascon-Sign、FAEST 和 SPHINCS-alpha。
- 其他签名(4个):ALTEQ、eMLE-Sig 2.0(Embedded Multilayer Equations with Heavy Layer Randomization)、KAZ-SIGN(Kriptografi Atasi Zarah)、Preon 和 Xifrat1-Sign。
- Isogeny 签名(1个):SQIsign。
RSA 加密方法使用两个素数的乘积来创建公共模数 (N)。不幸的是,如果使用量子计算机,N 的因式分解相当容易。因此,NIST 现在正在寻找可以取代 RSA 和 El Gamal 等其他方法的竞争者,以迎接量子计算机时代的到来。
目前经常使用对称加密(如 AES)进行主加密,然后使用非对称加密(如 RSA)来保护对称密钥和/或证明身份。如:
- 经常使用 RSA 来对身份进行签名(如使用私钥进行签名),然后使用关联的公钥来验证签名。
多变量多项式问题现在被应用于quantum robust密码学,其中创建一个trap door,能快速用 m 个方程(多变量多项式)求解 n 个变量。
可以使用的一种方案是 J. Patarin 创建的Unbalanced Oil and Vinegar方案。签名由多个方程式创建:
y1 = f(x1, x2… xn )
y2 = f(x1, x2 … xn )…
ym = f(x1, x2… xn )
其中y 1, y2,… ym是要签名的消息,x1, x2,… xn是该消息的签名。
一个简单的例子:
5 x+ 4y + 10 w + 9 z = 99
6 x+ 3y + 2 w + 3 z = 38
8 x + 2 y + 7 w + z = 51
x + 9 y + 4 w + 6 z = 57
消息为 99、38、51 和 57,签名为 5、4、10…6。
3. PROV 实现
PROV 的一个实现是:
对于 Dilithium、Falcon 和 SPHINCS+ 的密钥大小,以及与 PROV 相比的一系列additional Round 1 signatures,可知PROV的公钥和私钥比 Dilithium、Falcon 和 SPHINCS+ 大得多,但签名要小得多:
Method Public key size Private key size Signature size Security level
------------------------------------------------------------------------------------------------------
Crystals Dilithium 2 (Lattice) 1,312 2,528 2,420 1 (128-bit) Lattice
Crystals Dilithium 3 1,952 4,000 3,293 3 (192-bit) Lattice
Crystals Dilithium 5 2,592 4,864 4,595 5 (256-bit) Lattice
Falcon 512 (Lattice) 897 1,281 690 1 (128-bit) Lattice
Falcon 1024 1,793 2,305 1,330 5 (256-bit) Lattice
Sphincs SHA256-128f Simple 32 64 17,088 1 (128-bit) Hash-based
Sphincs SHA256-192f Simple 48 96 35,664 3 (192-bit) Hash-based
Sphincs SHA256-256f Simple 64 128 49,856
PROV-1 68,326 203,752 160 1 (128-bit) Multivariate
PROV-2 215,694 666,216 232 3 (192-bit) Multivariate
PROV-3 524,192 1,597,568 304 5 (256-bit) Multivar
PROV 的性能比 Dilithium 和 Falcon 弱很多(以运行周期计算):
Method Keygen Sign Verify
------------------------------------------------------------
Dilithium 2 300,751 1,081,174 327,362 (Unoptimized, Ref, Skylake)
Dilithium 3 544,232 1,713,783 522,267
Dilithium 5 819,475 2,383,399 871,609
Falcon-512 19,872,000 386,678 82,339 (Intel e5-8259U 2.3GHz)
Falcon-1024 63,135,000 961,208 205,128
PROV-1 1,171,537,400 38,962,000 52,797,800 Intel Core i5-7260U CPU at 2.20GHz
PROV-3 5,558,390,200 129,890,200 173,978,200
PROV-5 16,845,708,000 300,641,000 401,456,000
4. Oil and Vinegar
对于多变量密码学,多项式方程中有n 个变量。如,有四个变量(w、x、y、z)和二阶,有:(详情见2018年Brice Minaud Code-based, Multivariate and Hashbased Cryptography)
w² +4wx + 3x² + 2wy − 4wz + 2wx + 6xz = 387
一般来说,这是一个很难解决的问题,所以如果知道一个秘密,想让它变得简单。在这种情况下,知道其解是w =7、x =4、y =5和 z =6。可将其以矩阵形式表示。
该矩阵有一个trapdoor,可在其中定义vinegar and oil(醋和油)变量。醋变量是秘密的,只有我们知道,而油变量只有在知道醋变量的情况下才会被发现。trapdoor是为了不让oil变量混合,如果它们在矩阵中混合,将得到零(trapdoor):
为了包含得到的值,通常执行 (mod p ) 运算,其中p是素数。这被称为有限域,数字始终限制在 0 和p−1 之间。如,选择p=97,则有:
w²+4wx+3x²+2wy−4wz+2wx+6xz=5 (mod 97)
现在w、x、y、z有多个解,因此定义n 个多变量多项式。如:
w²+4wx+3x²+2wy−4xz+2wx+6xy=96 (mod 97)
5w²+3wx+3x²+4wy−xz+8wx+4xy=36 (mod 97)
4w²+5wx+3x²+2wy−5xz+3wx+6xy=95 (mod 97)
6w²+7wx+4x²+2wy−8xz+2wx+9xy=17 (mod 97)
由于变量值很大,这是一个众所周知的难以解决的问题。所以现在定义醋变量w和x以及油变量y和z。如果知道w和x ,就很容易确定油变量了。如,若w =7 且x =4,则有:
49+112+48+14y−16z+14z+24y=96 (mod 97)
245+84+48+28y−4z+56z+16y=36 (mod 97)
进而有:
209+38y−2z=96 (mod 97)
377+44y+52z=36 (mod 97)
进而有:
38y+95z=−113 (mod 97)
44y+52z=−341 (mod 97)
进而有:
38y+95z=81 (mod 97)
44y+52z=47 (mod 97)
这是一个简单的(mod形式)线性方程,可轻松求解。
可轻松地用y =5 和z =6 来解决这个问题。对应代码为(详情见:Oil and Vinegar Example):
import numpy as np
from inv import modMatInv
import sysp=97w=7
x=4
if (len(sys.argv)>1):
w=int(sys.argv[1])
if (len(sys.argv)>2):
x=int(sys.argv[2])if (len(sys.argv)>3):
p=int(sys.argv[3])def printM(M):
rtn = ""+str(M[0][0])+"w^2 + "+str(M[0][1]+M[1][0])+"wx + "+str(M[1][1])+"x^2 + "+str(M[0][2]+M[2][0])+"wy + "+str(M[1][3]+M[3][1])+"xz + " +str(M[0][3]+M[3][0])+"wz + "+str(M[1][2]+M[2][1])+"xy"
return rtndef revealM(M,w,x):
rtn = ""+str(M[0][0]*w*w) +" + "+str((M[0][1]+M[1][0])*w*x)+" + "+str(M[1][1]*x*x)+" + "+str((M[0][2]+M[2][0])*w)+"y + "+str((M[1][3]+M[3][1])*x)+"z + " +str((M[0][3]+M[3][0])*w)+"z + "+str((M[1][2]+M[2][1])*x)+"y"
return rtn
M0=[[1,2,1,1],[2,3,3,-2],[1,3,0,0],[1,-2,0,0]]
M1=[[5,2,1,2],[1,3,2,2],[3,2,0,0],[6,-3,0,0]]
M2=[[4,2,2,1],[3,3,3,-2],[0,3,0,0],[2,-3,0,0]]
M3=[[6,2,1,1],[5,4,3,-3],[1,6,0,0],[1,-5,0,0]]print ("p=",p)print ("\nM0:",M0)
print ("M1:",M1)
print ("M2:",M2)
print ("M3:",M3)# res = m . M0 . m^{-1}
res0=96
res1=36
res2=95
res3=17a=(res0-(M0[0][0]*(w*w)+(M0[0][1]+M0[1][0])*w*x + (M0[1][1])*x*x ) ) %p
b=(res1-(M1[0][0]*(w*w)+(M1[0][1]+M1[1][0])*w*x + (M1[1][1])*x*x ) ) %pfactor1=( ((M0[0][2]+M0[2][0])*w) + ((M0[1][2]+M0[2][1]) *x) ) %p
factor2=( ((M0[0][3]+M0[3][0])*w) + ((M0[1][3]+M0[3][1]) *x) ) %p
factor3=( (M1[0][2]+M1[2][0])*w) + ((M1[1][2]+M1[2][1]) *x) %p
factor4=( ((M1[0][3]+M1[3][0])*w) + ((M1[1][3]+M1[3][1])*x)) %pprint ("w=",w)
print ("x=",x)
print (printM(M0))
print (printM(M1))
print ()
print (revealM(M0,w,x))
print (revealM(M1,w,x))
print ()
print (str(factor1)+"y+"+str(factor2)+"z="+str(a))
print (str(factor3)+"y+"+str(factor4)+"z="+str(b))
print ()
A = np.array([[factor1,factor2], [factor3,factor4]])
B = np.array([a,b])invA = modMatInv(A,p)print (invA)res = np.dot(invA,B) % p
print ("y=",res[0])
print ("z=",res[1])
示例有:
p= 97
M0: [[1, 2, 1, 1], [2, 3, 3, -2], [1, 3, 0, 0], [1, -2, 0, 0]]
M1: [[5, 2, 1, 2], [1, 3, 2, 2], [3, 2, 0, 0], [6, -3, 0, 0]]
M2: [[4, 2, 2, 1], [3, 3, 3, -2], [0, 3, 0, 0], [2, -3, 0, 0]]
M3: [[6, 2, 1, 1], [5, 4, 3, -3], [1, 6, 0, 0], [1, -5, 0, 0]]
w= 7
x= 4
1w^2 + 4wx + 3x^2 + 2wy + -4xz + 2wz + 6xy=96 (mod 97)
5w^2 + 3wx + 3x^2 + 4wy + -1xz + 8wz + 4xy=36 (mod 97)
49 + 112 + 48 + 14y + -16z + 14z + 24y=96 (mod 97)
245 + 84 + 48 + 28y + -4z + 56z + 16y=36 (mod 97)
38y+95z=81
44y+52z=47
Inverse matrix:
[[63. 36.]
[81. 5.]]
y= 5.0
z= 6.0
5. 结论
PROV 具有安全性证明,这在 NIST 评估中将起到很大作用。它也能生成短签名,但其弱点是性能和密钥对较大。
参考资料
[1] Prof Bill Buchanan OBE FRSE 2024年7月12日博客 Provable Security With Oil and Vinegar