同态算法FHEW笔记
同态格密码FHEW笔记
- FHEW: Bootstrapping Homomorphic Encryption in Less Than a Second
- 1 LWE私钥加密算法
- 2 FHE同态加密算法
- 3 RGSW同态加速器RGSW
- 总结
- 参考文献
FHEW: Bootstrapping Homomorphic Encryption in Less Than a Second
论文阅读顺序
- [MP12]: Trapdoors for lattices: Simpler, tighter, faster,
smaller.- [GSW]: Homomorphic encryption from learning with errors: Conceptually-simpler,asymptotically-faster, attribute-based.
- [FHEW]: FHEW: Bootstrapping Homomorphic Encryption in Less Than a Second
1 LWE私钥加密算法
LWE加密算法
LWE加密算法参数化维数 n n n,消息模数 t ⩾ 2 t \geqslant 2 t⩾2,密文模数 q = n O ( 1 ) q=n^{O(1)} q=nO(1) ,随机约化函数 χ : R ⟶ Z \chi:\mathbb{R}\longrightarrow\mathbb{Z} χ:R⟶Z,其错误分布 ∣ χ ( x ) − t ∣ < q / 2 t \left | \chi (x)-t \right | <q/2t ∣χ(x)−t∣<q/2t。LWE加密算法 L W E q t / q ( m ) LWE_q^{t/q}(m) LWEqt/q(m)的私钥加密思路如下。
私钥: s ← Z q n \mathbf{s}\gets \mathbb{Z} _q^{n} s←Zqn
消息: m ← Z t m\gets \mathbb{Z} _t m←Zt
L W E q t / q ( m ) LWE_q^{t/q}(m) LWEqt/q(m)参数 : a ← Z q n \mathbf{a}\gets \mathbb{Z} _q^{n} a←Zqn, e e e, χ \chi χ
加密: L W E q t / q ( m ) = ( a , χ ( ( a ⋅ s + m q ) / t m o d q ) LWE_q^{t/q}(m)=(a,\chi ((a\cdot s+mq)/t\mod q) LWEqt/q(m)=(a,χ((a⋅s+mq)/tmodq)
解密: m ′ = ⌊ t ( b − a ⋅ s ) / q ⌉ m o d t {\color{Red} m^{'}} =\left \lfloor t(b-a\cdot s)/q \right \rceil\mod t m′=⌊t(b−a⋅s)/q⌉modt
令解密过程中 ⌊ t ( b − a ⋅ s ) / q ⌉ m o d t q = ⌊ t q ⋅ ( q t m + e ) ⌉ = ⌊ m + t q e ⌉ \left \lfloor t(b-a\cdot s)/q \right \rceil\mod t q =\left \lfloor\frac{t}{q} \cdot(\frac{q}{t}{\color{Red}m }+e)\right \rceil=\left \lfloor {\color{Red}m}+\frac{t}{q}e\right \rceil ⌊t(b−a⋅s)/q⌉modtq=⌊qt⋅(tqm+e)⌉=⌊m+qte⌉。因此,只要噪声小于 t q ∣ e ∣ < 1 / 2 \frac{t}{q}|e|<1/2 qt∣e∣<1/2,则四舍五入后,能够争取的解密噪声。
模数转化(Modulus switching)
LWE密文可以从模数 Q Q Q转化到模数 q q q利用随机约化函数 [ ⋅ ] Q : q : Z Q → Z q \left [ \cdot \right ]_{Q:q}:\mathbb{Z}_Q \to \mathbb{Z}_q [⋅]Q:q:ZQ→Zq,定义为 [ x ] Q : q = ⌊ q x / Q ⌋ + B \left [ x \right ]_{Q:q}=\left \lfloor qx/Q \right \rfloor+B [x]Q:q=⌊qx/Q⌋+B。S c a l e ( c , Q , q , r ) Scale(\mathbf{c},Q,q,r) Scale(c,Q,q,r): 输入整数向量 c \mathbf{c} c和整数向量 Q Q Q, q q q(Q>q>m),输出的结果是靠近 q x / Q qx/Q qx/Q的向量 c ′ \mathbf{c^{'}} c′,且满足 c ′ = c m o d r \mathbf{c^{'}}=\mathbf{c}\mod r c′=cmodr。
引理5:令 s ∈ Z q n \mathbf{s}\in \mathbb{Z} _q^{n} s∈Zqn, m ∈ Z t m\in \mathbb{Z} _t m∈Zt, 以及密文 c ∈ L W E q t / q ( m ) \mathbf{c}\in LWE_q^{t/q}(m) c∈LWEqt/q(m),其亚高斯的参数分布是 σ \sigma σ,约化密 M o d S w i t c h ( c ) = [ c ] Q : q ModSwitch(\mathbf{c})=\left [ \mathbf{c} \right ]_{Q:q} ModSwitch(c)=[c]Q:q, 其亚高斯的参数分是 ( q σ / Q ) 2 + 2 π ( ∥ s 2 + 1 ∥ ) \sqrt{(q\sigma/Q)^2+2\pi(\|s^2+1\|)} (qσ/Q)2+2π(∥s2+1∥) .
密钥转化(key switching)
由于LWE上的全同态加密的密文乘积会导致密文长度增长。因此,为了约化密文的长度,产生了密钥交换技术,该技术最初命名为再线性化技术。
原密钥: z ∈ Z q n \mathbf{z}\in \mathbb{Z} _q^{n} z∈Zqn
转换密钥: s ∈ Z q n \mathbf{s}\in \mathbb{Z} _q^{n} s∈Zqn
基数: B k s B_{ks} Bks,可以取2
扩张长度: d k s d_{ks} dks= log B k s q \log_{B_{ks}}q logBksq
加密密钥: k i , j , v ∈ L W E s q / q ( v z i B k s j ) \mathbf{k}_{i,j,v}\in LWE_s^{q/q}(vz_iB_{ks}^j) ki,j,v∈LWEsq/q(vziBksj)
给定转换密钥 R = k i , j , v \mathfrak{R}=\mathbf{k}_{i,j,v} R=ki,j,v,以及对应的密文 ( a , b ) ∈ L W E s q / q ( m ) (\mathbf{a},b)\in LWE_s^{q/q}(m) (a,b)∈LWEsq/q(m),每个系数 a i = ∑ j a i , j B k s j a_i=\sum_ja_{i,j}B_{ks}^j ai=∑jai,jBksj,可以得到下式。
k e y S w i t c h ( ( a , b ) , R ) = ( 0 , b ) − ∑ i , j k i , j , a i , j {\color{Blue} keySwitch((\mathbf{a},b),\mathfrak{R} )=(0,b)-\sum_{i,j}\mathbf{k}_{i,j,a_{i,j}}} keySwitch((a,b),R)=(0,b)−i,j∑ki,j,ai,j证明的过程只需要证明 b ′ − a ′ s + E = b − a z b^{'}-\mathbf{a}^{'}\mathbf{s}+E=b-\mathbf{a}\mathbf{z} b′−a′s+E=b−az。 ( b ′ , a ) = ( a i , j , v ′ , a i , j , v ′ s + v z i B k s j + e i , j , v ) (b^{'},\mathbf{a})=(\mathbf{a}_{i,j,v}^{'},\mathbf{a}_{i,j,v}^{'}\mathbf{s}+vz_iB_{ks}^j+e_{i,j,v}) (b′,a)=(ai,j,v′,ai,j,v′s+vziBksj+ei,j,v)。
因此:
b ′ = b − ∑ i , j ( a i , j , a i , j ′ s + v z i B k s j + e i , j , a i , j ) = b − a z + a ′ s + E b^{'}=b-\sum_{i,j}(\mathbf{a}_{i,j,a_{i,j}}^{'}\mathbf{s}+vz_iB_{ks}^j+e_{i,j,a_{i,j}}) \\=b- \mathbf{a}\mathbf{z}+\mathbf{a}^{'}\mathbf{s}+E b′=b−i,j∑(ai,j,ai,j′s+vziBksj+ei,j,ai,j)=b−az+a′s+E
其中 a ′ = − ∑ i , j a i , j , a i , j ′ \mathbf{a}^{'}=-\sum_{i,j} \mathbf{a}_{i,j,a_{i,j}}^{'} a′=−∑i,jai,j,ai,j′。
2 FHE同态加密算法
NAND门同态
引理7: 逻辑算法NAND m = 1 − m 0 m 1 = m 0 ∧ ‾ m 1 m=1-m_0m_1=m_0\overline{\wedge } m_1 m=1−m0m1=m0∧m1,二元加密消息 m 0 , m 1 ∈ { 0 , 1 } m_0,m_1\in\{0,1\} m0,m1∈{0,1}, 密文 c i ∈ L W E 4 / q ( m i , q / 16 ) , \mathbf{c}_i\in LWE^{4/q}(m_i,q/16), ci∈LWE4/q(mi,q/16), ( i = 1 , 2 ) (i=1,2) (i=1,2),输出同构加密 H o m o N A N D ( c 0 , c 1 ) ∈ L W E 2 / q ( m i , q / 4 ) HomoNAND(\mathbf{c}_0,\mathbf{c}_1)\in LWE^{2/q}(m_i,q/4) HomoNAND(c0,c1)∈LWE2/q(mi,q/4), ( i = 1 , 2 ) (i=1,2) (i=1,2),同构算法HomoNAND如下 H o m o N A N D : L W E 4 / q ( m 0 , q / 16 ) × L W E 4 / q ( m 1 , q / 16 ) ⟶ L W E 2 / q ( m 0 ∧ ‾ m 1 q / 4 ) HomoNAND:LWE^{4/q}(m_0,q/16)\times LWE^{4/q}(m_1,q/16)\longrightarrow LWE^{2/q}(m_0\overline{\wedge } m_1q/4) HomoNAND:LWE4/q(m0,q/16)×LWE4/q(m1,q/16)⟶LWE2/q(m0∧m1q/4)
Addition/XOR operation
L W E s ( m 1 , e 1 ) × L W E s ( m 2 , e 2 ) ⟶ L W E s ( m 1 ⊕ m 2 , e 1 + e 2 ) LWE_s(m_1, e_1) × LWE_s(m_2, e_2) \longrightarrow LWEs(m_1 \oplus m_2, e_1 + e_2) LWEs(m1,e1)×LWEs(m2,e2)⟶LWEs(m1⊕m2,e1+e2)
(N)AND operation
L W E s 1 ( m 1 , e 1 ) × L W E s 2 ( m 2 , e 2 ) ⟶ L W E s 1 ⊗ s 2 ( m 1 ⊗ m 2 , e 1 ⋅ e 2 ) LWE_{s_{1}}(m_1, e_1) × LWE_{s_{2}}(m_2, e_2) \longrightarrow LWE_{s_{1}\otimes s_{2}}(m_1 \otimes m_2, e_1 \cdot e_2) LWEs1(m1,e1)×LWEs2(m2,e2)⟶LWEs1⊗s2(m1⊗m2,e1⋅e2)
考虑 m 1 ∧ m 2 ⇔ m 1 + m 2 = 2 m o d 4 m_1 ∧ m_2 ⇔ m_1 + m_2 = 2 \mod 4 m1∧m2⇔m1+m2=2mod4, 二元消息
{ 0 , 1 } \{0, 1\} {0,1}, t = 4 t = 4 t=4.
考虑到 m 0 , m 1 ∈ { 0 , 1 } , m 0 2 = m 0 , m 1 2 = m 1 m_0,m_1\in\{0,1\},m_0^2=m_0,m_1^2=m_1 m0,m1∈{0,1},m02=m0,m12=m1:
L W E 2 / q ( m 0 ∧ ‾ m 1 , q / 4 ) : E r r = b − a s − ( 1 − m 0 m 1 ) q / 2 = ( 8 / 5 q − b 0 − b 1 ) + a 0 s + a 1 s − q / 2 + q / 2 m 0 m 1 = 8 / q − q / 4 m 0 − e 0 − q / 4 m 1 − e 1 + q / 2 m 0 m 1 = 8 / q − q / 4 m 0 2 − e 0 − q / 4 m 1 2 − e 1 + q / 2 m 0 m 1 = q / 4 ( 1 / 2 − ( m 0 − m 1 ) 2 ) − ( e 0 + e 1 ) = ± q / 8 − ( e 0 + e 1 ) < q / 8 + q / 16 + q / 16 = q / 4 LWE^{2/q}(m_0\overline{\wedge } m_1,q/4):Err\\ =b-\mathbf{a}\mathbf{s}-(1-m_0m_1)q/2\\ =(8/5q -b_0-b_1)+a_0\mathbf{s}+a_1\mathbf{s}-q/2+q/2m_0m_1\\ =8/q-q/4{\color{Violet}m_0 } -e_0-q/4{\color{Violet}m_1 }-e_1+q/2m_0m_1\\ =8/q-q/4{\color{Violet}m_0^2 } -e_0-q/4{\color{Violet}m_1 ^2}-e_1+q/2m_0m_1\\ ={\color{Red} q/4(1/2-(m_0-m_1)^2)-(e_0+e_1)}\\ =\pm q/8-(e_0+e_1)\\ <q/8+q/16+q/16\\ ={\color{Orange} q/4} LWE2/q(m0∧m1,q/4):Err=b−as−(1−m0m1)q/2=(8/5q−b0−b1)+a0s+a1s−q/2+q/2m0m1=8/q−q/4m0−e0−q/4m1−e1+q/2m0m1=8/q−q/4m02−e0−q/4m12−e1+q/2m0m1=q/4(1/2−(m0−m1)2)−(e0+e1)=±q/8−(e0+e1)<q/8+q/16+q/16=q/4
LightRefresh : L W E s 2 ( m , q / 4 ) → L W E s 4 ( m , q / 16 ) LWE^2_s (m, q/4) → LWE^4_s (m, q/16) LWEs2(m,q/4)→LWEs4(m,q/16)
- 同态累加器(Refreshing via Homomorphic Accumulator)
定义1:同态累加器方案是四元组(E, Init, Incr, msbExtractq),其中模数 t , q t,q t,q。 E E E和 m s b E x t r a c t msbExtract msbExtract与LWE密钥 S S S相关。为了公式的简洁性, A C C ← v ACC \leftarrow v ACC←v替代 A C C ← I n i t ( v ) ACC \leftarrow Init(v) ACC←Init(v), A C C ← + E ( v ) ACC \xleftarrow{+} E(v) ACC+ E(v)替代 A C C ← I n c r ( A C C , E ( v ) ) ACC \leftarrow Incr(ACC,E(v)) ACC←Incr(ACC,E(v))。令 v 0 , v 1 , ⋯ , v q ∈ Z q v_0,v_1,\cdots,v_q \in \mathbb{Z}_q v0,v1,⋯,vq∈Zq,
A C C ← v 0 ACC\leftarrow v_0 ACC←v0, for i = 1 i=1 i=1 to l l l, A C C ← + E ( v i ) ACC \xleftarrow{+} E(v_i) ACC+ E(vi)。称这样的ACC是一个 v v v的 l − e n c r y p t i o n l-encryption l−encryption, 其中 v = ∑ i = 0 l v i m o d q 。 v=\sum_{i=0}^lv_i \mod q。 v=∑i=0lvimodq。
任何一个 v v v的 l − e n c r y p t i o n l-encryption l−encryption,计算 c ← m s b E x t r a c t ( A C C ) \mathbf{c}\leftarrow msbExtract(ACC) c←msbExtract(ACC), 确保了 c ∈ L W E q t / q ( m s b ( v ) , ε ( l ) ) \mathbf{c}\in LWE_q^{t/q}(msb(v),\varepsilon (l)) c∈LWEqt/q(msb(v),ε(l)), ε ( l ) \varepsilon (l) ε(l) 是一个压倒性的概率,那么说同构累加器(Homomorphic Accumulator Scheme)是 ε \varepsilon ε 正确的,对于任意函数 ε \varepsilon ε。
累加器参数: t = 4 t=4 t=4以及 ε ( l ) ≤ / 16 \varepsilon (l)\leq/16 ε(l)≤/16
密文: ( a , b ) ∈ L W E s 2 / q ( m , q / 4 ) (a,b)\in LWE_s^{2/q}(m,q/4) (a,b)∈LWEs2/q(m,q/4)
密钥材料: K i , j = E ( s i B r j m o d q ) K_{i,j}=E(s_iB_r^j\mod q) Ki,j=E(siBrjmodq)
实际通用密钥材料: K i , a i , j , j = E ( a i , j s i B r j m o d q ) K_{i,a_{i,j},j}=E(a_{i,j}s_iB_r^j\mod q) Ki,ai,j,j=E(ai,jsiBrjmodq)
定理8:若 ( E , I n i t , I n c r , m s b E x t r a c t q ) (E, Init, Incr, msbExtractq) (E,Init,Incr,msbExtractq)是正确的同构累加器方案,对于刷新(refresh)过程, 输入密文 c ∈ L W E s 2 / q ( m , q / 4 ) \mathbf {c}\in LWE_s^{2/q}(m,q/4) c∈LWEs2/q(m,q/4), 刷新密钥 K = { K i , c , j = E ( c s i B r j m o d q ) } i , c , j \mathcal{K}=\{K_{i,c,j}=E(cs_iB_r^j\mod q)\}_{i,c,j} K={Ki,c,j=E(csiBrjmodq)}i,c,j 输出刷新密文 R e f r e s h K ( c ) ∈ L W E s t / q ( m , ε ( n d ) Refresh_{\mathcal{K}}(\mathbf {c})\in LWE_s^{t/q}(m,\varepsilon(nd) RefreshK(c)∈LWEst/q(m,ε(nd)。
证明:首先初始化累加器 b + q / 4 b+q/4 b+q/4, 进行 n d nd nd 次加法的密文 K i , a i , j , j = E ( a i , j s i B r j m o d q ) K_{i,a_{i,j},j}=E(a_{i,j}s_iB_r^j\mod q) Ki,ai,j,j=E(ai,jsiBrjmodq)。最终输出 L W E LWE LWE加密的错误向量 ε ( n d ) \varepsilon(nd) ε(nd)。累加器最后次循环输出的向量 v v v的值是
v − q / 4 = b + ∑ i , j a i , j s i B r j = b + ∑ i s i ∑ j a i , j B r j = b − ∑ i s i a i = q / 2 m + e v-q/4 \\ =b+\sum_{i,j}a_{i,j}s_iB_r^j \\ =b+{\color{Red} \sum_{i}s_i} {\color{Blue} \sum_{j}a_{i,j}B_r^j }\\ =b-{\color{Red} \sum_{i} s_i} {\color{Blue} a_{i} }\\ =q/2m+e v−q/4=b+∑i,jai,jsiBrj=b+∑isi∑jai,jBrj=b−∑isiai=q/2m+e
可以得到 ∣ e ∣ ≤ q / e |e|\le q/e ∣e∣≤q/e, m = 0 m=0 m=0, 0 < v < q / 2 0<v<q/2 0<v<q/2; m = 1 m=1 m=1, − q / 2 < v < 0 -q/2<v<0 −q/2<v<0。
3 RGSW同态加速器RGSW
GSW同构累加器方案12
- E z ( m ) E_z(m) Ez(m): 输入消息 m m m, 密钥 z ∈ R z\in \mathcal{R} z∈R, 均匀随机选择 ( a ) ∈ R Q 2 d g \mathbf(a)\in \mathcal{R}_Q^{2d_g} (a)∈RQ2dg, 错误向量 e ∈ R 2 d g e\in \mathcal{R}^{2d_g} e∈R2dg, 服从参数为 ζ \zeta ζ 亚高斯分布 χ \chi χ,
E z ( m ) = [ a , a ⋅ z + e ] + u Y m G ∈ R Q 2 d g × 2 E_z(m)=[\mathbf{a},\mathbf a\cdot z+\mathbf{e}]+uY^mG\in \mathcal{R}_Q^{2d_g\times 2} Ez(m)=[a,a⋅z+e]+uYmG∈RQ2dg×2- I n i t ( A C C ← v ) Init(ACC \leftarrow v) Init(ACC←v): 输入 v ∈ Z q n v\in \mathbb{Z}_q^n v∈Zqn, 设置 A C C : = u Y v G ∈ R Q 2 d g × 2 ACC:=uY^vG\in \mathcal{R}_Q^{2d_g\times 2} ACC:=uYvG∈RQ2dg×2。
- I n c r ( A C C ← + C ) Incr(ACC \xleftarrow{+} C) Incr(ACC+ C): A C C : = [ D 1 , D 2 , ⋯ , D d g ] C ACC:=[D_1,D_2,\cdots,D_{d_g}]C ACC:=[D1,D2,⋯,Ddg]C
- m s b E x t r a c t msbExtract msbExtract: 一个测试向量 t = − ∑ i = 0 N − 1 X → i \mathbf{t}=-\sum_{i=0}^{N-1}\overrightarrow{X}_i t=−∑i=0N−1X i,其中 t = ( − 1 , − 1 , ⋯ , − 1 ) ∈ Z N t=(-1,-1,\cdots,-1)\in\mathbb{Z}^N t=(−1,−1,⋯,−1)∈ZN。若 0 ≤ v < N 0\le v<N 0≤v<N, 计算可得 t ⋅ X → i = − 1 ; \mathbf{t}\cdot \overrightarrow{X}_i=-1; t⋅X i=−1; 若 N ≤ v < 2 N N\le v<2N N≤v<2N, 计算可得$\mathbf{t}\cdot \overrightarrow{X}_i=1。
总结
参考文献
1. 初探全同态加密之四:Bootstrapping的原理与实现https://zhuanlan.zhihu.com/p/260033204 ↩︎
2.FHEW阅读笔记https://blog.csdn.net/AdijeShen/article/details/119539449 ↩︎
同态算法FHEW笔记相关推荐
- Data Structures with C++ Using STL Chapter 3算法概述---笔记
<Data Structures with C++ Using STL Chapter 3算法概述---笔记>,作者:茉莉花茶,原文链接:http://www.cnblogs.com/yc ...
- 可由一个尾指针唯一确定的链表有_极客算法训练笔记(三),链表详细图解,别再逃避了朋友...
目录 缓存引爆链表 链表单链表双向链表循环链表双向循环链表 LinkedHashMap实现LRU缓存,源码解析(JDK1.8) 算法 爬楼梯 算法 反转链表 算法 链表环检测 缓存引爆链表 存储结构 ...
- 大顶堆删除最大值_算法学习笔记(47): 二叉堆
堆(Heap)是一类数据结构,它们拥有树状结构,且能够保证父节点比子节点大(或小).当根节点保存堆中最大值时,称为大根堆:反之,则称为小根堆. 二叉堆(Binary Heap)是最简单.常用的堆,是一 ...
- 《Algorithm算法》笔记:元素排序(2)——希尔排序
<Algorithm算法>笔记:元素排序(2)--希尔排序 Algorithm算法笔记元素排序2希尔排序 希尔排序思想 为什么是插入排序 h的确定方法 希尔排序的特点 代码 有关排序的介绍 ...
- 推荐算法炼丹笔记:排序模型CTR点击率预估系列
微信公众号:炼丹笔记 CTR点击率预估系列家谱 炼丹之前,先放一张CTR预估系列的家谱,让脉络更加清晰. (一)FiBiNET:结合特征重要性和双线性特征交互进行CTR预估 1.1 背景 本文发表在 ...
- 推荐算法炼丹笔记:序列化推荐系统
作者:一元 公众号:炼丹笔记 特约审稿:杰少 背景 序列推荐系统(SRS)不同于传统推荐系统(RSs)包括协同过滤和基于内容的过滤,SRSs试图理解和建模用户的连续行为.用户与物品之间的交互作用以及用 ...
- 推荐算法炼丹笔记:推荐系统采样评估指标及线上线下一致性问题
本文对于推荐系统中的采样评估指标进行了讨论,内容略多, 还有一些数学推导, 有兴趣的可以去阅读文末给出的原始论文链接, 此处直接列出核心观点: 在评估推荐算法的效果时,能不采样就不采样! 除了AUC, ...
- 推荐算法炼丹笔记:CTR点击率预估系列入门手册
CTR点击率预估系列家谱 炼丹之前,先放一张CTR预估系列的家谱,让脉络更加清晰. (一)FiBiNET:结合特征重要性和双线性特征交互进行CTR预估 1.1 背景 本文发表在RecSys 2019 ...
- 推荐算法炼丹笔记:如何让你的推荐系统具有可解释性?
作者:一元, 公众号:炼丹笔记 可解释性和有效性是构建推荐系统的两大关键成份,之前的工作主要关注通过引入辅助信息来获得更好的推荐效果.但这些方法会存在下面的两个问题: 基于神经网络的embedding ...
最新文章
- 09Abstract Factory(抽象工厂)模式
- Red Hat Linux、rhel 和 Fedora Core 以及 Centos 区别与联系
- 推荐系统笔记:基于模型的协同过滤
- 【编译原理】让我们来构建一个简单的解释器(Let’s Build A Simple Interpreter. Part 3.)(python/c/c++版)(笔记)
- 数据库系统概念总结:第一章 引言
- hdu 5444 Elven Postman(根据先序遍历和中序遍历求后序遍历)2015 ACM/ICPC Asia Regional Changchun Online...
- linux reboot命 过程,IDRAC安装dell服务器操作系统(linux or windows),用到生命周期管理器...
- 设计模式:装饰模式(C++)【小明习武闯天下】
- 一个基于链表的内存管理方案
- 【Kalman】卡尔曼滤波Matlab简单实现
- 掌握 3 个搜索技巧,在 GitHub 上快速找到实用软件资源
- 网络安全——端口对应服务大全(白帽必备万字快查表)
- php function overridden,php在函数外声明global变量有什么用?
- 微信小程序之店铺评分组件及vue中用svg实现的评分显示组件
- [经验教程]2022微信怎么给微信好友批量群发消息?
- 多标签用户画像分析跑得快的关键在哪里?
- 美女直播这么火,那你知道怎么测试直播软件吗?
- 以太坊漏洞分析————4、底层函数误用漏洞
- 科学防雷接地和雷电防护方案
- linux shell 未找到命令,未找到linux问题setenv命令(linux issue setenv command not found)