CRYSTALS-Dilithium

news2024/11/18 16:24:53

文章目录

简介

CRYSTALS-Dilithium是一种后量子密码学中的数字签名算法。它是由PQClean项目组中的Bernstein、Dahmen、Lange、Nickels和Schneider设计的,并且是NIST PQC竞赛中的一个获胜者。

Dilithium通过使用参数集、哈希函数和多项式函数来进行安全设计。参数集(params)定义了多项式的大小、参数Q(用于压缩表示和NTT域中的数值大小)、参数K(矩阵A中每行的非零系数数)等等。哈希函数用于将消息哈希为要签名的多项式。多项式函数用于执行NTT变换、多项式加法和减法以及其它操作。

CRYSTALS-Dilithium还包括一些安全性和性能保证。它具有强的安全性,能够在处理大量消息时保持高效率。此外,它还包括一些实现指南和支持文档,以帮助在各种应用中正确使用它。

PQClean项目组是一个由密码学家和程序员组成的自愿者团队,致力于实现并标准化后量子密码学算法。该团队的目标是提供经过仔细设计和实现的密码库,以促进后量子时代的安全通信和计算。他们的工作受到了标准化组织NIST的支持和认可,并已成为后量子时代算法的主要参考实现之一。

1和2版本区别

我们首先描述Dilithium的第一轮提交和当前版本之间的区别。我们所做的唯一概念设计更改是允许该方案是随机化的或确定性的选项(而第一轮版本仅为确定性的)。两个版本之间的差异是一行代码,其中一个种子是随机选择的(在随机化版本中),或者作为密钥和消息的哈希值(在确定性版本中)。为了允许确定性和随机化版本之间的这个小差异,函数ExpandMask现在以48字节的种子作为输入,而不是密钥和消息。作为一个小的额外更改,我们还协调了矩阵A,掩蔽向量y和秘密向量s1,s2的各种扩展函数的nonce,使其都为16位整数。

我们对签名算法进行了各种优化,其中最重要的优化是拒绝条件的计算方式,它基于向量w的低位部分和提示向量。我们的AVX2优化实现现在更多地使用向量化,并包括使用宏的简化汇编NTT实现。

此外,我们还引入了一个版本的算法,它使用AES而不是SHAKE来从种子扩展公共矩阵A、秘密向量s1、s2和屏蔽向量y。这主要是为了展示我们的方案在硬件支持SHAKE广泛可用后(如AES一样)的提高效率。

2和3的区别

  • 将前两个参数集(使用 4 × 3 和 5 × 4 公钥矩阵)合并为一个 NIST 二级参数集,其中包含一个 4 × 4 公钥矩阵。我们还引入了一个五级参数集。
  • 我们现在不总是输出具有60个非零系数(从而具有257位熵)的挑战多项式,而是输出具有39个和49个非零系数的多项式,它们在安全级别2和3中分别具有192和225位熵。这种熵对于相应的安全级别已经足够了(因为在证明中只需要第二前像抵抗),并且具有在一定程度上减少拒绝概率的效果。
  • 将公钥中被抛弃的比特数从14降低到13,这会提高该方案的SIS难度,但代价是公钥大小略微增加。
  • 现在,遮罩多项式y是从一个范围内进行采样,其中每个系数都有2的幂次方个可能性,这使得采样明显更容易实现。由于之前的范围已经非常接近2的幂次方了,因此这个变化对方案的安全性没有影响。
  • 改变了挑战值c的采样和传输方式。现在它采用两个阶段采样。在第一阶段,证明者创建一个哈希值并输出一个32字节的挑战种子 ~c,这就是包含在签名中的。然后使用SHAKE函数以 ~c 作为种子创建签名方案中使用的多项式挑战值。这样可以减小签名的大小,减少了8个字节。
  • 这个更新的内容是对方案的安全性分析进行了更新,采用门成本指标,基于近期关于预测格算法行为和成本方面的进展提供了更精细的估计。
  • 对 NIST 3 级别的参数集进行了一些小的杂项更改。

1.介绍

我们提出了数字签名方案Dilithium,其安全性基于在格中找到短向量的难度。我们的方案设计考虑以下几个标准:

  1. 易于安全实现。最紧凑的基于格的签名方案[DDLL13, DLP14]关键在于需要从离散高斯分布中生成秘密随机数。以安全的方式生成这样的样本非常复杂,很容易导致不安全的实现,如[ BHLY16,EFGT17,PBY17]中所示。虽然可能存在非常谨慎的实现可以防止此类攻击,但假设普遍部署的方案包含许多微妙之处,始终精通地实现是不合理的。因此,Dilithium仅使用均匀采样,正如[Lyu09,GLP12]中最初提出的那样。此外,所有其他操作(例如多项式乘法和舍入)都可以以恒定的时间轻松实现。
  2. 谨慎选择参数。因为我们的目标是长期安全,所以我们从攻击者的有利角度分析了格攻击的适用性。特别地,我们考虑了空间需求与时间需求同阶的(量子)算法。目前这样的算法是不现实的,似乎有严重的障碍阻碍了移除空间需求的可能性,但我们允许未来可能会出现改进。
  3. 证书链(certificate chain),也称证书路径(certificate path),是一系列数字证书的序列,用于建立数字证书的信任链。每个数字证书都包含公钥和签名,这些签名用于验证其真实性和可信度。证书链由多个数字证书连接在一起,形成一条从根证书到目标证书的路径,每个证书都由下一个证书颁发机构(CA)签名。这个过程一直持续到根证书,根证书由一个受信任的根CA签名,可以被所有信任这个CA的实体信任。证书链的目的是建立数字证书的信任体系,确保数字通信的安全性和可信度。
  4. 模块化——变化安全性。几乎构成签名和验证过程全部内容的两个操作是 XOF 扩展(我们使用 SHAKE-128 和 SHAKE-256),以及在多项式环 Zq [X]/(Xn+1) 中的乘法。我们方案高效的实现需要优化这些操作,并确保它们以常数时间运行。对于所有安全级别,我们的方案使用相同的环,其中 q = 223 − 213 + 1,n = 256。变化安全性只是涉及在该环上执行更多/更少的操作,以及执行更多/更少的 XOF 扩展。换句话说,一旦对某个安全级别获得了优化的实现,就很容易获得更高/更低级别的优化实现。

1.1基本方法概述

该方案的设计基于“Fiat-Shamir with Aborts”方法[Lyu09,Lyu12],与[GLP12,BG14]中提出的方案最相似。对于不熟悉此类签名方案的读者,我们在图1中展示了我们方案的简化(效率较低)版本。该版本是从[BG14]的方案稍作修改得来的。我们将逐个介绍其组成部分,以便读者了解此类方案的工作原理。
没有公钥压缩的签名方案模板
没有公钥压缩的签名方案模板

密钥生成算法

生成一个k×l矩阵A,其中每个条目都是环Rq= Zq[X]/(Xn+1)中的多项式。如先前提到的,我们将始终有q = 223−213 +1和n = 256。然后,该算法会对随机密钥向量s1和s2进行采样。这些向量的每个系数都是Rq中具有最多η大小的小系数的元素。最后,公钥的第二部分被计算为t = As1 + s2。这个方案中的所有代数运算都假定在多项式环Rq上进行。

签名过程

签名算法生成一个多项式掩码向量y,其中各系数小于γ1。参数γ1是有策略地设置的,它足够大,使得最终签名不会泄露秘密密钥(即签名算法是零知识的),但也足够小,使得签名不易伪造。然后,签名者计算Ay并将w1设置为此向量中系数的“高阶”位。特别地,Ay中的每个系数w都可以以规范方式写为w = w1·2γ2 + w0,其中|w0|≤γ2;w1是包含所有w1的向量。随后,挑战c被创建为消息和w1的哈希。输出c是一个在Rq中的多项式,恰好有τ个±1和其余为0。之所以采用这种分布,是因为c具有小的范数,并且来自大小为log2 (256 / τ) + τ的域,我们希望其在128和256之间。然后,潜在签名被计算为z = y + cs1。

如果直接输出z,则签名方案将不安全,因为秘密密钥将被泄露。为避免z对秘密密钥的依赖性,我们使用拒绝抽样。参数β设置为csi的最大可能系数。由于c具有τ个±1,而si中的最大系数为η,因此很容易看出β≤τ·η。如果z中的任何系数大于γ1−β,则我们拒绝并重新开始签名过程。此外,如果Az−ct的低阶位的任何系数大于γ2−β,则我们也重新开始。第一个检查对于安全性是必要的,而第二个检查对于安全性和正确性都是必要的。签名过程中的while循环会一直重复,直到满足前两个条件为止。参数被设置得使预期的重复次数不太高(例如大约为4次)。

验证

验证者首先计算 w 1 ′ w_1^{'} w1,即Az−ct的高位比特,并且如果z的所有系数都小于γ1−β并且c是消息和 w 1 ′ w_1^{'} w1的哈希值,则接受。让我们看看为什么验证可行,特别是为什么HighBits(Az−ct,2γ2)=HighBits(Ay,2γ2)。首先要注意的是Az−ct = Ay−cs2。因此,我们需要证明的是
在这里插入图片描述
理由是一个有效的签名将有 || LowBits(Ay-cs2, 2γ2) || ∞ < γ2-β。由于我们知道cs2的系数更小,因此我们知道添加cs2不足以通过增加任何低阶系数的幅度至少为γ2来导致任何进位。因此,公式(1)成立,签名可以正确验证。

1.2Dilithium

图1中的基本模板本身相当低效。最明显(但很容易解决)的低效率是,公钥由k·`个多项式的矩阵组成,其表示可能非常大。解决方法是简单地使用SHAKE-128从某些种子ρ生成A,这是一种标准技术。因此,公钥为(ρ, t),其大小由t主导。Dilithium相对于之前的方案(例如[BG14]和qTESLA[ABB+19],后者是[BG14]框架的一个特定实例)的新颖之处在于,我们还通过增加不到100字节的签名来缩小了t的位表示大小超过两倍。

获得这种非常有利的权衡的主要观察是,当验证者在第13行计算 w 1 ′ w_1^{'} w1时,Az−ct的高位比特不太依赖于t的低位比特,因为t正被一个非常低重量的多项式c乘以。在我们的方案中,t的某些低位比特没有包含在公钥中,因此验证者无法始终正确计算Az−ct的高位比特。为了弥补这一点,签名者在签名中包括了一些“提示”,它们本质上是由于将c与t的缺失低位比特的乘积加入所引起的进位。有了这个提示,验证者就能够正确计算 w 1 ′ w_1^{'} w1

此外,我们提供了一种使用标准技术使我们的方案具有确定性的选项,即将种子添加到密钥中,并使用该种子与消息一起生成 Line 07 中的随机数y。Kiltz等人[KLS18]最近的结果表明,对于相同消息,攻击者看到的不同签名越少,在量子随机预言模型下,签名方案与基础困难假设之间的约束就越紧。虽然目前尚不清楚是否存在针对随机签名的改进量子攻击,但我们建议将确定性版本作为默认选项,除非在攻击者可以利用确定性的侧信道攻击的情况下 [SBB+18, PSS+18]。我们在Fig. 4中的完整方案还利用了基本的优化技巧,如预处理消息M,以避免在每次签名尝试时都重新处理它。

实现注意事项

该方案中进行的主要代数运算是将矩阵A与向量y相乘,其中矩阵A的元素是在Zq[X]/( X 256 X^{256} X256 + 1)上的多项式,向量y也是如此。在我们的NIST Level 3参数设置中,矩阵A是一个6×5矩阵,因此由30个多项式组成。因此,乘法Ay涉及30个多项式乘法。与许多基于多项式环上运算的基于格的方案一样,我们选择了环,使得乘法操作可以通过数论变换(NTT)实现,这只是一个在有限域Zq上而不是复数上工作的FFT版本。为了启用“完全分裂”NTT算法,我们需要选择一个质数q,使得群Z∗q具有阶数2n = 512;或者等价地,q ≡ 1 (mod 512)。如果r是这样一个元素,则X 256 + 1 = (X−r)(X− r 3 r^3 r3) ···(X− r 511 r^{511} r511),因此可以等效地将任何多项式a ∈ Zq[X]/( X 256 X^{256} X256+1)表示为其CRT(中国剩余定理)形式,如(a®,a(r3),… ,a(r2n-1))。这种表示的优点是两个多项式的乘积是按坐标进行的。因此,多项式乘法的最昂贵的部分是变换a → a ^ \hat{a} a^和逆变换 a ^ \hat{a} a^ →a,这些是NTT和逆NTT操作。

以上提到使用NTT表示的优势更加明显,因为在执行矩阵乘法Ay时,需要计算的NTT数量比矩阵的维数少得多。由于矩阵是均匀随机的,因此可以将其生成(并存储)为NTT形式。将向量y∈ R q 5 R_q^5 Rq5转换为NTT表示形式只需要进行5次NTT计算,然后进行逐点乘法计算以获得NTT形式的Ay,最后进行6次逆NTT乘法计算。
另一个耗时的操作是将种子ρ扩展为多项式矩阵A。矩阵A用于签名和验证,因此SHA-KE-128的良好实现对方案的效率很重要。

我们使用整数算术来进行 AVX2 优化的NTT的实现。虽然我们将4个系数打包成一个256位的vector,这与浮点实现使用的密度相同,但我们可以将乘法速度提高约2倍。我们通过仔细安排指令和在NTT期间交错乘法和还原来隐藏部分乘法延迟来实现了这个加速。

安全性。

遵循[Lyu12]的基本方法,可以在随机预言机模型(Random Oracle model, ROM)下证明图1中签名方案的安全性,基于两个问题的难度。第一个问题是标准的LWE(多项式环上)问题,它要求区分(A,t:=As1+s2)和(A,u),其中u是均匀随机的。另一个问题是[KLS18]中称为SelfTargetMSIS问题,它是找到一个具有小系数的向量 [ z , c , v ] T [z,c,v]^T [zcv]T和一个消息(摘要)µ,使得
在这里插入图片描述
其中 A 和 t 均为均匀随机的矩阵和向量,I 为单位矩阵。在 ROM 中,可以使用分叉引理 [PS00,BN06] 从标准的 MSIS 问题(查找具有满足 Az0 = 0 的小系数的 z0)到 SelfTargetMSIS 中获得(非紧密的)约简。可以按照这个确切的方法,基于 MLWE 和 SIS 的困难性证明 Dilithium 在 ROM 中的安全性。

在量子随机预言机(QROM)模型中,敌手可以在超position中查询H,情况有些不同。在[KLS18]中表明,即使方案是确定性的,Dilithium在QROM中仍基于MLWE和SelfTargetMSIS,即使在密集化情况下也可以进行紧凑约减。但是,我们不能再直接使用分叉引理(因为它是一种类型的回绕)从MSIS到SelfTargetMSIS提供量子约减。仍然有很好的理由相信SelfTargetMSIS问题以及Dilithium在QROM中是安全的。首先,没有使用Fiat-Shamir变换从Σ-协议构建的自然签名方案在ROM中是安全的但在QROM中不是安全的。其次,可以设置Dilithium的参数(同时保持方案设计不变),使得SelfTargetMSIS问题变得信息论上难解,因此仅基于MLWE使该版本的Dilithium在QROM中安全。[KLS18]中的此类参数的实例化导致具有2X签名和5X公钥的方案。虽然我们认为这不是一个很好的权衡,但这种方案的存在使我们对优化的Dilithium的安全性更有信心。

最近,有两项新工作进一步缩小了在ROM和QROM中的安全性差距。[DFMS19]的工作表明,如果底层的Σ-协议是collapsing并具有特殊的soundness性质,则其Fiat-Shamir变换是在QROM中安全的签名。Dilithium Σ-协议的特殊soundness是由MSIS的难度直接导出的[Lyu12,DKL + 18]。此外,[DFMS19]猜测Dilithium Σ-协议是collapsing的。[LZ19]的工作进一步表明,collapsing属性确实具有从MLWE的约简性质。尽管这个约简性质不是特别紧密,但它确实进一步证实了Dilithium的构造或通过Fiat-Shamir框架构建的任何自然方案的本质安全性。在我们看来,证据显然越来越多,即在ROM和QROM中安全的签名之间的区别将很快像在标准模型和ROM中安全的方案之间的区别一样被视为理论上的差异,但实际上安全性将是相同的。

表格1
Dilithium的输出大小、安全性和性能。公钥和签名的大小公式在第5.4节中给出。SIS安全性中括号内的数字是针对强不可伪造(即对于已经见过的消息/签名对难以产生第二个不同的签名)版本的签名方案,其中系数长度来自于方程(8),而非未括号的方程(7)。由于拒绝采样,中位数和平均签名时间之间有明显差异,因此我们两者都进行了测量。
在这里插入图片描述

基础操作

环操作

本文中,我们使用 R 和 Rq 表示环 Z[X]/(Xn + 1) 和 Zq[X]/(Xn + 1),其中 q 是整数,n 的值始终为 256,q 是素数 8380417 = 2 23 2^{23} 223 2 13 2^{13} 213 + 1。正常字体的字母表示 R 或 Rq 中的元素(包括 Z 和 Zq 中的元素),粗体小写字母表示在 R 或 Rq 中具有系数的列向量。默认情况下,所有向量都是列向量。粗体大写字母表示矩阵。对于向量 v v T {\bf v^T} vT 表示其转置。布尔运算符 statement 的值为 1,如果 statement 为 true,则为 0。

模约简。

对于偶(奇)正整数 α \alpha α,我们定义 r 0 = r m o d    ± α r_0=r\mod\pm\alpha r0=rmod±α为唯一的 r 0 r_0 r0,满足 − α / 2 < r 0 ≤ α / 2 -\alpha/2<r_0\leq\alpha/2 α/2<r0α/2 − ( α − 1 ) / 2 ≤ r 0 ≤ ( α − 1 ) / 2 -(\alpha - 1)/2\leq r_0\leq (\alpha - 1)/2 (α1)/2r0(α1)/2),例如 r 0 ≡ r m o d    α r_0\equiv r\mod\alpha r0rmodα。我们有时将其称为模 α \alpha α方的中心约简。对于任何正整数 α \alpha α,我们定义 r 0 ≡ r m o d    α r_0\equiv r\mod\alpha r0rmodα为唯一的 r 0 r_0 r0,满足 0 ≤ r 0 < α 0\leq r_0<\alpha 0r0<α,且 r 0 ≡ r m o d    α r_0\equiv r\mod\alpha r0rmodα。当精确表示不重要时,我们简单地写成 r m o d    α r\mod\alpha rmodα

元素的大小

在这里插入图片描述

NTT域表示

我们选择模数q,以便存在一个关于q的512次本原单位根r。具体地,我们始终使用r = 1753。这意味着分圆多项式 X 256 X^{256} X256 + 1在模q意义下分解为线性因子X − r i r_i ri(i = 1, 3, 5, …, 511)。根据中国剩余定理,我们的分圆环Rq因此同构于环的乘积 Z q [ X ] / ( X − r i ) ≈ Z q Z_q[X]/(X-r_i)\approx Z_q Zq[X]/(Xri)Zq。在这个环的乘积中,由于乘法是逐点的,因此易于乘法操作。这个同构关系为:
在这里插入图片描述
这个同构可以利用快速傅里叶变换快速计算。由于 X 256 + 1 = X 256 − r 256 = ( X 128 − r 128 ) ( X 128 + r 128 ) X^{256}+1=X^{256}-r^{256}=(X^{128}-r^{128})(X^{128}+r^{128}) X256+1=X256r256=(X128r128)(X128+r128),因此可以先计算映射:
在这里插入图片描述
然后单独继续处理度小于128的两个约简多项式,注意到 X 128 + r 128 = X 128 − r 384 X^{128}+r^{128}=X^{128}-r^{384} X128+r128=X128r384。在这种情况下,快速傅里叶变换也称为数论变换(NTT),其中地面场是有限场。自然的快速NTT实现不会输出具有按 a ( r ) a(r) a(r) a ( r 3 ) a(r^3) a(r3),…, a ( r 511 ) a(r^{511}) a(r511)排序的系数的向量。因此,定义NTT域表示a ^ = NTT(a)∈Z_256 q表示多项式a的NTT域表示,其系数按照我们参考NTT的输出排序。
在这里插入图片描述
其中ri = r b r v ( 128 + i ) r^{brv(128+i)} rbrv(128+i),其中brv(k)是8位数字k的位翻转。使用这种表示法,由于同构属性,我们有ab = NTT−1(NTT(a)NTT(b))。对于向量y和矩阵A,表示yˆ = NTT(y)和Aˆ = NTT(A)表示y和A的每个多项式yi和ai,j都在NTT域表示中。我们在第5.6节中详细介绍了NTT的实现。

2.3 Hashing

signature

Gen

ζ ← { 0 , 1 } 256 \{{0, 1\}}^{256} {0,1}256

ζ 被赋值为一个 256 位的二进制数列,每个元素的取值范围为 {0, 1}。

(ρ, ρ’, K) ∈ { 0 , 1 } 256 \{{0, 1\}}^{256} {0,1}256 × { 0 , 1 } 256 \{{0, 1\}}^{256} {0,1}256 × { 0 , 1 } 256 \{{0, 1\}}^{256} {0,1}256 := H(ζ) H is instantiated as SHAKE-256

这个句子是在描述一个哈希函数 H,它接受一个 256 位的输入 ζ,并输出三个 256 位的二进制数 ρ \rho ρ, ρ ′ \rho' ρ, K。其中 ρ \rho ρ ρ ′ \rho' ρ 是 H 的输出的前两个值,而 K 是 H 的输出的最后一个值。这些值的二进制位是由输入 ζ 和 SHAKE-256 算法共同决定的,因此可以视为是随机生成的。

A ∈ R q k × l R^{k \times l}_q Rqk×l := ExpandA(ρ) A is generated and stored in NTT Representation as A ^ \hat{A} A^

A ∈ R q k × l R^{k \times l}_q Rqk×l := ExpandA(ρ) 表示生成一个 k × l k \times l k×l的矩阵A,每个元素都是从 q q q的剩余类 R q R_q Rq中随机选择的。这里的 R q R_q Rq是一个大小为 q q q的环,表示在模 q q q意义下的所有整数。而ExpandA(ρ)是一个根据输入 ρ \rho ρ生成矩阵A的函数。在实现中,这个矩阵通常以NTT表示法存储,即矩阵A的每个元素都是模NTT模数的剩余类。因此,我们可以将A表示为 A ^ \hat{A} A^

(s1, s2) ∈ S η l S_η^l Sηl × S η k S_η^k Sηk := ExpandS( ρ ′ \rho' ρ)

这句话表示一个元组 ( s 1 , s 2 ) (s_1, s_2) (s1,s2)属于两个集合, s 1 s_1 s1属于集合 S η l S_η^l Sηl s 2 s_2 s2属于集合 S η k S_η^k Sηk。同时这个元组的值是通过将输入参数 ρ ′ \rho' ρ作为种子,通过某种函数ExpandS生成的。具体来说, s 1 s_1 s1 s 2 s_2 s2都是 l l l位和 k k k位的向量,向量的每个元素都是来自有限集合 − η , … , η {-η, \dots, η} η,,η中的一个整数。
集合 S η l S_η^l Sηl是一个有限集合,包含所有 − η , − η + 1 , ⋯   , η − 1 , η {-η, -η + 1, \cdots, η - 1, η} η,η+1,,η1,η中的整数 l l l个元素的所有 l l l元组。

t := A s 1 s_1 s1 + s 2 s_2 s2

这行代码的意思是将矩阵 A A A和向量 s 1 s_1 s1做矩阵乘法,再加上向量 s 2 s_2 s2,得到向量 t t t。其中, A A A是一个 k × l k \times l k×l的矩阵, s 1 s_1 s1是一个 l l l维向量, s 2 s_2 s2是一个 k k k维向量, t t t是一个 k k k维向量。在这里,我们可以将 A A A看作一个公钥, s 1 s_1 s1 s 2 s_2 s2看作私钥的一部分, t t t是签名的一部分。

为什么t是签名的一部分

在这个签名方案中,对于给定的消息,签名过程需要使用一组秘密密钥 ( ρ , ρ ′ , s ) (\rho, \rho', s) (ρ,ρ,s) 生成一个签名 ( z ^ , t ) (\hat{z}, t) (z^,t). 其中 t t t 是与公钥 A A A 和秘密密钥 s 1 , s 2 s_1, s_2 s1,s2 相关的一个向量,它在签名验证过程中起到关键作用。因此, t t t 必须作为签名的一部分被包含在内。

( t 1 t_1 t1, t 0 t_0 t0) := P o w e r 2 R o u n d q Power2Round_q Power2Roundq(t, d)

( t 1 , t 0 ) (t_1, t_0) (t1,t0)是从向量 t t t中获取的。这个向量 t t t是由矩阵 A A A和向量 s 1 , s 2 s_1, s_2 s1,s2的线性组合得到的,即 t = A ⋅ s 1 + s 2 t=A\cdot s_1 + s_2 t=As1+s2。由于 t t t中的元素可能大于 q q q,需要将其映射到模 q q q的范围内。函数 P o w e r 2 R o u n d q ( t , d ) Power2Round_q(t, d) Power2Roundq(t,d)执行了这个映射,并返回了两个向量 t 1 t_1 t1 t 0 t_0 t0,其中 t 1 t_1 t1的元素都是 q q q d d d次幂的整数倍,而 t 0 t_0 t0的元素是剩余的元素。在这里, d d d是方案参数之一,用于控制这个映射的精度。这个映射可以帮助我们在保证签名安全的同时,减小签名的大小。

tr ∈ { 0 , 1 } 256 \{{0, 1\}}^{256} {0,1}256 := H(ρ || t 1 t_1 t1)

这段代码的意思是将 ( ρ , t 1 ) (\rho, t_1) (ρ,t1)串接起来,输入到哈希函数 H H H中进行哈希运算,得到一个256比特的哈希输出值 t r tr tr。其中, ∣ ∣ || ∣∣表示将两个比特串连接起来形成一个更长的比特串的操作。

return (pk = (ρ, t 1 t_1 t1), sk = (ρ, K, tr, s 1 s_1 s1, s 2 s_2 s2, t 0 t_0 t0))

return语句返回了公钥和私钥。其中,公钥pk由元组(ρ, t 1 t_1 t1)组成,私钥sk由元组(ρ, K, tr, s 1 s_1 s1, s 2 s_2 s2, t 0 t_0 t0)组成。具体来说:

公钥pk中,ρ是哈希函数H的输入, t 1 t_1 t1是签名的一部分;
私钥sk中,ρ是哈希函数H的输入,K是私钥,tr是另一个哈希函数H’的输出, s 1 s_1 s1 s 2 s_2 s2是随机向量, t 0 t_0 t0是签名的一部分。
在后续的签名和验证过程中,私钥将用于生成签名,公钥将用于验证签名。

签名算法

A ∈ R q k × l R^{k \times l}_q Rqk×l := ExpandA(ρ) A is generated and stored in NTT Representation as A ^ \hat{A} A^

这段代码在Dilithium签名方案的签名算法中表示根据私钥中的 ρ \rho ρ和公钥中的 l l l k k k,使用密钥扩展算法ExpandA(ρ)生成一个矩阵A,然后对这个矩阵进行NTT变换并存储在NTT表示中,即 A ^ \hat{A} A^

μ ∈ { 0 , 1 } 256 : = H ( t r ∣ ∣ M ) \mu \in \{{0, 1\}}^{256} := H(tr\mathbin|\mathbin| M) μ{0,1}256:=H(trM)

其中 ∣ \mathbin| 表示将两个二进制串拼接起来。这个式子表示将消息 M M M 和追踪器 t r tr tr 一起哈希成一个256比特的二进制串作为 μ \mu μ 值。

κ \kappa κ = 0, ( z , h ) (z, h) (z,h) = ⊥ \perp

这段代码表示将变量 κ \kappa κ 赋值为0,同时将元组 ( z , h ) (z, h) (z,h) 赋值为 ⊥ \perp ,表示它们还没有被定义或初始化。

ρ ′ \rho' ρ { 0 , 1 } 256 \{{0, 1\}}^{256} {0,1}256 := H(K || µ) (or ρ ′ \rho' ρ { 0 , 1 } 256 \{{0, 1\}}^{256} {0,1}256 for randomized signing)

这段代码表示在 Dilithium 签名方案中的密钥生成算法中, ρ ′ \rho' ρ 被赋值为哈希值 H(K || µ) 的结果。其中,K 是一个密钥,µ 是消息的哈希值。如果使用随机签名,则将 ρ ′ \rho' ρ 随机生成。

while (z, h) = ⊥ do Pre-compute s 1 ^ \hat{s_1} s1^ := NTT( s 1 s_1 s1), s 2 ^ \hat{s_2} s2^:= NTT( s 2 s_2 s2), and t 0 ^ \hat{t_0} t0^ := NTT( t 0 t_0 t0)

这段代码的作用是为了准备一些NTT(Number Theoretic Transform)表示的值,以便后面进行处理。具体来说, s 1 ^ \hat{s_1} s1^ s 2 ^ \hat{s_2} s2^ t 0 ^ \hat{t_0} t0^ 分别是 s 1 s_1 s1 s 2 s_2 s2 t 0 t_0 t0 的 NTT 表示形式,预先计算这些值可以提高后面的计算效率,因为 NTT 可以加速一些多项式运算。此外,while 循环的条件是 ( z , h ) (z,h) (z,h) 为 ⊥,即当 ( z , h ) (z,h) (z,h) 被赋值后,循环会结束。

y ∈ S γ 1 l S^l_{{\gamma}_1} Sγ1l := ExpandMask( ρ ′ \rho' ρ, κ \kappa κ)

表示从 ρ ′ \rho' ρ κ \kappa κ 生成一个长度为 l l l 的掩码 y y y。在 Dilithium 签名方案中,掩码 y y y 的作用是用于隐藏签名消息 m m m 和签名密钥的哈希值 μ \mu μ,从而防止敌手获取签名者的私密信息。ExpandMask 函数通过将 ρ ′ \rho' ρ κ \kappa κ 哈希后再进行特定计算,得到了掩码 y y y

w := Ay --------------w := N T T − 1 ( A ^ ⋅ N T T ( y ) ) NTT^{−1}(\hat{A} · NTT(y)) NTT1(A^NTT(y))

首先,从之前的步骤中,我们获得了展开的密钥 ρ ′ \rho' ρ 和掩码 κ \kappa κ。接下来,我们使用 ρ ′ \rho' ρ κ \kappa κ 生成一个向量 y y y,其中 y y y 属于集合 S γ 1 l S_{{\gamma}_1}^l Sγ1l,即 y y y 的每个元素都是 γ 1 {\gamma}_1 γ1 位的整数。

然后,我们使用向量 y y y 和展开的矩阵 A A A(通过调用 ExpandA(ρ) 函数生成),计算向量 w w w。其中, A A A 是一个 k × l k \times l k×l 的矩阵, y y y 是一个 l l l 维的向量。我们首先将 y y y A A A 转换为 NTT 表示形式,然后计算 A ^ ⋅ N T T ( y ) \hat{A}·NTT(y) A^NTT(y),最后将结果转换回常规表示形式得到向量 w w w

因此,这段代码主要用于计算签名中的一个重要部分 w w w

w 1 w_1 w1 := H i g h B i t s q ( w , 2 γ 2 ) HighBits_q(w, 2\gamma_2) HighBitsq(w,2γ2)

这行代码中的 H i g h B i t s q HighBits_q HighBitsq 函数是指将输入的元素取模 q q q 之后,只保留最高的 2 γ 2 2\gamma_2 2γ2 位,即返回 w w w 中最高的 2 γ 2 2\gamma_2 2γ2 位。其中 γ 2 \gamma_2 γ2 是 Dilithium 签名方案中的一个参数,通常取值为 60 60 60。这个操作的目的是将 w w w 中的噪声掩码掩盖住,只保留 w w w 中的有效信息,从而增强签名的安全性。

c ∈ { 0 , 1 } 256 : = H ( κ \{{0, 1\}}^{256} := H(\kappa {0,1}256:=H(κ || w_1)$

这行代码在 Dilithium 签名方案的签名算法中的作用是生成签名中的一个值 c c c。具体来说,该行代码将一个256比特的哈希值赋值给 c c c,其中哈希输入由密钥生成过程中生成的随机值 κ \kappa κ w 1 w_1 w1 组成。 w 1 w_1 w1 w w w 的高 2 γ 2 2\gamma_2 2γ2 位, w w w 是由矩阵 A A A 和掩码 y y y 计算得出的值,代表了消息的某种哈希。 c c c 是签名中的一个挑战值,用于验证签名的正确性。

c ∈ B τ Bτ Bτ := SampleInBall( c ^ \hat{c} c^) ---- Store c in NTT representation as c ^ \hat{c} c^ = NTT( c )

这行代码在Dilithium签名方案的签名算法中,是用来生成签名中的附加噪音项 c c c的。其中 B τ Bτ Bτ表示一个球上的离散高斯分布, c ^ \hat{c} c^表示 c c c在NTT表示中的值。SampleInBall函数会从 B τ Bτ Bτ分布中采样一个随机的 c ^ \hat{c} c^,并将其转换为 c c c的NTT表示 c ^ \hat{c} c^,最终返回 c c c的NTT表示。这个附加噪音 c c c对签名的安全性非常重要,可以有效防止攻击者对签名进行反演攻击。

z := y + c s 1 cs_1 cs1 ------------ Compute c s 1 s_1 s1 as N T T − 1 ( c ^ ⋅ s 1 ^ ) NTT^{-1}(\hat{c} · \hat{s_1}) NTT1(c^s1^)

这行代码在Dilithium签名方案的签名算法中表示计算签名的过程, z z z 是一个向量,它是随机掩码 y y y 和校验和 c s 1 cs_1 cs1 的和,其中 c c c 是签名中的一个参数。

z : = y + c s 1 z := y + cs_1 z:=y+cs1 表示计算签名中的 z z z 值,即掩码和。具体来说, ρ ′ \rho' ρ κ \kappa κ 由密钥生成算法生成并传递给签名算法,在签名算法中使用 ρ ′ \rho' ρ κ \kappa κ 生成 y y y,并将 y y y 和签名中的随机数 s 1 s_1 s1 组合成 z z z。其中, c c c 是由 w 1 w_1 w1 计算得到的签名哈希值,而 s 1 s_1 s1 是由密钥生成算法生成的随机数。最终,使用 c c c s 1 s_1 s1 计算出 c s 1 cs_1 cs1,并将其加入 y y y 中,得到 z z z

r 0 : = L o w B i t s q ( w − c s 2 , 2 γ 2 ) r_0 := LowBits_q(w − cs_2, 2\gamma_2) r0:=LowBitsq(wcs2,2γ2) ------------ Compute c s 1 s_1 s1 as N T T − 1 ( c ^ ⋅ s 1 ^ ) NTT^{-1}(\hat{c} · \hat{s_1}) NTT1(c^s1^)

这段代码计算签名 r 0 r_0 r0的值,它是用于保证签名的正确性。具体而言, r 0 r_0 r0是在 w − c s 2 w-cs_2 wcs2的低 2 γ 2 2\gamma_2 2γ2位上截取的,其中 w w w是由公钥 p k pk pk和消息 M M M计算出的向量, c c c是签名中的挑战值, s 2 s_2 s2是密钥中的一个秘密向量。这个截取操作可以确保 r 0 r_0 r0的值在模 q q q意义下小于 2 γ 2 2{\gamma_2} 2γ2,从而符合Dilithium签名方案中的要求。

if ∣ ∣ z ∣ ∣ ∞ ≥ γ 1 ||z||_∞ ≥ \gamma_1 ∣∣zγ1 − β or ∣ ∣ r ∣ ∣ ∞ ≥ γ 2 ||r||_∞ ≥ \gamma_2 ∣∣rγ2 − β, then (z, h) := ⊥

∣ ∣ z ∣ ∣ ||z|| ∣∣z∣∣ 表示向量 z z z L ∞ L_{\infty} L 范数,即向量 z z z 的绝对值最大元素的值。在 Dilithium 签名方案中, ∣ ∣ z ∣ ∣ ||z|| ∣∣z∣∣ 表示 z z z 向量的 L ∞ L_{\infty} L 范数,通常用于检测 z z z 是否超过阈值。

向量 z z z L ∞ L_{\infty} L 范数,也称为最大范数,是指向量 z z z 的所有元素中绝对值最大的那个元素的值,即:

∣ ∣ z ∣ ∣ ∞ = max ⁡ 1 < = i < = n ∣ z i ∣ ||z||_{\infty} = \max_{1 <=i <= n } |z_i| ∣∣z=max1<=i<=nzi

其中 n n n 是向量 z z z 的长度。

这段代码表示如果向量 z z z的各个元素的绝对值超过 γ 1 \gamma_1 γ1 - β \beta β 或者向量 r r r的各个元素的绝对值超过 γ 2 \gamma_2 γ2 - β \beta β,则将(h, z)设为⊥,重新进行签名过程。其中, γ 1 \gamma_1 γ1 γ 2 \gamma_2 γ2是参数, β \beta β是安全参数。

也就是如果 z z z ∞ \infty 范数(即绝对值的最大值)大于等于 γ 1 − β \gamma_1 - \beta γ1β 或者 r r r ∞ \infty -范数大于等于 γ 2 − β \gamma_2 - \beta γ2β,那么返回 ( z , h ) : = ⊥ (z, h) := \bot (z,h):= 表示签名失败;


else h := M a k e H i n t q ( − c t 0 , w − c s 2 + c t 0 , 2 γ 2 MakeHint_q(−ct_0, w − cs_2 + ct_0, 2\gamma_2 MakeHintq(ct0,wcs2+ct0,2γ2) --------Compute c t 0 ct_0 ct0 as N T T − 1 ( c ^ ⋅ t 0 ^ ) NTT^{−1}(\hat{c} · \hat{t_0}) NTT1(c^t0^)

否则,计算 c ⋅ t 0 c\cdot t_0 ct0 并存储为 c t 0 ^ = N T T ( c ⋅ t 0 ) \hat{ct_0} = NTT(c \cdot t_0) ct0^=NTT(ct0),然后计算 h h h 作为一个长度为 n n n 的向量,其中第 i i i 位上的值为:

∣ ( − c ⋅ t 0 ) i ∣ < 2 γ 2 |(-c\cdot t_0)_i| < 2{\gamma_2} (ct0)i<2γ2 ∣ ( w − c s 2 + c ⋅ t 0 ) i ∣ ≥ 2 γ 2 |(w-cs_2 + c\cdot t_0)_i| \geq 2{\gamma_2} (wcs2+ct0)i2γ2,则 h i = 1 h_i = 1 hi=1
∣ ( − c ⋅ t 0 ) i ∣ ≥ 2 γ 2 |(-c\cdot t_0)_i| \geq 2{\gamma_2} (ct0)i2γ2 ∣ ( w − c s 2 + c ⋅ t 0 ) i ∣ < 2 γ 2 |(w-cs_2 + c\cdot t_0)_i| < 2{\gamma_2} (wcs2+ct0)i<2γ2,则 h i = − 1 h_i = -1 hi=1
否则, h i = 0 h_i = 0 hi=0
其中 w w w 已经是在上一步计算得到的 w = A y + z − c s 1 w = Ay + z - cs_1 w=Ay+zcs1 s 2 s_2 s2 是在密钥生成阶段计算的, γ 2 \gamma_2 γ2 是 Dilithium 参数中的一个常数。

在 Dilithium 签名方案中, M a k e H i n t q ( − c t 0 , w − c s 2 + c t 0 , 2 γ 2 ) MakeHint_q(−ct_0, w − cs_2 + ct_0, 2\gamma_2) MakeHintq(ct0,wcs2+ct0,2γ2) 函数的作用是生成签名的辅助信息 h h h。该函数将输入的三个向量 − c t 0 , w − c s 2 + c t 0 −ct_0, w − cs_2 + ct_0 ct0,wcs2+ct0 2 γ 2 2\gamma_2 2γ2,并输出一个向量 h h h。其中, − c t 0 −ct_0 ct0 w − c s 2 + c t 0 w − cs_2 + ct_0 wcs2+ct0 分别是两个 N N N 元向量, 2 γ 2 2\gamma_2 2γ2 是一个标量。

生成的 h h h 在 Dilithium 签名方案中用作签名的一部分,它是一个二元组 ( a , b ) (a, b) (a,b),其中 a a a 是一个 ⌊ log ⁡ 2 q ⌋ \lfloor \log_2 q \rfloor log2q 位的整数, b b b 是一个 n n n 位的二进制向量。 h h h 的作用是帮助验证人验证签名是否正确。具体地,当签名验证人接收到签名 ( z , h ) (z, h) (z,h)、消息 M M M 和公钥 p k pk pk 时,它首先检查 ∣ ∣ z ∣ ∣ ∞ ||z||_{\infty} ∣∣z 是否小于 γ 1 − β \gamma_1 - \beta γ1β ∣ ∣ r ∣ ∣ ∞ ||r||_{\infty} ∣∣r 是否小于 γ 2 − β \gamma_2 - \beta γ2β,如果是,则认为签名无效,否则它会计算以下值:

w : = A y − c t 1 z w := Ay - ct_1z w:=Ayct1z
c ′ : = H ( κ ∣ ∣ w 1 ) c' := H(\kappa || w_1) c:=H(κ∣∣w1)
c ′ ^ : = N T T ( c ′ ) \hat{c'} := NTT(c') c^:=NTT(c)
a ′ : = H ( c ′ ^ ∣ ∣ z ^ )   m o d   2 ⌊ log ⁡ 2 q ⌋ a' := H(\hat{c'} || \hat{z}) \bmod 2^{\lfloor \log_2 q \rfloor} a:=H(c^∣∣z^)mod2log2q
b ′ : = M a k e H i n t q ( − a ′ c ′ + c t 0 , w − c s 2 + c t 0 , 2 γ 2 ) b' := MakeHint_q(-a'c' + ct_0, w - cs_2 + ct_0, 2\gamma_2) b:=MakeHintq(ac+ct0,wcs2+ct0,2γ2)
然后,它会检查 a ′ a' a 是否等于 a a a,并使用函数 U s e H i n t q ( b ′ , w − c s 2 + c t 0 , 2 γ 2 ) UseHint_q(b', w - cs_2 + ct_0, 2\gamma_2) UseHintq(b,wcs2+ct0,2γ2) 来检查 c ′ c' c 是否等于签名中的 c c c。如果 a ′ a' a 不等于 a a a c ′ c' c 不等于签名中的 c c c,则验证失败,否则验证成功。因此, h h h 的作用是帮助验证人在验证签名时计算 a ′ a' a b ′ b' b,从而检查签名是否正确

κ \kappa κ := κ \kappa κ + l l l

在 Dilithium 签名方案中, κ \kappa κ 是一个随机种子,它被用于生成一系列的随机数,包括 y y y c ^ \hat{c} c^。每次进行签名时,都需要重新生成这些随机数,因此需要在每次签名之后更新 κ \kappa κ 的值,以保证每次生成的随机数都是不同的。在更新 κ \kappa κ 的值时,需要将其增加 l l l,因为每次生成的 y y y 的长度为 l l l,因此每次更新 κ \kappa κ 的值都需要增加 l l l

return σ = ( c ^ \hat{c} c^, z, h)

这行代码是Dilithium签名算法的输出,返回一个签名 σ \sigma σ。其中, c ^ \hat{c} c^ 是签名中的哈希值的NTT表示, z z z 是签名中的向量 y y y 和一些其他值的线性组合, h h h 是生成签名的过程中计算出的一些用于验证签名的值的哈希值的NTT表示。

验证算法

A ∈ R q k × l R^{k \times l}_q Rqk×l := ExpandA(ρ)--------- A is generated and stored in NTT Representation as A

在Dilithium验证算法中,矩阵 A A A 用于计算签名中的向量 w w w。具体地,验证算法需要计算以下两个向量:

w ′ = A ⋅ z − c ⋅ t 1 w' = A \cdot z - c \cdot t_1 w=Azct1
w ′ ′ = A ⋅ h − c ⋅ t 0 w'' = A \cdot h - c \cdot t_0 w′′=Ahct0
其中 z z z h h h 分别是签名中的两个向量, c c c 是签名中的挑战, t 1 t_1 t1 t 0 t_0 t0 是公钥中的两个向量。由于矩阵 A A A 存储在 NTT 表示中,因此需要先将向量 z z z h h h 转换为 NTT 表示,然后计算 A A A t 1 t_1 t1 的乘积 A ⋅ z A \cdot z Az c ⋅ t 1 c \cdot t_1 ct1 的乘积,最后通过减法得到向量 w ′ w' w。同理,计算 w ′ ′ w'' w′′ 也需要用到矩阵 A A A

μ ∈ { 0 , 1 } 256 : = H ( H ( ρ ∣ ∣ t 1 ) ∣ ∣ M ) \mu \in \{{0, 1\}}^{256} := H(H(\rho |\mathbin|\mathbin t_1)|\mathbin|\mathbin M) μ{0,1}256:=H(H(ρt1)M)

ρ \rho ρ t 1 t_1 t1 是签名中的两个参数,M 是待验证的消息,通过这些参数和消息的哈希值,可以计算出签名中的哈希值 μ \mu μ,用于与签名中的哈希值比对,以判断签名是否正确。

c := SampleInBall( c ^ \hat{c} c^)

执行 c : = S a m p l e I n B a l l ( c ^ ) c := SampleInBall(\hat{c}) c:=SampleInBall(c^) 表示从半径为 β q \beta q βq 的球中均匀随机采样一个向量 c \mathbf{c} c。这里的 c ^ \hat{c} c^ 是签名中的 c ^ \hat{c} c^,是经过 NTT 变换后的 c \mathbf{c} c

w 1 ′ w_1^{'} w1 := U s e H i n t q ( h , A z − c t 1 ⋅ 2 d , 2 γ 2 ) UseHint_q(h, Az − ct_1 · 2^d, 2\gamma_2) UseHintq(h,Azct12d,2γ2) ----- Compute as N T T − 1 ( A ^ ⋅ N T T ( z ) − N T T ( c ) ⋅ N T T ( t 1 ⋅ 2 d ) ) NTT^{−1}(\hat{A} · NTT(z) − NTT(c) · NTT(t_1 · 2^d)) NTT1(A^NTT(z)NTT(c)NTT(t12d))

这行代码用于使用前面生成的提示(hint) h h h 来验证签名。具体来说,首先计算 A z − c t 1 ⋅ 2 d Az − ct_1 · 2^d Azct12d 的 NTT 表示,并使用 h h h 来提取 w 1 ′ w_1^{'} w1(即 w w w 的高位)。然后,将 w 1 ′ w_1^{'} w1 与签名中的 w 1 w_1 w1 进行比较,如果它们相等,则验证成功。

return [ [ ∣ ∣ z ∣ ∣ ∞ < γ 1 − β ] ] [[||z||_∞ < \gamma_1 − β]] [[∣∣z<γ1β]] and [ [ c ^ = H ( µ ∣ ∣ w 1 ′ ) ] ] [[\hat{c} = H (µ || w_1^{'})]] [[c^=H(µ∣∣w1)]] and [[# of 1’s in h is ≤ ω ]]

第一个条件 [ [ ∣ ∣ z ∣ ∣ ∞ < γ 1 − β ] ] [[||z||_∞ < \gamma_1 − β]] [[∣∣z<γ1β]]检查签名中的 z z z向量是否满足限制条件,即 L ∞ L{\infty} L范数小于 γ 1 − β \gamma_1-\beta γ1β。如果不满足条件,验证算法返回失败。这个条件保证了签名的正确性和安全性。

第二个条件 [ [ c ^ = H ( µ ∣ ∣ w 1 ′ ) ] ] [[\hat{c} = H (µ || w_1^{'})]] [[c^=H(µ∣∣w1)]]检查签名中的 c ^ \hat{c} c^是否等于通过消息、公钥、和 h h h生成的哈希值。如果不满足条件,验证算法返回失败。这个条件保证了签名中的 c ^ \hat{c} c^值是由正确的信息生成的。

第三个条件[[ # of 1’s in h is ≤ ω} ]] 检查 h h h中1的个数是否小于或等于 ω \omega ω。如果 h h h中1的个数超过了限制,验证算法返回失败。这个条件保证了签名中的 h h h不会太大,从而保证了签名的效率和安全性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/419307.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【springBoot篇2】springBoot日志篇

目录 一、日志有什么作用 作用1&#xff1a;快速定位问题的所在之处(最主要) 作用2&#xff1a;记录用户的登录日志 作用3&#xff1a;记录系统的操作日志 作用4&#xff1a;记录方法的执行时间 二、日志怎样使用 ①先得到日志对象(slf4j的Logger对象) ​​​编辑 ②根…

Python 无监督学习实用指南:1~5

原文&#xff1a;Hands-on unsupervised learning with Python 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#xff0c;只关…

docker运行服务端性能监控系统Prometheus和数据分析系统Grafana

文章目录一、Prometheus的安装和运行1、使用docker拉取镜像2、创建prometheus.yml文件3、启动容器4、查看启动是否成功5、记录安装过程中出现的错误二、Grafana的安装和运行1、使用docker拉取镜像2、创建grafana3、运行grafana4、查看grafana运行日志5、登录grafana一、Prometh…

学会了selenium 模拟鼠标操作,你就可以偷懒点点点了

目录&#xff1a;导读 前言 01.ActionChains 类常用方法 02.ActionChains 类所有方法 03.ActionChains 使用步骤 04.实战 05.总结 前言 我们在做 Web 自动化的时候&#xff0c;有时候页面的元素不需要我们点击&#xff0c;值需要把鼠标移动上去就能展示各种信息。 这个…

云服务器开启声音的办法

云服务器开启声音的办法 淘小云 云计算从业者&#xff0c;架构师 ​关注 云服务器没有声音是一件很烦恼的事情&#xff0c;那么今天小编给大家分享一下服务器开启声音的方法&#xff01; 首先您需要先拥有一台windows系统的云服务器&#xff0c;小编这里以腾讯云服务器为例…

( “树” 之 DFS) 687. 最长同值路径 ——【Leetcode每日一题】

687. 最长同值路径 给定一个二叉树的 root &#xff0c;返回 最长的路径的长度 &#xff0c;这个路径中的 每个节点具有相同值 。 这条路径可以经过也可以不经过根节点。 两个节点之间的路径长度 由它们之间的边数表示。 示例 1: 输入&#xff1a;root [5,4,5,1,1,5] 输出&…

Loki采集Mysql errorlog,你值得拥有的错误日志聚合系统

说到分布式日志存储系统&#xff0c;大家肯定对ELK、EFK这些工具并不陌生。可是它们都基于Elasticsearch存储&#xff0c;搭建复杂&#xff0c;耗资源&#xff0c;上手难。所以&#xff0c;个人非常推崇Grafana Labs开源的Loki 轻量级日志聚合分析系统 Loki使用标签来作为索引…

java maven学习

我本身是个前端&#xff0c;目前Java都算是自学&#xff0c;为了直接能做Java服务端开发&#xff0c;我其实很多基础都没学&#xff0c;直接上项目做东西。现在来补充常用maven。避免以后出现低级错误。 一、依赖拉不下来解决步骤 1. 检查网络&#xff08;最好检查&#xff09…

Flutter(六)可滚动组件

目录1.可滚动组件简介Sliver布局模型ScrollableViewportSliver可滚动组件的通用配置2.SingleChildScrollView3.ListView默认构造函数ListView.builderListView.separated固定高度列表ListView 原理无限加载列表&#xff0c;分页添加Header4.滚动监听及控制ScrollController滚动…

SpringCloud-Alibaba学习笔记01——Nacos介绍以及注册中心的演变和Nacos核心功能

文章参考自图灵大佬课程&#xff1a;https://www.bilibili.com/video/BV1fe4y1b7ha?p1&vd_source5f425e0074a7f92921f53ab87712357b 1.什么是Nacos 官方&#xff1a;一个更易于构建云原生应用的动态服务发现(Nacos Discovery )、服务配置(Nacos Config)和服务管理平台。 …

threejs 模型 世界坐标系和设备坐标系

前言 开发中遇到需求需要点击屏幕位置处&#xff0c;生成一个类似圆形弹窗面板&#xff0c;这个交互需要进行的坐标转换为模型坐标&#xff08;局部坐标&#xff09;>场景坐标&#xff08;世界坐标&#xff09;>标准设备坐标>屏幕空间坐标&#xff0c;也就是一个将3D…

开启分片支持需要如何去做?

开启分片支持 如果您计划使您的Javashop系统数据分片&#xff0c;请参考本文档进行相应的配置。 一、做好分片策略 在开始之前&#xff0c;您应该根据自己的业务情况准备好分片策略&#xff0c;包括&#xff1a; 1、要用几个数据库来分片 2、相应的表要分几张表 在本例&#x…

大数据 | 实验一:大数据系统基本实验 | MapReduce 初级编程

文章目录&#x1f4da;实验目的&#x1f4da;实验平台&#x1f4da;实验内容&#x1f407;编程实现文件的合并和去重&#x1f407;编程实现对输入文件的排序&#x1f407;对指定的表格进行信息挖掘&#x1f4da;实验目的 1&#xff09;通过实验掌握基本的 MapReduce 编程方法。…

警惕“Money Message”勒索软件!数据安全不容忽视

近段时间&#xff0c;出现了一个名为“Money Message”的新型勒索软件&#xff0c;他们利用Money Message 病毒加密文件并以此向受害者勒索巨额赎金。 Money Message勒索软件是用 C编写&#xff0c;包含一个嵌入式JSON 配置文件&#xff0c;用于确定设备的加密方式。加密设备后…

小红书内容种草,曝光渠道分析总结

这是一个内容为王的时代&#xff0c;也是一个内容爆炸的时代。想要在以分享特色的小红书平台&#xff0c;实现内容种草&#xff0c;迅速出圈。今天来马文化传媒就从实操的角度&#xff0c;为大家带来小红书内容种草&#xff0c;曝光渠道分析总结的各种干货&#xff01; 一、什…

关于图形界面Pyqt与QT的区别选择

关于图像界面&#xff08;GUI&#xff09;想必大家都并不陌生&#xff0c;想要将一段已经完善的功能列表进行可视化操作并且具有一定的操作空间&#xff0c;将功能可视化必不可少&#xff0c;一个好的可视化工具不仅可以集成一系列小的文件功能&#xff0c;还能将不同方法之间的…

ubuntu基本环境配置及mysql8.0.32和mysql workbench安装

ubuntu基本环境配置 文章目录ubuntu基本环境配置各种依赖包下载地址一、使用root账号进行远程连接二、防火墙相关设置2.1启用2.2开放和关闭端口数据库mysql安装(8.0.32)工具mysqlworkbench(8.0.32)各种依赖包下载地址 http://cn.archive.ubuntu.com/ubuntu/pool/main/liba/lib…

【1019. 链表中的下一个更大节点】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给定一个长度为 n 的链表 head 对于列表中的每个节点&#xff0c;查找下一个 更大节点 的值。也就是说&#xff0c;对于每个节点&#xff0c;找到它旁边的第一个节点的值&#xff0c;这个节点的值 严…

三天吃透Redis八股文

Redis连环40问&#xff0c;绝对够全&#xff01; Redis是什么&#xff1f; Redis&#xff08;Remote Dictionary Server&#xff09;是一个使用 C 语言编写的&#xff0c;高性能非关系型的键值对数据库。与传统数据库不同的是&#xff0c;Redis 的数据是存在内存中的&#xf…

java调用python动态生成光电雷达图

一、编写java调用程序 //http://localhost:8945/api/ExecPy/ExecPyPollutionRadarMap ApiOperation(value "ExecPy") GetMapping(value "/ExecPyPollutionRadarMap") public String ExecPyPollutionRadarMap() {String scriptpath"F:\\demo\\Radar…