.net-core - 为什么Curve25519即使参数错误也能正确计算 key 对?

标签 .net-core elliptic-curve diffie-hellman curve-25519 x25519

.NET (Core 3.1) 似乎支持 ECC 中的自定义曲线。所以我定义了 Curve25519 , 并通过以下代码生成 key 对:

using System;
using System.Security.Cryptography;

namespace Curve25519
{
    class Program
    {
        static void Main(string[] args)
        {
            ECCurve ecCurve = new ECCurve() // Curve25519, 32 bytes, 256 bit
            {
                CurveType = ECCurve.ECCurveType.PrimeMontgomery,
                B = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
                A = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x07, 0x6d, 0x06 }, // 486662
                G = new ECPoint()
                {
                    X = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 },
                    Y = new byte[] { 0x20, 0xae, 0x19, 0xa1, 0xb8, 0xa0, 0x86, 0xb4, 0xe0, 0x1e, 0xdd, 0x2c, 0x77, 0x48, 0xd1, 0x4c,
                    0x92, 0x3d, 0x4d, 0x7e, 0x6d, 0x7c, 0x61, 0xb2, 0x29, 0xe9, 0xc5, 0xa2, 0x7e, 0xce, 0xd3, 0xd9 }
                },
                Prime = new byte[] { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed },
                //Prime = new byte[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
                Order = new byte[] { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x14, 0xde, 0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6, 0x58, 0x12, 0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed },
                Cofactor = new byte[] { 8 }
            };

            using (ECDiffieHellman ecdhOwn = ECDiffieHellman.Create())
            {
                // generate the key pair
                ecdhOwn.GenerateKey(ecCurve);
                // save ECDiffieHellman implicit parameters including private key
                ECParameters ecdhParamsOwn = ecdhOwn.ExportParameters(true);
                // print key pair
                Console.WriteLine(BitConverter.ToString(ecdhParamsOwn.D) + "\r\n" + BitConverter.ToString(ecdhParamsOwn.Q.X) + "\r\n" + BitConverter.ToString(ecdhParamsOwn.Q.Y));
            }
        }
    }
}
示例输出如下:
90-54-A7-71-C0-03-D9-69-40-21-A4-CF-8C-81-7C-09-C4-CD-7A-44-77-2E-19-AD-B7-09-82-C9-AC-6E-AF-46
80-32-26-BD-C3-85-BC-35-17-98-B1-6C-C7-31-EF-BE-21-91-BA-CD-4A-BD-87-5B-FB-EC-4B-6B-02-C9-07-46
00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
然后我想与另一个库/平台交叉检查,即 x-cube-cryptolib/stm32f103c8。给定 ECDiffieHellman 生成的私钥(第一行),控制库计算相同的公钥(第二行),验证该对(万岁)。
在进行 key 交换阶段之前,我想尝试一下,并更改了 Curve25519 的参数,如代码中注释掉的素数。我希望看到两个平台从同一个私钥计算不同公钥的错误或计算。但是不,ECDiffieHellman 总是计算控制库确认的 key 对。我将曲线参数更改为错误、交换或归零,我对每个参数都这样做,清理并重建项目,但每次的情况都是一样的。即使在我进行 key 交换阶段时,ECDiffieHellman 计算出与控制库相同的共享 key Material 。
为什么 ECDiffieHellman/Curve25519 会以某种方式生成正确的 key 对和共享 key ,它们与控制库一致,即使其定义参数错误,似乎忽略了它们?或者这可能是关于 .Net Core 的 ECDH 实现的?

最佳答案

我不知道你提到的库,但我知道一点关于 curve25519 .
ECDH 当然是采用对应的公钥点(实际上是 k[G] ,其中 k 是他们的私钥(一个被限制的 256-bit 数字)和 G 是曲线的生成点)并将其乘以你的私钥,产生 yourK * theirK * G .
这个过程是交换式 这就是为什么当对方对你的公钥和他们的私钥做同样的事情时它会起作用。
现在,至于为什么曲线参数似乎无关紧要。 curve25519是高度优化的椭圆曲线密码系统。优化了标量乘法(variable base 用于ECDH 的标量乘法),优化了点算术等。乘法仅使用X-coordinate 执行。和微分加法。见 here详情。X25519 (curve25519+ECDH) 专门使用“X-only”标量乘法,其中点仅由它们的 X 表示。协调。这是在恒定时间内进行 key 交换的最快和最简单的方法之一,恒定时间对于旁道定时攻击很重要。
实际需要曲线的唯一时间是当我们执行 EdDSA 时点减压。 EdDSA点线格式由 Y 坐标和 X 的符号组成。协调。
并不是忽略了曲线,当然,椭圆曲线运算必须尊重它们运算的基础曲线,实际上是定义该曲线的伽罗瓦域,更多的是保证正在使用的计算保持在曲线定义。
如果您将所有参数归零,那很奇怪,但是如果您仍然离开该字段(在您的情况下为 Prime),如 2^255 - 19 ,这一定足以让ECDH类知道该怎么做。
因此,简而言之,我认为在 ECDH 计算中实际上可能没有使用曲线方程。

关于.net-core - 为什么Curve25519即使参数错误也能正确计算 key 对?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65039528/

相关文章:

c# - 在 LINQ Query net core 3 中使用函数逻辑

c# - ASP.NET Core Web API 中的过滤结果

c# - 弹跳城堡 C# : How to Implement EllipticCurve Encryption/Decryption

cryptography - python Diffie Hellman 标准库

c# - 在 .NET Core 或 UWP 中使用 C# 使 Windows 10 主音量静音

c# - 由于 SSL 握手异常,.NET Core 3.0 上的 WebRequest 第二次失败

java - 使用 ECC Curve25519 在 Java 中加密/解密数据

java - 从 W 参数在主机端生成 ECDSA 公钥

cryptography - 我正在为 Diffie-Hellman 使用 Wincrypt——我可以以纯文本格式导出共享 key 吗?

google-chrome - 内部网站的 Chrome 错误 "Server has a weak ephemeral Diffie-Hellman public key"