1. 引言

ECC金字塔:

该金字塔层级之间不是独立的。
scalar multiplication针对的为:

  • (finite, abelian)group GGG,为加法群,计算k⋅Pk\cdot Pk⋅P,其中k∈Z,P∈Gk\in \mathbb{Z},P\in Gk∈Z,P∈G。
  • 而对于乘法群G′G'G′,等价为计算xkx^kxk,其中x∈G′x\in G'x∈G′。

加法群的scalar multiplication 与 乘法群的幂运算,二者算法等价。

Scalar-multiplication广泛用于多种密码学场景中:

  • 基于ECDLP的密钥生成
  • EC Diffie-Hellman密钥交换
  • Schnorr签名

这些场景中都需要计算kPkPkP。
进一步观察可发现:

  • 密钥生成时,点PPP在编译时是固定的。
  • Diffie-Hellman密钥交换时,联合密钥计算时的点是在运行时收到的。
  • Schnorr签名验签时,需要double-scalar multiplication k1P1+k2P2k_1P_1+k_2P_2k1​P1​+k2​P2​。Schnorr签名验签时的scalar值k1,k2k_1,k_2k1​,k2​是public的。

以上场景中,存在secret scalar和public scalar的差异:

  • 无论kkk是secret scalar还是public scalar值,计算kPkPkP的结果应完全相同。

不过在scalar multiplication中需考虑Timing信息问题:

  • 某些快速scalar-multiplication算法其运行时长与kkk值相关。
  • 攻击者可测量时长来推断kkk的信息。
  • 如Brumley, Tuveri, 2011:数分钟即可窃取网络中TLS服务的私钥。

因此,当kkk为secret scalar时,相应的scalar multiplication算法应为constant-time的。

1.1 基于ECDLP的密钥生成

所谓ECDLP(基于椭圆曲线的DLP)为:
已知椭圆曲线上2个点P和QP和QP和Q,Q∈<P>Q\in <P>Q∈<P>,找到某整数kkk,使得kP=QkP=QkP=Q成立。

密码学系统的经典设定为:

  • PPP为某固定的系统参数
  • kkk为私钥
  • QQQ为公钥

已知k和Pk和Pk和P,密钥生成实际是计算Q=kPQ=kPQ=kP。

1.2 EC Diffie-Hellman密钥交换

EC Diffie-Hellman密钥交换针对的场景为:

  • 用户Alice和Bob分别具有密钥对(kA,QA)和(kB,QB)(k_A,Q_A)和(k_B,Q_B)(kA​,QA​)和(kB​,QB​)。
  • Alice将其公钥QAQ_AQA​发送给Bob
  • Bob将其公钥QBQ_BQB​发送给Alice
  • Alice计算联合密钥K=kAQBK=k_AQ_BK=kA​QB​
  • Bob计算联合密钥K=kBQAK=k_BQ_AK=kB​QA​

1.3 Schnorr签名

Schnorr签名的场景为:

  • Alice的密钥对为(kA,QA)(k_A, Q_A)(kA​,QA​)
  • 基点<P><P><P>的order为lll
  • 采用的密码学哈希函数为HHH

Schnorr签名过程为:

  • Alice(签名者)生成密码随机值r∈{1,⋯,l}r\in\{1,\cdots,l\}r∈{1,⋯,l},对于消息mmm进行如下计算获得签名(R,s)(R,s)(R,s):

    • 计算R=rPR=rPR=rP
    • 计算s=(r−H(R,m,QA)kA)modls=(r-H(R,m,Q_A)k_A)\mod ls=(r−H(R,m,QA​)kA​)modl

任何具有Alice公钥QAQ_AQA​的人,都可对消息mmm的签名(R,s)(R,s)(R,s)进行验签,验签过程为:

  • 验证R=sP+H(R,m,QA)QAR=sP+H(R,m,Q_A)Q_AR=sP+H(R,m,QA​)QA​成立,即验签通过。

2. Scalar-multiplication算法演变

以计算105⋅P105\cdot P105⋅P为例:

  • 直观的算法是,直接做104次加法运算:P+P+P+⋯+PP+P+P+\cdots +PP+P+P+⋯+P

但是,105105105约有7个bits,需要约272^727次加法运算。实际真实的scalar值约有256256256个bits,若采用这种直观算法,需要约22562^{256}2256次加法运算(比解决ECDLP还昂贵)。

为此,我们需要scalar-multiplication算法的运行时长为与scalar size呈polynomial time关系的。

将105105105表示为:
105=64+32+8+1=26+25+23+20105=64+32+8+1=2^6+2^5+2^3+2^0105=64+32+8+1=26+25+23+20

进一步表示为:
105=1⋅26+1⋅25+0⋅24+1⋅23+0⋅22+0⋅21+1⋅20105=1\cdot 2^6+1\cdot 2^5+0\cdot 2^4+1\cdot 2^3+0\cdot 2^2+0\cdot 2^1+1\cdot 2^0105=1⋅26+1⋅25+0⋅24+1⋅23+0⋅22+0⋅21+1⋅20

根据Horner’s rule有:
105=((((((((((1⋅2+1)⋅2)+0)⋅2)+1)⋅2)+0)⋅2)+0)⋅2)+1105= ((((((((((1 \cdot 2 + 1) \cdot 2) + 0) \cdot 2) + 1) \cdot 2) + 0) \cdot 2) + 0) \cdot 2) + 1105=((((((((((1⋅2+1)⋅2)+0)⋅2)+1)⋅2)+0)⋅2)+0)⋅2)+1

从而有:
105⋅P=((((((((((P⋅2+P)⋅2)+0)⋅2)+P)⋅2)+0)⋅2)+0)⋅2)+P105\cdot P= ((((((((((P \cdot 2 + P) \cdot 2) + 0) \cdot 2) + P) \cdot 2) + 0) \cdot 2) + 0) \cdot 2) + P105⋅P=((((((((((P⋅2+P)⋅2)+0)⋅2)+P)⋅2)+0)⋅2)+0)⋅2)+P

相应的计算开销减为:

  • 仅需要 666次double运算 和 333 次加法运算

扩展为通用“double-and-add”算法表示为:

2.1 single-scalar multiplication double-and-add算法分析

single-scalar multiplication针对的场景是:

  • 计算kPkPkP

将scalar kkk值以二进制表示,其总bits数为nnn,位为111的总个数为mmm。
double-and-add算法需要:

  • n−1n-1n−1次double运算
  • m−1m-1m−1次加法运算(平均约为n/2n/2n/2次加法运算)

double-and-add算法中,无需提前知道PPP,也没有基于PPP做预计算。

double-and-add算法:

  • 适于处理single-scalar multiplication。
  • 运行时间依赖于具体scalar值,对于secret scalar场景下的scalar-multiplication是不安全的。

2.2 double-scalar multiplication double-and-add算法分析

double-scalar multiplication针对的场景是:【也可参看 书本 《Handbook of Elliptic and Hyperelliptic Curve Cryptography 》multi-exponentiation章节的 Algorithm 9.23算法。】

  • 计算k1P1+k2P2k_1P_1+k_2P_2k1​P1​+k2​P2​

直观的算法是:

  • 1)计算k1P1k_1P_1k1​P1​(需n1−1n_1-1n1​−1次double运算和m1−1m_1-1m1​−1次加法运算)
  • 2)计算k2P2k_2P_2k2​P2​(需n2−1n_2-1n2​−1次double运算和m2−1m_2-1m2​−1次加法运算)
  • 3)将以上结果相加(需111次加法运算)

以上算法可改进为:(其中O\mathcal{O}O表示无穷远点)

改进后的算法,计算k1P1+k2P2k_1P_1+k_2P_2k1​P1​+k2​P2​的开销减为:

  • 仅需max(n1,n2)max(n_1,n_2)max(n1​,n2​)次double运算 和 m1+m2m_1+m_2m1​+m2​次加法运算。

2.3 为scalar-multiplication引入预计算

对2.2节的算法观察可发现,当k1,k2k_1,k_2k1​,k2​在同一位置具有bit 111时,总是先加P1P_1P1​然后再加P2P_2P2​(出现该情况的概率为1/41/41/4)。
因此,可先预计算T=P1+P2T=P_1+P_2T=P1​+P2​。

对2.2节的算法进一步改进为:【为Straus algorithm的特例情况】

若预计算是free的(如fixed basepoint, offline precomputation)等场景下,可以:

  • 预计算出来一个table,其中包含:0P,P,2P,3P,⋯0P,P,2P,3P,\cdots0P,P,2P,3P,⋯,当收到kkk时,仅需查表获得kPkPkP。

但是,当kkk很大时,如kkk为256 bit时,需要的table size为:
3369993333393829974333376885877453834204643052817571560137951281152TB

不过,如果预计算的table中只包含:P,2P,4P,8P,⋯,2n−1PP,2P,4P,8P,\cdots,2^{n-1}PP,2P,4P,8P,⋯,2n−1P。当n=256n=256n=256时,存储该table的size仅需约8KB8KB8KB。
对于kPkPkP这样的single-scalar fixed-basepoint scalar multiplication,相应算法可改进为:

从而可移除fixed-basepoint scalar multiplication中的所有double运算。

2.4 secret scalar 场景下的scalar-multiplication

大多数密码学应用场景下,scalar均为secret的,这就意味着以上算法中的conditional addition中的condition是secret的,为此,可不管condition是啥均做加法运算,相应算法改为:

或者改为,若条件为非1,则与中立元素(无穷远点)O\mathcal{O}O相加:

但是,目前为止,仍未实现secret scalar场景下要求的constant-time属性。

引入table T=(O,P)T=(\mathcal{O}, P)T=(O,P),对以上算法进行重写,此时:

  • T[0]=O,T[1]=PT[0]=\mathcal{O},T[1]=PT[0]=O,T[1]=P
  • 相应的scalar multiplication kPkPkP 算法为:

2.5 不以二进制方式来表示scalar值

以上均是以二进制来表示scalar kkk值。
如果以radix 3来表示kkk,则预计算table T=(O,P,2P)T=(\mathcal{O},P,2P)T=(O,P,2P),并将kkk表示为(kn−1,⋯,k0)3(k_{n-1},\cdots,k_0)_3(kn−1​,⋯,k0​)3​,则kPkPkP的scalar multiplication算法为:

以更高的radix来表示scalar kkk值:

  • 优势是:以更高的radix表示的scalar更短,具有更少的加法运算。
  • 劣势是:radix 333并不足够好,需要做3倍运算。

怎样的radix来表示更优呢?4,8,164,8,164,8,16?

2.5.1 Fixed-window scalar multiplication

固定窗口宽度为www,预计算table T=(O,P,2P,⋯,(2w−1)P)T=(\mathcal{O},P,2P,\cdots,(2^w-1)P)T=(O,P,2P,⋯,(2w−1)P),将scalar kkk值以radix 2w2^w2w表示为(km−1,⋯,k0)2w(k_{m-1},\cdots,k_0)_{2^w}(km−1​,⋯,k0​)2w​,整个算法实现是与将二进制scalar切碎进固定长度为www的“窗口”一样,详细的scalar multiplication算法为:

不过,以上算法:

  • 对于具有nnn-bit scalar值,仍然需要n−1n-1n−1次double运算。
  • 预计算table TTT的开销为:w/2−1w/2-1w/2−1次加法运算 和 w/2−1w/2-1w/2−1次double运算。
  • 在for循环中的加法运算次数为:⌈n/w⌉\left \lceil n/w\right \rceil⌈n/w⌉。
  • 更大的www,意味着更多的预计算。
  • 更小的www,意味着for循环中更多的加法运算。
  • 对于约256256256-bit的scalar值,通常取w=4或w=5w=4或w=5w=4或w=5。

2.5.2 Fixed-window scalar multiplication算法是否为constant time?

2.5.1节的Fixed-window scalar multiplication算法是否为constant time?

  • 对于该scalar的每个window,需要www次double运算,和111次加法运算,似乎可认为是constant time的?

不过,魔鬼在于细节:

  • 1)加法运算是否以constant time运行的?即使是与O\mathcal{O}O的加法运算也是constant time的么?【可让这些加法运算是constant time的,但是具体的实现容易程度以及效率取决于曲线形状(提示:你会想要使用Edward 曲线)。】
  • 2)从预计算table TTT中查找是否是以constant time运行的?【通常不是constant time的。】

2.5.3 Cache-timing攻击

Cache-timing攻击针对的场景为:
从tabel TTT中加载位置p=(k)2w[i]p=(k)_{2^w}[i]p=(k)2w​[i],该位置为secret scalar的一部分,也应是secret的。
但是,大多是处理器是通过多个缓存来加载数据(这些缓存是透明的,fast memory的):

  • 若该数据在cache中找到了,则加载快速(cache hit)
  • 若该数据未在cache中找到,则加载缓慢(cache miss)

为解决该问题,可加载所有items,然后选择正确的那个:

不过,以上算法存在的问题是:

  • 1)if-statements不是constant time的。
  • 2)comparison无法保证是constant time的。

为此:

  • 1)实现constant-time ifs,通用的表达应遵循:

    但是所需时间依赖于bit sss,即使A,BA,BA,B用时相同。原因在于:branch prediction(分支预测)。
    更合适的表达应为:

    可将乘法运算和加法运算替换为bit-logic运算(AND和XOR)。对于很快的A和BA和BA和B,其会比if else这种条件分支要快。

  • 2)实现constant-time comparison:

2.6 针对fixed-basepoint scalar-multiplication的更多离线预计算

2.3节预计算P,2P,4P,8P,⋯P,2P,4P,8P,\cdotsP,2P,4P,8P,⋯之外,结合2.5.1节的fixed-window scalar multiplication,针对i=0,w,2w,3w,⋯,⌈n/w⌉−1i=0,w,2w,3w,\cdots,\left \lceil n/w\right \rceil-1i=0,w,2w,3w,⋯,⌈n/w⌉−1,预计算相应的Ti=(O,P,2P,3P,⋯,(2w−1)P)⋅2iT_i=(\mathcal{O}, P, 2P, 3P,\cdots,(2^w-1)P)\cdot 2^iTi​=(O,P,2P,3P,⋯,(2w−1)P)⋅2i。
整个scalar multiplication算法为:

相应的开销为:

  • 无需double运算,仅有⌈n/w⌉−1\left \lceil n/w\right \rceil-1⌈n/w⌉−1次加法运算。

可使用更大www,但是:

  • 对于某个大www,会使得预计算table无法再载入cache中。
  • 对于大www,意味着constant-time load速度将变慢。

2.7 Sliding-window scalar multiplication

2.5.1节的fixed-window scalar multiplication算法为:

运用2.5.1节的fixed-window scalar multiplication算法计算kPkPkP,k=22=(10110)2k=22=(1\ 01\ 10)_2k=22=(1 01 10)2​,且window size为2时,相应的流程为:

  • 初始化RRR为PPP。
  • double, double, add PPP
  • double, double, add 2P2P2P

但是该场景下,效率更高的算法流程应为:

  • 初始化RRR为PPP。
  • double, double, double, add 3P3P3P
  • double

这就是fixed-window算法的缺陷:它是固定的。

一个解决思路是:“Slide” the window over the scalar。

Sliding-window scalar multiplication算法思路为:

  • 选择window size为www
  • 将scalar kkk值重写为k=(k0,⋯,km)k=(k_0,\cdots,k_m)k=(k0​,⋯,km​),其中每个ki∈{0,1,3,5,⋯,2w−1}k_i\in\{0,1,3,5,\cdots, 2^w-1\}ki​∈{0,1,3,5,⋯,2w−1},使得每个长度为www的窗口内最多只有一个非零entry。
  • 从右到左扫描kkk,每遇到111-bit 就expand window。
  • 预计算P,3P,5P,⋯,(2w−1)PP,3P,5P,\cdots,(2^w-1)PP,3P,5P,⋯,(2w−1)P。

Sliding-window scalar multiplication具体算法为:

相应的开销为:

  • 对于nnn-bit scalar,仍然需要n−1n-1n−1次double运算
  • 预计算量为2w−12^{w-1}2w−1
  • 主循环中加法运算次数的期望值为:n/(w+1)n/(w+1)n/(w+1)
  • 对于相同的www,相比于fixed-window scalar multiplication,其仅需要一半的预计算。
  • 对于相同的www,主循环中的加法运算次数更少。

但是sliding-window算法存在的一个问题是:不是以constant time运行的。但仍然适用于验签环境中的double-scalar场景。

3. 使用 efficient negation加速

以上算法适于任意cyclic group <P><P><P>。
但对于椭圆曲线来说,其可提供更多效率优化策略。
例如,基于Weierstrass curves,efficient negation表示为:
−(x,y)=(x,−y)-(x,y)=(x,-y)−(x,y)=(x,−y)

因此,可用有符号(signed)来表示scalar值。

借助efficient negation,可对Fixed-window scalar multiplication进一步做如下优化:

  • 将scalar表示为(k0,⋯,km−1)(k_0,\cdots,k_{m-1})(k0​,⋯,km−1​),其中ki∈[−2w,⋯,2w−1]k_i\in[-2^w,\cdots,2^w-1]ki​∈[−2w,⋯,2w−1]
  • 预计算T=(−2wP,(−2w+1)P,⋯,O,P,⋯,(2w−1)P)T=(-2^wP,(-2^w+1)P,\cdots,\mathcal{O}, P,\cdots, (2^w-1)P)T=(−2wP,(−2w+1)P,⋯,O,P,⋯,(2w−1)P)
  • 运行正常的fixed-window scalar multiplication。
  • 一半的预计算几乎是free的,可get one bit of www for free。
  • 由于negation很快,可do it on fly(从而节约一半的预计算table,实现更快的constant-time lookups)。

同理,也可借助scalar-negation对sliding-window scalar multiplication进行类似的加速。

4. 使用 efficient endomorphisms加速

Ben展示了在椭圆曲线上存在efficient endomorphisms,以φ\varphiφ来表示。
假设对于所有的Q∈<P>Q\in<P>Q∈<P>,φ(Q)\varphi(Q)φ(Q)对应λQ\lambda QλQ。

见 (Gallant, Lambert, Vanstone, 2000; and Galbraith, Lin, Scott, 2009),可借助efficient endomorphisms,可实现更快的scalar multiplication:

  • 将scalar kkk表示为k=k1+k2λk=k_1+k_2\lambdak=k1​+k2​λ,其中k1,k2k_1,k_2k1​,k2​长度为kkk的一半。
  • 运行half-size double-scalar multiplication k1P+k2⋅φ(P)k_1P+k_2\cdot \varphi(P)k1​P+k2​⋅φ(P)。
  • 可节约一半的double运算(预计速度提升约30%~40%)。

借助2个efficient endomorphisms,可实现4-dimensional decomposition。
执行quarter-size quad-scalar multiplication,可再节约25%的double运算。

5. 使用 Differential addition加速(Montgomery ladder优势)

对于形如By2=x3+Ax2+xBy^2=x^3+Ax^2+xBy2=x3+Ax2+x的椭圆曲线,Montgomery在1987年展示了如何进行基于xxx坐标的计算:【为此,以projective坐标系(X:Z)(X:Z)(X:Z)来表示,其中x=(X/Z)x=(X/Z)x=(X/Z)。Montgomery "ladder step"算法。】

  • 已知点PPP的xxx坐标xPx_PxP​,点QQQ的xxx坐标xQx_QxQ​,点P−QP-QP−Q的xxx坐标xP−Qx_{P-Q}xP−Q​
  • 计算点R=P+QR=P+QR=P+Q的xxx坐标xRx_RxR​。

这种计算称为differential addition。
对于其它形状的椭圆曲线,其differential addition效率要低一些。

仅知点PPP的xxx坐标,可借助differential addition来高效计算kPkPkP的xxx坐标:

使用Montgomery ladder算法的优势在于:

  • 非常整齐的结构,易于保护不受timing攻击。

    • 将其中的if statement替换为conditional swap。
    • 仔细处理constant-time swaps。
  • 速度很快(不与 具有efficient endomorphisms的曲线相比的话)。
  • point压缩和解压缩是free的。
  • 易于实现。
  • 没有恶心的特例情况(见Bernstein的“Curve25519”论文)。

6. multi-scalar multiplication

multi-scalar multiplication针对的场景为:
计算Q=∑1nkiPiQ=\sum_{1}^n k_iP_iQ=∑1n​ki​Pi​

在2.2节看到了n=2n=2n=2的情况,当n=128n=128n=128呢?

思路为:假设k1>k2>⋯>knk_1>k_2>\cdots >k_nk1​>k2​>⋯>kn​。

Bos-Coster算法为递归计算:
Q=(k1−k2)P1+k2(P1+P2)+k3P3⋯+knPnQ=(k_1-k_2)P_1+k_2(P_1+P_2)+k_3P_3\cdots +k_nP_nQ=(k1​−k2​)P1​+k2​(P1​+P2​)+k3​P3​⋯+kn​Pn​

在递归计算过程中:

  • 每一步都需要一次scalar subtraction运算和一次point addition运算。
  • 每一步都“消除” expected log⁡n\log nlogn scalar bits

Bos-Coster算法:

  • 速度可以很快(但不是constant-time的)。
  • 需要能快速访问最大的2个scalar值:将scalars放入heap中。
  • 实现fast heap对于实现好的性能至关重要。

6.1 fast heap

heap为二叉树,每个父节点都大于其2个子节点。
数据结构以数组的形式存储,在该数组中的位置决定了其在树中的位置。
Root在位置0,左叶子节点在位置1,右叶子节点在位置2。
对于在位置iii的节点,其子节点在位置2⋅i+12\cdot i+12⋅i+1和2⋅i+22\cdot i+22⋅i+2,其父节点在位置⌊(i−1)/2⌋\left \lfloor (i-1)/2 \right \rfloor⌊(i−1)/2⌋。

Typical heap root replacement (pop operation)为:从root开始,swap down for a variable amount of times。

Floyd‘s heap为:swap down to the bottom, swap up for a variable amount of times。

Floyd‘s heap的优势为:

  • 每个swap-down step仅需要一次比较(而不是2次)
  • swap-down loop对branch predicators更友好。

7. finite-field inversion

根据Fermat定理可知,xp−1≡1modpx^{p-1}\equiv 1\mod pxp−1≡1modp,从而可知求倒数对应为幂运算:
x−1≡xp−2modpx^{-1}\equiv x^{p-2} \mod px−1≡xp−2modp。

不过这种幂运算实际与scalar multiplication并无本质差异(double运算变为了square运算,加法运算变为了multiplication运算)。

由于素数ppp是公开的,因此p−2p-2p−2也是公开的。

思路一:采用sliding window来进行幂运算。

但是ppp不仅是公开的,而且是固定的系统参数,有更好的方案么?
答案是:addition chains

所谓addition chains,定义为:
令kkk为正整数,若序列s1,s2,⋯,sms_1,s_2,\cdots,s_ms1​,s2​,⋯,sm​满足如下条件,则可称其为kkk的长度为mmm的addition chain:

  • s1=1s_1=1s1​=1
  • sm=ks_m=ksm​=k
  • 对于每个sis_isi​,存在j,k<ij,k<ij,k<i,使得si=sj+sks_i=s_j+s_ksi​=sj​+sk​成立。

因此,可将kkk的addition chain防疫为计算kPkPkP的multiplication算法:

  • 起始状态为s1P=Ps_1P=Ps1​P=P
  • 计算siP=sjP+skPs_iP=s_jP+s_kPsi​P=sj​P+sk​P,其中i=2,⋯,mi=2,\cdots,mi=2,⋯,m

迄今为止,所有的算法本质是计算addition chains “on the fly”。

Signed-scalar表示的是“addition-subtraction chains”。

求倒数时,在编译时知道kkk值,因此,可花大量时间来找到a good addition chain。

F2255−19\mathbb{F}_{2^{255}-19}F2255−19​域内的倒数运算为:

8. 总结

  • 1)基础思想为:double-and-add
  • 2)对于secret scalar情况,不要直接使用double-and-add算法。
  • 3)注意实际要实现constant-time code是困难的。
  • 4)以一杯啤酒来庆祝任何能以254次square运算 + 10次multiplication运算 计算出a2255−21a^{2^{255}-21}a2255−21 的方案。
  • 5)以两杯啤酒来庆祝任何能以254次square运算 + 9次multiplication运算 计算出a2255−21a^{2^{255}-21}a2255−21 的方案。

参考资料

[1] Scalar-multiplication algorithms
[2] cryptojedi.org
[3] Cryptographic Engineering——Scalar multiplication

Scalar-multiplication算法集相关推荐

  1. 这可能是史上最全的Python算法集!

    来源 | CSDN(ID:CSDNnews ) 本文是一些机器人算法(特别是自动导航算法)的Python代码合集. 其主要特点有以下三点:选择了在实践中广泛应用的算法:依赖最少:容易阅读,容易理解每个 ...

  2. python优化算法工具包_这可能是史上最全的 Python 算法集(建议收藏)

    原标题:这可能是史上最全的 Python 算法集(建议收藏) 导读:本文是一些机器人算法(特别是自动导航算法)的Python代码合集.其主要特点有以下三点: 选择了在实践中广泛应用的算法: 依赖最少: ...

  3. Pytorch框架的深度学习优化算法集(优化中的挑战)

    个人简介:CSDN百万访问量博主,普普通通男大学生,深度学习算法.医学图像处理专攻,偶尔也搞全栈开发,没事就写文章,you feel me? 博客地址:lixiang.blog.csdn.net Py ...

  4. 数据结构算法集---C++语言实现

    /// // // // 堆栈数据结构 stack.h // // // /// #include<iostream.h> template<class Type>class ...

  5. VEGA:诺亚AutoML高性能开源算法集简介

    摘要:VEGA是华为诺亚方舟实验室自研的全流程AutoML算法集合,提供架构搜索.超参优化.数据增强.模型压缩等全流程机器学习自动化基础能力. 本文分享自华为云社区<VEGA:诺亚AutoML高 ...

  6. python算法动画_这可能是史上最全的Python算法集!

    来源 | CSDN(ID:CSDNnews ) 本文是一些机器人算法(特别是自动导航算法)的Python代码合集. 其主要特点有以下三点:选择了在实践中广泛应用的算法:依赖最少:容易阅读,容易理解每个 ...

  7. c语言算法集,【二级C语言】数据结构算法集---C  语言实现

    蜡烛马区新固动工八拐怪状小城,小城炮兵会晒茶麸领子.冒算心头画行启脾沙拉,壮志骗人淡漠流生宣布木锯南政新车?猛料妙绝长亭浓味寺塔马兜放领理光.普特民师初生情境民寿流传灭绝!勤恳心曲修整拭除转子苛评. ...

  8. OpenSSL密码库算法笔记——第5.1.2章 椭圆曲线算法集

    在定义椭圆曲线点群时出现了描述曲线所用算法的参数const EC_METHOD *meth,这一节就来看看这个参数有什么用处. 椭圆曲线算法集的定义如下. typedef struct ec_meth ...

  9. OpenSSL密码库算法笔记——第5.3.1章 椭圆曲线点群的算法集

    在使用椭圆曲线之前,必需先设定好曲线上的算法集,只有这样在应用中才知道应该使用哪些函数. 下面就来看看怎样设定好曲线上的方法集. ─────────────────────────────────── ...

最新文章

  1. [C#] enum 枚举
  2. DD来拜年送红包啦!
  3. 计算机考试用远程桌面,职称计算机考试:教你体验XP远程桌面多用户登录
  4. 如何绑定多个action到一个slot
  5. 腾讯alloyteam团队前端代码规范(记录)
  6. dev-mysql_GitHub - intergrate-dev/mysql-elasticsearch
  7. dlink虚拟服务器端口转发,D-Link路由器端口转发怎么设置【图文教程】
  8. 做数据可视化有什么好
  9. SWPUACM第二次周赛
  10. Axure中引入Echarts图表并制作元件库
  11. 2018年最令人惊讶的WordPress统计数据
  12. ha rose server安装 sql_ROSE HA V8.9+Win2008+SQL2008双机配置详细指南(图文)
  13. 网页微信linux,Ubuntu安装Linux网页版微信
  14. 每日简报 4月22日简报新鲜事 每天一分钟 了解新鲜事
  15. 弘辽科技:宝妈开淘宝网店,要不要注册公司才能做电商呢?
  16. 后台管理系统导出Excel表格的方法
  17. percona-toolkit的安装及简介
  18. OpenAcc的使用
  19. sea.js简单配置
  20. 利用Python来爬取“吃鸡”数据,为什么别人能吃鸡?

热门文章

  1. Unity与全息投影
  2. 自适应波束形成(三)——频域宽带LCMV波束形成器
  3. VIM 编辑器使用教程
  4. 2019.12.31罗振宇2020年跨年演讲《时间的朋友》精华全文版本——思维决定一个人的上限,能力决定一个人的下限
  5. Netsuite设置中文多语言
  6. LeetCode 167.Two Sum II 解题报告
  7. 使用Xshell连接Ubuntu 20.4系统时提示
  8. python使用pandas中的to_json函数将dataframe数据写入json文件中
  9. win10+docker+laradock最新安装
  10. [Luogu P3642] [BZOJ 4585] [APIO2016]烟火表演