# 使用secp256k1曲线
## 背景
ECDSA(Elliptic Curve Digital Signature Algorithm)是一种基于椭圆曲线的数字签名算法,广泛应用于比特币、以太坊等区块链系统。
其中,secp256k1 是 ECDSA 的一种标准椭圆曲线参数,被比特币和以太坊采用。
secp256k1曲线可以由六元组 `T = (p,a,b,G,n,h)`描述, 曲线方程式定义为:
```
y^2 = x^3 + 7
```
即`a=0 ,b=7`
因为计算机对于数字类型的最大取值有限制,所以对于曲线方程,secp256k1限定了x和y的取值范围,其中有限域Fp定义为:
`p= FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F`
`= 2^256 – 2^32 – 2^9 – 2^8 – 2^7 – 2^6 – 2^4 – 1`
即`0<=x,y
压缩形式的基点G为:
`G= 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798`
未压缩的形式,即G的x,y坐标是:
`G= 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 , 483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8`
G的阶n和协因子(又称辅助因子)h是:
`n= FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141`
`h= 01`
## 版本
- 长安链底链chainmaker-go从v2.3.8开始全面支持secp256k1曲线。
- 长安链工具chainmaker-cryptogen从v2.3.6开始支持secp256k1曲线。
- `仅支持公钥模式(pk模式)`,因为secp256k1曲线公钥一般不会用于生成证书,所以长安链证书模式(cert模式)暂不支持secp256k1曲线。
## 使用方法
chainmaker-cryptogen的分支必须使用v2.3.6及以上
修改配置文件:`chainmaker-cryptogen/config/pk_config_template.yml`
将配置文件pk_algo的值改为 ecc_secp256k1 ,hash_algo的值改为SHA256,大小写均可。
hash类型必须使用`SHA256`,包括`pk_config_template.yml`、节点配置、sdk配置的hash算法都需要指定为`SHA256`
```yml
pk_config:
pk_algo: ecc_secp256k1
hash_algo: SHA256
```
然后回到chainmaker-go/scripts目录,根据实际需求,依次执行:
```
prepare_pk.sh
build_release.sh
cluster_quick_start.sh
```
## 查看secp256k1设置是否成功
### 使用golang代码判断
使用长安链common模块代码判断私钥类型,common模块的版本需要在v2.3.9及以上。
示例代码如下,如果代码走到`println("ok")`分支,则代表`PrivateKeyFromPEM`的参数是secp256k1类型的私钥:
```
package yourpackage
import (
"chainmaker.org/chainmaker/common/v2/crypto"
"chainmaker.org/chainmaker/common/v2/crypto/asym"
"testing"
)
func TestPrivate(t *testing.T) {
k1, err := asym.PrivateKeyFromPEM([]byte("chainmaker-go生成的secp256k1类型私钥"), nil)
if err != nil {
t.Error(err)
}
if k1.Type() == crypto.ECC_Secp256k1 {
println("ok")
}
}
```
### 根据私钥格式判断
由长安链prepare_pk.sh生成的私钥,使用 `more private.key`查看私钥的格式,如果没有`begin`字样,且格式是长度约为64的一串个16进制字符,则可以初步判断是secp256k1类型的私钥。
下面给出一个范例:
```
0a7c0d6220c8040ea3162d1d7c403a6d67e3aed4c6ad7d71100a48cd49b168e4
```
### 查看节点id判断
节点id是由节点公钥或者证书计算得来,所以可以查看节点id的前缀,以 16U 开头的节点id,就说明该节点的公钥是ecc_secp256k1的。
节点id的查看方法为:每个节点的`/config/`路径下`*.nodeid`文件,里面记录了当前节点的节点id即nodeid。
不同模式/config/ 下面的路径略有不同,但是最终都能找到`*.nodeid`文件。
cert模式路径一般是 `/config/wx-org1.chainmaker.org/certs/node/consensus1/consensus1.nodeid`
pk模式路径一般是 `/config/node1/node1.nodeid`