{"content":{"title":"椭圆曲线密码学的奇妙世界","body":"> 原文链接：https://medium.com/coinmonks/the-wonderful-world-of-elliptic-curve-cryptography-b7784acdef50\r\n\r\n\r\n## 介绍\r\n\r\n那么，什么比互联网上的任何其他东西更能保护你的隐私和安全呢？那将是椭圆曲线，尤其是：\r\n\r\n$$y² = x³+ax+b$$\r\n\r\n其中 4a³+27b² ≠ 0（需要避免[奇点](http://mathworld.wolfram.com/SingularPoint.html) ）。最流行的曲线是 Secp256k1（或 Curve 25519），定义为 a=0 且 b=7：\r\n\r\n$$ y² = x³+7 $$ [[链接](https://asecuritysite.com/comms/plot05) \\]\r\n\r\n在这里，使用 ECC（椭圆曲线密码学），我们取一个随机数（_n_），以及椭圆曲线上的一个点（_G_），然后将它们相乘以产生 P：\r\n\r\n$$ P = n G$$\r\n\r\n$G$ 将是曲线上的一个$（x，y）$点，Bob 和 Alice 都知晓。n 将是 Bob 的私钥，P 将是他的公钥。挑战在于，如果 n 是一个 256 位的随机值，即使我们知道 G 和 P，找到这个值也将非常困难。\r\n\r\n因此，让我们看一下 Python 代码，设置一个椭圆曲线：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048664219)\r\n\r\n在这种情况下，我们看到\\_a 为 0，\\_b 为 7（y² = x³+7），我们有一个\\_Gx 和一个\\_Gy 值。我们还有 \\_p，这是一个素数，所有操作都是通过（mod \\_p）函数进行的。在 Python 中，我们可以为 Alice 和 Bob 创建两个密钥对：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048664015)\r\n\r\n我们生成一个随机的 256 位值作为 a，然后通过与 G 相乘找到公钥（A）。这将给我们一个椭圆曲线上的点。请注意，所有操作都是使用（mod \\_p）进行的，其中 mod 运算符是整数除法的余数。\r\n\r\n## 分析密钥\r\n\r\n当我们使用 Openssl 生成密钥对时，我们会看到一个 256 位的私钥（由 32 字节组成），以及 65 字节的公钥。公钥开头的 04 是一个标识符。定义公钥的两个 256 位点（每个点都是 32 字节长）：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048663781)\r\n\r\n在这种情况下，私钥是：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048663967)\r\n\r\n公钥是：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048665010)\r\n\r\n可以查看共享的椭圆曲线参数：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048665211)\r\n\r\n请注意，这里的素数、A、B 和生成器的值与上面 Python 片段中的\\_p、\\_a、\\_b、\\_Gx 和\\_Gx 的值相同，对于此曲线标准的任何应用可能是相同的。如果你感兴趣，一些曲线参数的标准定义在[这里](https://asecuritysite.com/encryption/ecdh3) 。\r\n\r\n## ECC 应用 — 密钥交换\r\n\r\nECC 的两个主要应用是数字签名和密钥交换。在密钥交换中，我们可以采用类似于常见的 Diffie-Hellman 方法的方法：ECDH。使用此方法，Bob 和 Alice 都生成他们的密钥对，然后交换他们的公钥值。接下来，他们将这些值分别与自己的私钥相乘，应该得到相同的点。点的 x 值通常用作共享值，可以用来生成加密密钥\\[[链接](https://asecuritysite.com/encryption/ecdh2) \\]\\[[实际示例](https://asecuritysite.com/encryption/ecdh2) \\]：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048665295)\r\n\r\n一个简单的例子是\\[[链接](https://asecuritysite.com/encryption/ecdh) \\]：\r\n\r\n基点：（920（mod 3851），303（mod 3851））  \r\nAlice 的私钥：25720  \r\nBob 的私钥：15297  \r\n\\==========================  \r\nAlice 的公钥：（1996（mod 3851），3624（mod 3851））  \r\n\r\nBob 的公钥：（94（mod 3851），884（mod 3851））  \r\n\\==========================  \r\nAlice 的共享密钥：（2636（mod 3851），3251（mod 3851））  \r\nBob 的共享密钥：（2636（mod 3851），3251（mod 3851））  \r\n\\==========================  \r\n共享值是 x 值：2636\r\n\r\n## ECC 应用 —  数字签名\r\n\r\nECC 的另一个应用是签名，例如椭圆曲线数字签名算法\\[[这里](https://asecuritysite.com/encryption/ecdsa2) \\]。使用此方法，Alice 将生成一个密钥对，然后使用她的私钥加密消息的哈希值。然后，她将消息和签名的哈希发送给 Bob，Bob 对消息进行哈希，并用 Alice 的公钥解密 Alice 的哈希版本。如果哈希匹配，他就证明了 Alice 发送了消息，并且消息没有改变：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048663739)\r\n\r\n## 比特币地址和签名\r\n\r\n椭圆曲线在互联网、智能卡和物联网应用中随处可见。你还可以在区块链中看到它，区块链中使用它作为标准方法来签署交易。使用此方法，Bob 有一个钱包，其中包含他的公钥和私钥。私钥用于签署他的交易，公钥将证明他是签署者。我们还从密钥对生成 Bob 的 ID。\r\n\r\n为此，Bob 最初创建一个 256 位值，这将是他的私钥。该密钥转换为 Base-58 形式（去除难以区分的字符，如'O'和'l'等\\[[这里](https://asecuritysite.com/encryption/base58) \\]）。这是他的 WiF（钱包互换格式）私钥。他不应该向任何人透露这一点，并且如果可能的话，不应该将其存储在线。接下来，他将生成他的 512 位公钥（如上所示）。然后，将其使用 SHA-256 和 RIPEM-160 进行哈希处理，以生成公钥哈希值。然后，使用 Base-58 将其转换为 Bob 的比特币 ID：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048665725)\r\n\r\n一个示例：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048666306)\r\n\r\n因此，如果我们想向 Bob 发送比特币，我们只需要获取他的地址，然后用我们的公钥签署交易。\r\n\r\n## 添加点\r\n\r\n我们知道如何通过标量值（私钥）将我们的椭圆曲线上的点相乘，但是我们可以将点相加吗？如果我们取两个点：\r\n\r\nP1 = _n G_\r\n\r\nP2 _= m G_\r\n\r\n如果我们将这些点相加，我们得到：\r\n\r\nP1 + P2 = n G + m G = (n + m) G\r\n\r\n因此，如果我们添加公钥（P1 + P2（mod p）），等效的私钥将是（n + m（mod p））。如果 Bob 有一个私钥（a）和一个公钥（A），然后 Trent 有一个私钥（b）和一个公钥（B）。那么公钥将是 A+B，私钥将是 a+b。以下是一个示例\\[[这里](https://asecuritysite.com/encryption/vanity2) \\]：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048666856)\r\n\r\n程序是 Trent 生成一个密钥，Bob 可以使用它来生成等效的公钥：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048667202)\r\n\r\n使用从比特币库中获取的 fast\\_add()和 fast\\_multiply()，我们可以实现如下：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048668199)\r\n\r\n一个示例运行是：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048668399)\r\n\r\n## BN 曲线上的密钥配对\r\n\r\n椭圆曲线在公钥加密中被广泛使用（例如比特币和 Tor）。 BN 曲线（Barreto-Naehrig curve）\\[[paper](https://eprint.iacr.org/2005/133.pdf)\\] 定义了一个椭圆曲线，可用于支持高安全性和效率的配对。本页面使用 256 位 BN 曲线上的配对，并为消息生成签名。椭圆曲线密钥配对还与 zk-SNARKs 和零知识证明一起使用。它可用于“加密乘法”。\r\n\r\n对于椭圆曲线，我们为私钥（p）生成一个 256 位的随机数，然后取椭圆曲线上的一个点（G）\\[x,y\\]，然后将其乘以私钥以获得另一个点（p×x,p×y）。通过这种方式，我们得到 P=p×G，其中 G 是椭圆曲线上的一个已知点，P 是我们的公钥，p 是我们的私钥。\r\n\r\n通过配对，我们可以在点之间推导出更复杂的关系，例如如果 P=G×p，Q=G×q 和 R=G×r，我们可以检查是否 r=p×q，但我们只知道 P、Q 和 R（公共值）。目前我们无法从 P=p×G 计算 pp，即使我们知道 P 和 G。值的暴露受限于我们可以计算 R=G×p×q，但无法确定 p 或 q。\r\n\r\n以下代码集成了 BN-256 代码。让我们通过简单地为消息创建一个签名来测试代码。Bob 将获取一条消息并使用他的私钥创建一个签名，Alice 将使用他的公钥来验证。\r\n\r\n首先我们将消息哈希到椭圆曲线上的一个点（pt）。接下来我们取私钥（priv）— 一个随机的 256 位值 — 并将点乘以 priv 以给出 priv×pt。这就是签名。然后 Bob 通过将他的私钥（priv）乘以 G 来生成他的公钥以给出 priv×G。Alice 然后将消息哈希到椭圆曲线上的一个点（pt）。接着她将此点乘以 Bob 的公钥以得到 pub×pt。她还将签名（sig）乘以 G 以得到 sig×G。如果签名正确，生成的两个值应该匹配\\[[here](https://asecuritysite.com/encryption/bn)\\]：\r\n\r\n![](https://img.learnblockchain.cn/attachments/migrate/1721048668572)\r\n\r\n\r\n\r\n## 结论\r\n\r\n椭圆曲线加密是魔法！"},"author":{"user":"https://learnblockchain.cn/people/21648","address":null},"history":"bafkreifqe4l7vhzmu524u5tkmzpzib5iywjg34h3eit2rdhknowkywvzsa","timestamp":1721051780,"version":1}