Skip to main content

crypto/curves/curve_test.go

package curves

import (
"encoding/hex"
"encoding/json"
"fmt"
"testing"

"github.com/decred/dcrd/dcrec/edwards/v2"
"github.com/decred/dcrd/dcrec/secp256k1/v2"
"github.com/okx/threshold-lib/crypto"
)

func TestCurve(t *testing.T) {
curve := secp256k1.S256()
x := crypto.RandomNum(curve.N)
point := ScalarToPoint(curve, x)
fmt.Println(point)

ecPoint := point.ScalarMult(x)
fmt.Println(ecPoint)

bytes, _ := json.Marshal(ecPoint)
fmt.Println(string(bytes))
p := ECPoint{}
_ = json.Unmarshal(bytes, &p)
fmt.Println(p)

add, _ := ecPoint.Add(&p)
fmt.Println(add)
}

func TestPointToPubKey(t *testing.T) {
curve := secp256k1.S256()
x := crypto.RandomNum(curve.N)
fmt.Println("private key: ", hex.EncodeToString(x.Bytes()))
point := ScalarToPoint(curve, x)
publicKey := secp256k1.PublicKey{Curve: point.Curve, X: point.X, Y: point.Y}
fmt.Println("ecdsa publicKey: ", hex.EncodeToString(publicKey.SerializeCompressed()))

curve2 := edwards.Edwards()
point2 := ScalarToPoint(curve2, x)
publicKey2 := edwards.PublicKey{Curve: point2.Curve, X: point2.X, Y: point2.Y}
fmt.Println("ed25519 publicKey: ", hex.EncodeToString(publicKey2.SerializeCompressed()))
}

// 公钥转化成点
func TestPubKeyToPoint(t *testing.T) {
// ecdsa publicKey: 0220dcc94db44d846a174b10765bbc2ea916988d098598eb812aaddd5c7378f29d
point, err := EcdsaPubKeyToPoint("0220dcc94db44d846a174b10765bbc2ea916988d098598eb812aaddd5c7378f29d")
if err != nil {
fmt.Println(err)
} else {
fmt.Println("---------")
fmt.Println(point)
fmt.Println("---------")
}

// ed25519 publicKey: d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
point2, err := Ed25519PubKeyToPoint("bb10a2166436f1d8d1b8dc18403ed0b254b5d024e4e1b1a62d697803cb1c4379")
if err != nil {
fmt.Println(err)
} else {
fmt.Println(point2)
}
}


测试用例的 目的

这段 Go 代码包含了几个测试用例,主要用于测试椭圆曲线加密库中的功能。这些测试用例涉及到椭圆曲线的基本操作,如密钥生成、点乘、点加以及密钥与点的转换。这里使用了两种不同的椭圆曲线:secp256k1edwards(可能指的是 Ed25519 曲线)。以下是每个测试用例的详细说明:

TestCurve

  1. 密钥生成:使用 secp256k1.S256() 获取椭圆曲线的参数,并生成一个随机数 x 作为私钥,该随机数小于曲线的阶 N
  2. 点乘操作:将私钥 x 转换成椭圆曲线上的点 point,然后使用这个点进行标量乘法(ScalarMult),即点自乘,得到新的点 ecPoint
  3. 序列化与反序列化:将 ecPoint 序列化为 JSON 字符串,然后再反序列化回 ECPoint 结构体。
  4. 点加操作:将 ecPoint 与反序列化后的点 p 进行加法操作,得到新的点 add

目的:为了验证椭圆曲线是否正确

info

TestCurve 测试用例中,所执行的操作主要是为了验证椭圆曲线密码学库在处理基本椭圆曲线操作时的正确性和功能完整性。这个测试用例通过一系列的步骤确保了以下几点:

  1. 密钥生成:验证随机数生成器能够在给定的椭圆曲线阶内正确生成随机数。这保证了生成的私钥是有效和安全的,符合椭圆曲线密码学的要求。

  2. 点乘操作(标量乘法):检查椭圆曲线上的点乘操作是否正确实现。点乘是椭圆曲线密码学中最核心的运算之一,用于生成公钥、计算签名等关键步骤。在这个测试中,通过将私钥(一个标量)与其对应的点进行乘法操作,来验证乘法运算的实现是否正确。

  3. 序列化与反序列化:测试椭圆曲线点的序列化和反序列化功能。在实际应用中,椭圆曲线上的点经常需要在网络中传输或存储,这要求点能够被正确地序列化成一种标准格式,并能从该格式正确恢复。这一步骤检查了序列化机制是否能够无损地保存和恢复椭圆曲线点的数据。

  4. 点加操作:验证点加操作的实现。点加是椭圆曲线上的另一种基本运算,用于诸如密钥协商过程中计算共享密钥等。这个测试通过加法操作确保了点的加法运算符合椭圆曲线的代数规则。

通过这些测试,开发者可以确保椭圆曲线密码学库的关键功能按预期工作,没有实现错误或逻辑缺陷。这对于任何依赖于椭圆曲线密码学的安全系统来说都是至关重要的,特别是在需要高安全性的应用场景(如金融服务、身份验证、区块链等)中。

TestPointToPubKey

  1. 密钥生成:与 TestCurve 中类似,生成随机私钥 x
  2. 生成公钥:将私钥 x 转换为对应的公钥点,分别用 secp256k1edwards 曲线。
  3. 公钥序列化:将这些公钥点序列化为压缩形式的字符串,并打印出来。

目的:验证椭圆曲线密码学库中将椭圆曲线上的点转换为公钥的功能是否正确实现

info

TestPointToPubKey 这一测试用例的目的是验证椭圆曲线密码学库中将椭圆曲线上的点转换为公钥的功能是否正确实现。这一步骤在密码学中尤为重要,因为它涉及到从椭圆曲线上的几何点(这是一个数学上的抽象概念)到实际应用中使用的公钥(通常是一种可用于加密通信的格式化数据)的转换。以下是这一测试可能涉及的几个关键方面:

  1. 正确性验证: 确保从椭圆曲线上的点到公钥的转换过程遵循了正确的算法和协议。公钥需要正确地反映椭圆曲线点的坐标,并且必须符合预期的格式和标准(如 SEC(Standards for Efficient Cryptography)格式)。

  2. 格式和编码: 测试椭圆曲线点是否被正确编码为公钥。这通常涉及到坐标的编码(比如将 x 和 y 坐标转换为字节串)以及可能的压缩形式,其中只包含 x 坐标和一个用于表示 y 坐标奇偶性的标志位。

  3. 兼容性: 确保生成的公钥能与其他系统或软件交互。例如,在区块链技术中,生成的公钥必须能够被网络中其他节点接受和验证。

  4. 安全性: 验证转换过程中没有引入安全漏洞。公钥的生成和表示必须能防止常见的攻击,如中间人攻击或重放攻击。

  5. 性能: 测试这一转换过程的效率和性能,确保它不会在实际应用中成为性能瓶颈。

通过TestPointToPubKey,开发者可以确保椭圆曲线密码学库在将椭圆曲线上的点转换为用于加密、签名或其他密码学操作的公钥时,既准确无误又高效可靠。这对于保障加密系统的整体安全性和功能完整性是非常关键的。

TestPubKeyToPoint

  1. 公钥到点的转换:将给定的公钥字符串转换回椭圆曲线上的点。这里分别处理了 secp256k1edwards 曲线的公钥。
  2. 错误处理:如果转换过程中出现错误,会打印错误信息。

这些测试用例主要用于验证椭圆曲线库的功能是否正确实现,包括密钥生成、点的运算(加法和乘法)以及公钥与点之间的正确转换。这对于加密库的开发和维护是非常重要的,确保库的操作正确无误,安全性得到保障。

目的:公钥转化成点在椭圆曲线密码学中有多个重要用途,特别是在实现和验证加密算法、签名算法以及进行密钥交换时

info

以下是一些具体的应用场景:

  1. 验证签名: 在数字签名算法中,如 ECDSA(Elliptic Curve Digital Signature Algorithm)或 EdDSA(Edwards-curve Digital Signature Algorithm),签名的验证过程需要将公钥从其序列化形式转换为椭圆曲线上的点。这个点随后用于计算签名的有效性,通过一系列的椭圆曲线点运算来确认签名是否由持有相应私钥的实体生成。

  2. 密钥协商: 在密钥交换协议中,如 ECDH(Elliptic Curve Diffie-Hellman),两个参与方各自生成一个临时的公私钥对,并将公钥发送给对方。接收方将收到的公钥(通常是序列化的形式)转换为椭圆曲线上的点,然后使用自己的私钥与对方的公钥点进行运算,以生成一个共享的密钥。这个共享密钥可以用于后续的加密通信。

  3. 加密和解密: 在某些基于椭圆曲线的加密方案中,如 ElGamal 椭圆曲线加密,公钥被用来加密数据,而转换为点的公钥是执行加密运算的必要步骤。同样地,解密过程也需要用到椭圆曲线上的点。

  4. 公钥验证: 在某些系统中,为了确保公钥的合法性和有效性,需要将公钥从其序列化形式转换成点,并对其进行一系列的验证过程,例如检查点是否确实位于椭圆曲线上,以及是否满足曲线方程。

  5. 区块链和加密货币: 在比特币和其他基于区块链的加密货币中,公钥的转换也是验证交易的一个关键步骤。公钥点用于验证交易签名的正确性,从而确保交易的安全性和完整性。

总之,将公钥转化为椭圆曲线上的点是椭圆曲线密码学中的一个基础操作,对于实现安全的加密通信、数据签名和验证等功能至关重要。这一步骤确保了数字身份和数据的安全性,是现代加密系统的核心组成部分。