[以太坊源代码分析] IV. 椭圆曲线密码学和以太坊中的椭圆曲线数字签名算法应用

【信息科学与工程学】【安全领域】第三十五篇 网络安全算法表 编号算法名称算法的逐步骤思考推理的数学方程式和分解的数学方程式参数/变量列表复杂度(时间/空间)1​AES (高级加密标准)​1. 密钥扩展:从初始密钥生成轮密钥。 2. 初始轮: 3. 主轮循环(Nr-1轮):  - SubBytes:(非线性字节替换)  - ShiftRows:对状态矩阵的行进行循环移位。  - MixColumns:(在GF(2⁸)上的矩阵乘法)  - AddRoundKey: 4. 最终轮:执行SubBytes、ShiftRows、AddR 阅读详情

数字签名算法在Ethereum中的应用不少,目前已知至少有两处:一是在生成每个交易(Transaction, tx)对象时,对整个tx对象进行数字签名;二是在共识算法的Clique算法实现中,在针对新区块进行授权/封印的Seal()函数里,对新创建区块做了数字签名。这两处应用的签名算法都是椭圆曲线数字签名加密算法(Elliptic Curve Digital Signature Algorithm,ECDSA)。Ethereum 在采用ECDSA进行数字签名的基础上,基于自身的业务需求,又将数字签名过程所用的公钥作为地址类型(common.Address)对象,在许多应用场景下作为地址(即账户的唯一标识符)使用。

有关ECDSA的几个理论概念的关系是这样的:椭圆曲线数字加密算法ECDSA是数字签名算法(DSA)的变例之一,ECDSA的基础是椭圆曲线密码学(Elliptic-curve cryptography,ECC),而ECC的理论前提是椭圆曲线上点的倍积(Elliptic curve point multiplication)。本文将从这些概念的原理讲起,试图讲解一下Ethereum所采用ECDSA的来龙去脉。

1.椭圆曲线点的倍积

概念知识

椭圆曲线的点倍积(point multiplication),指的是椭圆曲线上一个点沿着这条曲线不断的与自身相加,最终落在曲线另一个点上的(计算)过程。也许有些地方会把这里的multiplication翻译成“乘积”或“乘法”,那样的话就要特别注意,这种所谓的“点乘积”,是特指一个标量与一个点的乘积,它属于一种标量乘法(scalar multiplication)。所以,个人觉得将这里的point multiplication翻译成“点倍积”会更准确些,本文会沿用这种翻译。

假设起点是椭圆曲线点P,终点是曲线上点R,于是我们有如下点倍积公式,注意此时标量一定要写在点的左边。

R = nP

上式中的结果R点暂时还计算不出来,我们需要多一些准备。理论上,这里的椭圆曲线所选择的几何方程是固定的,它可以表示为:

y^2 = x^3 + ax + b

上式中a和b都是普通标量参数,以上方程所绘出的几何曲线如下图所示,其中红色曲线表示(a, b) = (-7, 6)时的椭圆曲线,蓝色曲线表示 (a, b) = (-6, 6)时的椭圆曲线。显然,a和b的取值对曲线形状还是有影响的。



现在有了椭圆曲线的具体形状和方程,假设曲线上有一个点P,我们想计算它的倍积nP,该怎么做呢?

这里需要再引入一个概念:椭圆曲线点的相加(point addition)。以上图为例,红色椭圆曲线上有两个点P和Q,设定这两个点相加得到一个同样处于曲线上的R点,这个R点来自P, Q两点直连延长线与椭圆曲线的交点(T点)的共轭点,也就是T点沿X轴的对称点R。由于上述椭圆曲线本身必定沿X轴对称,所以这个R点也必定处于曲线上。

我们从代数的角度重新看下这个问题:

这里我们用XY坐标来表示P,Q,R每个点,结合设定的椭圆曲线公式 y^2 = x^3 + ax + b,可以得到如下解答:


通过引入一个参数lambda,我们可以得到P,Q两点相加得到R点的坐标。

很好,我们再往前跨出一步,如果P点和Q点重合,那么它们相加R点是怎样的呢?这种情况被称之为椭圆曲线点的翻倍或叠加(point double),根据上式,R点的x,y相对坐标不变,我们只需要用一个特殊的lambda值就行了,不过要留意此时的lambda取值跟曲线方程参数a有关:

好的,在拥有了以上这些基础知识之后,我们终于可以计算出椭圆曲线点的倍积,因为对于 R = nP,无论n取何值,我们都可以通过上述“点相加”和“点翻倍”的方法计算出R点坐标。

计算方法

我们来看下具体的如何计算椭圆曲线点倍积 Q = dP,即已知椭圆曲线点P和标量d,计算出曲线点Q。

开始写代码前需要将标量d以二进制的方式表示出来,以便于应用“点相加”和“点翻倍”方法。

上式就是d的二进制表示,代码中将各个系数表示成一个长度为(m+1)的数组d[]即可,d[i]对应于第i个bit位的取值0或1。下列伪代码均来自wiki-PointMultiplication。

最直观的就是迭代型的,比如自底向上的迭代:

// iterative: index increasing
N = P; Q = 0;
for i in [0, m] do:
    if d[i] == 1  then Q = point_add(Q, N)
    N = point_double(N)
return Q
还有从顶向下的迭代:

// iterative: index decreasing
Q = 0;
for i in [m, 0] do:
    Q = point_double(Q)
    if d[i] == 1 then Q = point_add(Q,P)
return Q
可以看出,自顶向下的迭代算法相比前者,计算量其实完全一样,不过可以少用一个局部变量N。

除了迭代型,当然还有递归型的

// recursive
func f(p, n) is 
    if n == 0  then 
        return 0
    else if n == 1 then
        return p
    else if n mod(2) == 1 then
        return point_add(p, f(p, n-1)) 
    else 
        return f(point_double(p), n/2)
除此之外,还可以针对窗口宽度作优化。注意到之前将d以二进制的形式表示,其中的窗口宽度可以表示为1,即2的幂次每次+1。如果现在选取更合适的窗口宽度w,则可以将d表示为成

这样得到的m更小,也就是系数数组d[]的长度更小,这就意味着仅需更少的迭代(递归)次数。相关伪代码可见wiki。

2. 椭圆曲线密码学

椭圆曲线密码学(Elliptic-curve cryptography,ECC)同当前流行的其他几种密码学类型,也是通过一个公钥 + 一个私钥组成的一对钥匙来进行加密相关操作。它基于有限域上特定椭圆曲线进行操作,最重要的操作是椭圆曲线的点倍积,不夸张的说,椭圆曲线点倍积正是椭圆曲线密码学的基石。

为什么这么说呢?因为对于点倍积的计算式Q = nP 而言, 在已知起点P和终点Q的情况下,想要计算出n,理论上在目前计算条件下近乎是不可能的!这个数学证明过程比较复杂,这里只想举一个极端的例子。回看上一章节中那幅图,如果这里选用了图中红色椭圆曲线作点倍积运算,注意到它的左边部分是一个封闭的不规则圆弧,如果倍积运算的终点Q恰好落在这个圆弧上面,那么参数n是死活都算不出来的,因为如果增大n,让Q在圆弧上多循环几圈后依旧保持在Q点...

加密用椭圆曲线的参数组

ECC的使用场景包括数字签名,安全的伪随机数生成等。在应用中,所采用的椭圆曲线必须用一组完整的参数来加以定义,这组参数被称为域参数。一般的,ECC定义的这组参数可表为

(p, a, b, G, n, h)

其中 p 是一个极大的质数,用来表示曲线所有点的范围; a, b 分别是椭圆曲线方程 y^2 = x^3 + ax + b 中的系数;G 是该椭圆曲线上点倍积的基点,对于所有通过点倍积运算得到的曲线上点的集合来说,G可算是它们的生成器(generator);n 是基点G的可倍积阶数,定义为能够使得点倍积nG 不存在的最小的整数n;h 是一个整数常量,它跟椭圆曲线运算中得到点的集合以及 n 有关,h 一般取值为1。

在下一章节中,我们可以看到这些椭圆曲线参数在椭圆曲线数字签名中的应用。

3. 椭圆曲线数字签名算法理论

椭圆曲线数字签名算法(ECDSA)是数字签名算法(DSA)的变例之一,它基于椭圆曲线密码学。相比于基于RSA密码学的DSA,ECDSA在计算数字签名时所需的公钥长度可以大大缩短。比如,对于一项安全级别为80 bits的数字签名来说,ECDSA需要的公钥长度仅仅为安全级别的2倍,即160 bits,而同样安全级别要求下的RSA所需公钥长度至少为1024 bits;同时算法所生成的签名长度,不论是ECDSA还是RSA都大约是320 bits,这样一来,ECDSA相对于RSA在应用上的优势就很明显了。

注:安全级别(security level)的概念是:N bits的安全级别,意味着攻击者大约要经过2^N的运算才能获得本次加密用的私钥。安全级别所代表的bits越长,意味着安全性能越好,越难以被攻破,当然同时在加密时的代价,包括公钥长度和生成签名长度,自然也会相应增加。

ECDSA基于DSA,DSA定义了数字签名生成过程和验证过程的基本步骤,通过比较可以看出,ECDSA遵循了DSA的这些定义,并在一些特定步骤中,转而采用了椭圆曲线的相关操作。这里由于篇幅所限,就不详细介绍DSA的内容了,有兴趣的朋友可以去wiki上一看。

数字签名的生成

下面来看一下ECDSA的签名生成过程,以下内容主要来自wiki_ECDSA

假设Alice要给Bob发一个经过数字签名的消息,他们首先需要定义一组共同接受的椭圆曲线加密用参数,简单的,这组参数可表示为

(CURVE, G, n)

其中,CURVE表示椭圆曲线点域和几何方程;G是所有点倍积运算的基点;n是该椭圆曲线的可倍积阶数(multiplicative order),作为一个很大的质数,n的几何意义在于,nG = 0,即点倍积nG的结果不存在,而对于小于n的任何一个正整数 m = [1,n-1],点倍积mG都可以得到一个合理的处于该椭圆曲线上的点。

其次,Alice要创建一对钥,即一个私钥和一个公钥。私钥来自于[1, n-1]范围内一个随机数:


公钥如下,它来自私钥和基点的椭圆曲线点倍积:

好,准备工作就绪,假设Alice想要对消息m作数字签名,有以下步骤:

  1. 计算 e = HASH(m),HASH是一个哈希加密函数,比如SHA-2,或SHA-3。
  2. 计算 z,来自e的二进制形式下最左边(即最高位)L_n个bits,而L_n是上述椭圆曲线参数中的可倍积阶数n的二进制长度。注意z 可能大于n,但长度绝对不会比 n 更长。
  3. 从 [1, n-1] 内,随机选择一个符合加密学随机安全性的整数k。
  4. 计算一个椭圆曲线上点:
  5. 以下式计算 r 值, 如果r == 0, 则返回步骤3重新计算。

  6. 以下式计算 s 值,如果 s == 0,则返回步骤3重新计算。
  7. 生成的数字签名就是 (r, s)

特别需要注意的是步骤3中 k 的选择,它不仅要满足加密学的随机安全性要求,要像私钥一样保护起来,更重要的是,在每次生成一个新的数字签名时,这个 k 必须每次都要更新。否则,通过上述数字签名过程中的算式相互换算,很容易从中破译出私钥!具体换算过程可见wiki_ECDSA。

数字签名的验证

对于消息的接收方Bob来说,他除了收到数字签名文件外,还会有一份公钥。所以Bob的验证分两部分,首先验证公钥,然后验证签名文件(r, s)。

公钥的验证

  1. 公钥的坐标应是有效的,不会等于一个极限值空点
  2. 通过公钥的坐标验证它必须是处于该椭圆曲线上的点。
  3. 应有下式成立,即曲线的可倍积阶数 n 与公钥的点倍积不存在

签名文件的验证

  1. 验证 r 和 s 均是处于[1, n-1]范围内的整型数;否则验证失败
  2. 计算 e = HASH(n),HAHS()即签名生成过程步骤1中使用的哈希函数。
  3. 计算 z,来自 e的最左边L_n个bits。
  4. 计算参数 w:

  5. 计算两个参数 u1 和 u2:

  6. 计算(x1, y1),如果(x1, y1)不是一个椭圆曲线上的点,则验证失败:
  7. 如果以下恒等式不成立,则验证失败:

以上就是椭圆曲线数字签名算法(ECDSA)的生成和验证的完整过程,在wiki_ECDSA还可以看到关于上述验证方法正确性的证明过程。无论用何种编程语言实现,其中数字签名的生成和验证必然要遵循以上的理论和步骤。

4. go-ethereum中的椭圆曲线数字签名算法

go语言安装包中自带的crypto/ecdsa包中包含了关于椭圆曲线的结构体声明和操作函数,以及ECDSA的签名生成和验证到的完整实现代码。不过,以太坊(go-ethereum)并没有采用这个crypto/ecdsa包来实现它自己的数字签名算法。尽管如此,这部分代码仍然很有阅读的必要,原因有二:1.它里面定义的一些行为接口和结构体类型,依然在被go-ethereum中的代码所使用,以方便调用;2. 它关于ECDSA的实现代码写的简洁清晰,非常适合ECDSA的初学者加以研习。

go语言包中的ecdsa代码包

go语言包自带的crypto/ecdsa相关的结构体如以下UML图所示:


对照着上一章节中ECDSA的算法理论,以上的结构体和接口的声明就非常易于理解了。

  • ecdsa.PublicKey结构体通过持有一个elliptic,Curve接口的实现体,可以提供椭圆曲线的所有属性,和相关操作;PublicKey的成员(X,Y),对应于算法理论中公钥 的坐标。
  • elliptic.Curve接口声明了椭圆曲线的相关操作方法,其中Add()方法就是椭圆曲线点倍积中的“点相加”操作,Double()就是点倍积中的“点翻倍”操作,ScalarMult()根本就是一个点倍积运算(参数k是标量),IsOnCurve()检查参数所代表的点是否在该椭圆曲线上;
  • elliptic.CurveParams结构体实现了<Curve>接口的所有方法,另外用成员属性定义了一个具体的椭圆曲线,比如(Gx, Gy) 表示该椭圆曲线的基点,即算法理论中的G点; N 是与基点对应的可倍积阶数n;B是椭圆曲线几何方程中的参数b,注意此处ecdsa代码包中隐含的椭圆曲线方程为y^2 = x^3 - 3x + b,故只需一项参数b即可。
  • ecdsa.PrivateKey是暴露给外部使用的主要结构体类型,它其实是算法理论中的私钥和公钥的集合。它的成员D,才真正对应于算法理论中的(标量)私钥。
  • ecdsa.ecdsaSignature对应于生成的数字签名(r, s)。

由此可见,go语言自带的crypto/ecdsa代码包从结构体的成员到方法的声明,都力图使得其所代表的ECDSA算法理论清晰易懂。关于实现函数,重点推荐ecdsa/ecdsa.go中的两个函数Sign()和Verify()

// go-1.x/src/crypto/ecdsa/ecdsa.go
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error)
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool
以上两个函数的实现过程,均严格遵循了上一章节介绍的算法理论中的签名生成和验证的过程逐步执行,对于加密算法实现方面的coding会有些不错的启示,有心的朋友可以找来源代码一看究竟。

go-ethereum中对ECDSA的调用

go-ethereum中实际采用的ECDSA函数实现,来自于第三方库libsecp256k1,它是一个C++库,在比特币代码(github_bitcoin)中就有应用,被视为一个经过优化的,针对椭圆曲线secp256k1的一个实现库。secp256k1对应于一组特定的椭圆曲线数字签名参数,包括曲线方程以及签名运算所需的一系列参数等,secp256k1被率先应用在比特币中,关于它的参数细节可见secp256k1,其中所指定的曲线方程为y^2 = x^3 + 7,它的形状如下图所示:


在go-ethereum源代码中,路径在/crypto/下的代码包负责所有与加密相关的操作,libsecp256k1库的源代码也在其中/secp256k1/的子路径下存放,待编译后以C++库文件的方式被调用。

处理数字签名

以go-ethereum中交易对象的代码为例,与ECDSA签名相关的操作,都被放在一个名叫Signer的接口以及它的实现体里了。


接口<Signer>声明的方法中,Sender()用来从tx对象携带的数字签名里解析出公钥并转换成Address类型变量;SignatureValues()从tx对象里取出数字签名的三个部分R,S,V;Hash()返回当前tx对象需要做数字签名的内容,即tx对象中的部分成员变量作RLP编码后取Hash值;Equal()用来比较Signer实现体对象。由此可见,<Signer>接口及其实现体主要提供对已生成数字签名进行操作的方法,

Signer的三个实现类中,HomesteadSigner通过持有FrontierSigner对象,可以节省代码。关于EIP155: EIP(Ethereum Improvement Proposals,EIP)是Ethereum的需求汇总。EIP155是其中一个比较重要的需求,加入了一种抵御重现攻击(Replay Attack)的简单方法,要求在对tx作签名(或恢复签名时),在Hash(*Transaction)函数里的RLP编码环节多选择几个成员变量,所以EIP155Signer中的Hash()是重新定义的。

从数字签名中恢复出公钥(地址)

从数字签名中恢复(解析)出地址变量的函数叫recoverPlain():

// core/types/transaction_signing.go
func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (common.Address, error) {
    V := byte(Vb.Uint64() - 27)
    if !crypto.ValidateSignatureValues(V, R, S, homestead) {
        return common.Address{}, ErrInvalidSig
    }
// encode signature in uncompressed format
    r, s := R.Bytes(), S.Bytes()
    sig := make([]byte, 65)
    copy(sig[32-len(r):32], r)
    copy(sig[64-len(s):64], s)
    sig[64] = V
// recover the public key from the signature
    pub, err := crypto.Ecrecover(sighash[:], sig)
    if err != nil || len(pub) == 0 || pub[0] != 4 {
        return common.Address{}, err
    }
// convert pubKey to Address
    var addr common.Address
    copy(addr[:], crypto.Keccak256(pub[1:])[12:])
    return addr, nil
}
上述recoverPlain()的函数体中,

首先调用crypto.ValidateSignatureValues()来验证数字签名是否正确有效,crypto包的这个方法正是通过调用libsecp256k1库的API,遵循ECDSA算法理论中有关数字签名验证部分来完成的;

其次,将R,S,V拼接出所需的数字签名字符串;

接着,调用crypto.Ecrecover(),凭借被数字签名的内容sighash和签名字符串sig,从中恢复出数字签名所用的公钥,当然,crypto包的方法依然调用libsecp256k1库的API来完成;

最后,在返回的公钥里,去掉标志头所在的第一个byte(值为4),生成它的SHA-3(256 bits)哈希值,再截取其中的后20bytes,此即最终返回的Address类型变量。

生成数字签名

针对某个tx对象生成数字签名的函数叫SignTx()

// core/types/transaction_signing.go
func SignTx(tx *Transaction, s Signer, prv *ecdsa.PrivateKey) (*Transaction, error) {
    h := s.Hash(tx)
    sig, err := crypto.Sign(h[:], prv)
    if err != nil {
        return nil, err
    }
    return tx.WithSignature(s, sig)
}
从SignTx()函数体可以看出,在Signer.Hash()方法提供要签名的内容(即Transaction对象的部分成员RLP编码后哈希)后,生成签名的主要工作交给crypto.Sign()函数来完成。该Sign()的函数体如下:

// /crypto/signature_cgo.go
func Sign(hash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
    if len(hash) != 32 {
        return nil, fmt.Errorf(...)  // hash must be 32 bytes
    }
    seckey := math.PaddedBigBytes(prv.D, n:prv.Params().BitSize/8)
    defer zeroBytes(seckey)
    return secp256k1.Sign(hash, seckey)
}

可见crypto.Sign()函数正是通过调用libsecp256k1库的API来完成椭圆曲线数字签名的生成。

公钥和地址

以太坊中用到的Address类型地址变量,比如每个账户的地址,都来自于椭圆曲线数字签名用的公钥。在数字签名中,公钥可以在多次签名中重复使用,这反映到以太坊的账户上,就是一个账户下的多次交易,即多个不同的Transaction对象,它们所作的数字签名均使用同一个公钥。

具体到变量类型上,Address类型是一个长度为20 bytes的字符串,而椭圆曲线数字签名中的公钥,原生含义应该是曲线上的一个点的坐标(X, Y),那么它们之间必然存在格式上的相互转换。在代码中,这涉及到三种不同格式(类型):地址变量是Address类型,长度为20bytes的字符串;publicKey变量是一个字符串,长度未知;椭圆曲线上的公钥,是一个点的坐标,在ecdsa.PublicKey{}中以成员X,Y表示。

publicKey变量转换成Address类型,在之前提到的core.types.recoverPlain()函数体里介绍过(函数末尾)。

publicKey字符串类型和ecdsa.PublicKey{}类型的格式转换函数,由crypto代码包定义。

// crypto/crypto.go
func ToECDSAPub(pub []byte) *ecdsa.PublicKey {
    x, y := elliptic.Unmarshall(S256(), pub)
    return &ecdsa.PublicKey{Curve:S256(), X:x, Y:y}
}
func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
    return elliptic.Marshall(S256(), pub.X, pub.Y)
}
crypto.ToECDSAPub()函数将一个publicKey的字符串转换成ecdsa.PublicKey{}类型中的点坐标X,Y的形式,FromECDSAPub()函数作相反的操作。所调用的elliptic.Unmarshall()函数的逻辑也很简单,就是将[]byte字符串去掉标志头后,均分成两段,分别赋值给X和Y,然后再由[]byte转换成big.Int,就成了。

ps, 上述代码中的S256(),是本地代码写的一个转换函数,返回一个elliptic.Curve接口的实现类,它基于secp256k1的椭圆曲线参数,自己实现了<Curve>接口声明的所有曲线操作函数,以方便用go语言包中的结构体/接口类型,去使用secp256k1椭圆曲线。

小结:

  • 以太坊中的数字签名全部采用椭圆曲线数字加密算法(ECDSA), 它的理论基础是椭圆曲线密码学(ECC),而ECC存在的理论基础是点倍积(point multiplication)算式 Q = dP 中的私钥 d (几乎)不可能被破译。ECC相对于基于大质数分解的RSA,在提供相同安全级别的情况下,仅需长度更短的公钥。
  • 以太坊中调用的椭圆曲线数字签名算法实现,来自己libsecp256k1库,这是一个针对特定椭圆曲线secp256k1的、经过优化的C++库,并早已被比特币系统采用。
  • 以太坊中的使用的Address类型,比如每个账户的地址,均来自于椭圆曲线数字签名的公钥。
JAVA实现ECDSA椭圆曲线数字签名算法 在本文中,我们将使用Java编程语言来实现ECDSA算法,并提供相应的源代码。通过以上的代码实现和解析,我们成功地使用Java实现了ECDSA椭圆曲线数字签名算法。常用的椭圆曲线有多种参数集,例如NIST提供的P-256、P-384和P-521等曲线。ECDSA算法涉及到一系列的数学运算,包括点的加法、点的乘法、点的压缩等操作。请注意,在实际应用中,我们还需要考虑密钥的安全存储、证书管理等问题。以上代码中,我们通过BouncyCastle提供的API进行了密钥对的生成、数字签名和验证等操作。 阅读详情

相关推荐

CMPE.rar_cmwpe_多尺度排列熵_多尺度熵_多尺度熵计算_时间序列

计算了一个时间序列的多尺度排列熵,可以用于金融时间序列和生理时间序列的复杂性分析。

【加解密篇】利用HashCat破解RAR压缩包加密文件详细教程

在取证知识里挖呀挖呀挖---【蘇小沐】

蘇小沐的电子数据取证博客 2万+

深入解析APS开源排程工具OptaPlanner:链式结构与移动优化

本文深入解析了开源APS排程工具OptaPlanner的核心机制,重点阐述了链式结构如何作为排程优化的“骨架”,通过单一`previous`变量隐式定义资源与顺序,从而简化建模。文章详细介绍了基于此结构的移动操作(如`ChainChangeMove`)如何驱动优化引擎探索解空间,并自动触发影子变量更新与分数计算,为构建高效、灵活的生产计划系统提供了实践指导。

keras9composer的博客 296

【探讨以太坊关键技术之一的椭圆曲线密码原理】| 猿创征文

探讨以太坊关键技术之一的椭圆曲线密码的新算法原理

C/C++/C#/JAVA的博客 641

CHNS数据库下载与使用指南:从申请到导入的全流程解析

面板数据是经济学与公共卫生实证研究的重要支撑。中国健康与营养调查(CHNS)自1989年持续追踪中国居民的家庭与个人健康、营养及经济行为,为研究者提供了跨度近三十年的纵向微观数据。理解CHNS的数据组织原理与申请机制,是高效利用该数据的前提。该数据广泛适用于健康经济学、膳食营养分析及公共政策评估等场景。围绕CHNS的下载流程,完整梳理了注册申请、数据文件解析以及Stata、R、Python三种工具的读取方法,并针对邮箱验证、文件损坏、ID匹配等常见问题提供排查建议,帮助研究者快速建立数据处理基础。

weixin_33624741的博客 283

GE Proficy Historian8.0历史数据库部署与配置全攻略

本文提供了GE Proficy Historian 8.0历史数据库的详细部署与配置指南。内容涵盖安装前的系统环境、权限与依赖检查,服务器安装的关键步骤与类型选择,采集器的安装配置与数据接入,以及客户端工具的使用与数据分析实战。旨在帮助用户规避常见陷阱,实现一次部署成功,构建稳定高效的工业数据归档平台。

silver的专栏 765

一文说明白ECDSA secp256k1 secp256r1 EdDSA ed25519千丝万缕的关系

spec256r1、spec256k1、ed25519都是签名算法,而且是具体数字算法的实现。spec256k1、spec256r1都属于椭圆曲线数字签名算法ECDSA(EllipticCurveDigitalSignatureAlgorithm)签名的具体实现,只是椭圆曲线函数不同。是由NIST(NationalInstituteofStandardsandTechnology)这个组织确定的。......

FeelTouch Labs 2万+

TSMaster二次开发实战:如何用Python搞定CAN/CANFD事件回调(附完整代码)

本文详细介绍了如何利用Python进行TSMaster二次开发,实现CAN/CANFD事件回调功能。通过实战代码演示,讲解了预发送与后处理回调的核心区别、注册流程、资源管理及性能优化技巧,帮助工程师高效构建自动化测试与数据监控应用。

star的博客 667

一起学习以太坊|理解以太坊的椭圆曲线签名

1 原 理 以太坊数字签名和比特币的关系 以太坊数字签名,几乎完全沿用了比特币的数字签名算法ECDSA-secp256k1。只有哈希的生成方式不一样,这个之后会说。ECDSA-secp256k1是一种非对称加密算法。 什么是ECDSA 以太坊数字签名算法使用的是椭圆曲线数字签名算法,英文简称ECDSA。其中EC是“椭圆曲线”的简称,DSA是“数字签名算法”的简称。 什么是secp256k1 椭...

weixin_34153893的博客 660

RV1126B SDK移植实战:从DDR配置到USB烧写全解析

本文详细解析了RV1126B SDK移植的核心实战流程,重点攻克了DDR初始化失败与USB烧写两大难题。文章从理解启动流程入手,提供了DDR配置错误的排查步骤、SDK编译配置要点,并深入讲解了USB烧写的完整操作与常见问题解决方案,旨在帮助开发者高效完成系统移植与稳定运行。

weixin_29164497的博客 542

数据工程师——ETL

文章摘要 ETL(数据抽取、转换、加载)是数据处理的核心流程,负责将分散数据源整合为高质量数据。ETL与ELT的主要区别在于转换步骤顺序,分别适用于不同规模数据场景。数据仓库通过ETL从多个数据源集成数据,支持分析决策。维度建模中的事实表记录业务指标,维度表提供上下文信息。缓慢变化维度(SCD)处理随时间变化的维度数据,常见类型包括直接覆盖型、新增版本型等。数据清洗解决数据缺失、重复、错误等问题,确保数据质量。数据血缘记录数据流转路径,便于问题排查和影响分析。常用ETL工具如Kettle通过转换和作业实现数

weixin_45729710的博客 1558

密码学基础--ECDSA算法入门

从上面签名生成过程,其实我们可以发现,不管是r还是s,它的长度都不会超过模数p,因此P-256签名(r,s)的长度最大理应为256*2 = 512bit.ECDSA的签名总体流程一句话概括:对消息做Hash计算得到H,对M进行计算得到整数对(r,s),(r,s)根据不同编码格式输出S,作为最终签名。仔细看,这个签名的长度竟然来到了568bit,可是我们用的是SECP256R1,这个长度既不是256,也不是256的倍数,这里面到底有什么玄机?为了证明消息是自己发的,用自己的私钥对摘要进行加密,也即签名;

认真搞搞汽车MCU 3087

华为流程L1-L6业务流程深度细化到可执行【附全文阅读】

该文档主要介绍了华为业务流程的深度细化及相关内容,包括流程框架、建模方法、流程模块描述、流程图建模等,旨在帮助企业构建有效的流程体系,实现战略目标。

cdfunlove的博客 4001

ECC椭圆曲线入门

​ECC(Ellipse Curve Cryptography)又称椭圆曲线密码体制、椭圆曲线加密算法等。椭圆曲线加密算法在比特币、区块链上有着广泛的应用。公式: y^2 = x^3 + ax + b这里使用简单易懂的方式对大家介绍这部分内容,让大家有个简单的理解​。

踩踩多来梦的博客 1万+

UDPProbe UDP端口存活探测(发送特征包+响应分析)、UDP服务识别

qDebug() << "收到响应:" << ip.toString() << ":" << port << " 服务:" << serviceName << " 响应长度:" << response.size();qDebug() << "开始探测:" << targetIp << ":" << port << " 超时时间:" << timeout << "ms";qInfo() << "\n==================== UDP探测结果 ====================";

寒寒豆豆软件公司的博客 146

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

ECDSA短信签名

短信所发送的字节有限,一般为140字节左右,若对短信进行签名,会导致短信利用率降低,故短信签名的过程中,签名的长度很关键,ECDSA 签名方式的在长度适中(根据加密算法位数不同而不同)的情况下,提供了很好的安全保障。另外手机短信一般不需要进行加密,因为手机一般处于移动状态,其网络变化,比较大,攻击者要截取并分析比较困难。 手机短信安全防护重点放在:防止被人修改 ECDSA常用签名算法 E...

u010217394的博客 808

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

椭圆曲线ECDSA算法

本文介绍了ECDSA数字签名算法的原理与应用。首先阐述了数字签名的四大特性:可验证性、不可伪造性、不可否认性和数据完整性。然后详细讲解了椭圆曲线密码学(ECC)的基础数学原理,包括点加法和点乘法的几何解释。ECDSA算法部分重点说明了密钥生成、签名过程和验证机制,强调了其基于离散对数难题的安全性。文章指出,ECDSA通过将私钥与消息哈希结合产生签名(R,S),而验证时只需公钥即可确认签名有效性。这种非对称加密特性使其在区块链等领域具有重要应用价值。

懒猫的脚印 708

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

基于ECDSA公私钥实现的“非对称加解密“方案(带源码)

需求 ECDSA(elliptic curve digital signature algorithm) 椭圆曲线数字签名算法是区块链应用常用的签名算法(例如比特币,腾讯的trustsql等),这个算法具有速度快,强度高,签名短等特点。这个算法适合用于签名,但是在openssl库里找不到对应的加解密方案。 在工作中遇到这样的需求,区块链用户(客户端)本身已经拥有了ECDSA的公私钥,现在服务端......

zhengluohai1的专栏 3032

【我的区块链之路】- go实现区块链中常见的各类算法

【转载请标明出处】https://blog.csdn.net/qq_25870633/article/details/82900508 咳咳,为什么要出这一篇文章呢?首先,这段时间本人在找工作,然后被问到了各类算法的底层细节,有些确实很懵逼。这里做个总结,也顺便给大家归纳归纳一下! 上主题: 椭圆曲线加密: 我们先来说一说最常用的 ECC 吧,ECC 就是 Elliptic Curve C...

qq_25870633的博客 3431

JAVA:实现ECDSA椭圆曲线数字签名算法(附带源码)

JAVA:实现ECDSA椭圆曲线数字签名算法(附带源码)

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 1200

Go-ecc数字签名详解与代码

目录Ecc签名的Go实现crypto/ecdsa包签名验证签名截图参考 在Go-数字签名详解与Rsa数字签名代码中已经讲了数字签名的原理,就不重复了 Ecc签名的Go实现 crypto/ecdsa包 func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) 使用私钥对任意长度的hash值(必须是较大信息的hash结果)进行签名,返回签名结果(一对大整数)。私钥的安全性取决于密码读取器的熵度(随机程

关注网络安全、云原生安全 2365

Golang区块链钱包_go语言钱包

只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

2401_84247849的博客 2773

区块链的基石--椭圆曲线密码学

如果SF公式解析有问题,请移步备份链接 https://blog.csdn.net/chenmo1... 椭圆曲线密码学 椭圆曲线密码学(ECC, Elliptic Curve Cryptography)是基于椭圆曲线数学的一种公钥加密方法。 什么是公钥加密方法 在诸如 DES、AES 这类对称密码系统中,信息的发送方使用一把密钥进行...

weixin_34259159的博客 1488

Go 实现:椭圆曲线数字签名算法ECDSA

椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟。它基于椭圆曲线离散对数问题(ECDLP)的难解性,具有密钥短、速度快和安全性高的优点。

Shinobi_Jack的博客 1056
上一篇: [Bluetooth]: android 平台上BLE连接流程之优化方案
下一篇: [以太坊源代码分析] VI. 基于p2p的底层通信(上篇)
teaspring
博客等级 码龄19年 350粉丝 24原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值