为什么Curve25519即使参数错误也可以正确计算密钥对? [英] Why does Curve25519 calculate key pair correctly even though its parameters are wrong?

查看:100
本文介绍了为什么Curve25519即使参数错误也可以正确计算密钥对?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.NET(Core 3.1)似乎在ECC中支持自定义曲线.因此,我定义了 Curve25519 ,并通过以下代码生成了密钥对:

It seems that .NET (Core 3.1) supports custom curves in ECC. So I've defined the Curve25519, and generated key pair by below code:

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(第一行)生成的私钥,控制库将计算相同的公钥(第二行),以验证该对(hooray).

Then I wanted to cross check with another library/platform, namely x-cube-cryptolib/stm32f103c8. Given the private key generated by ECDiffieHellman (1st line), control library calculated the same public key (2nd line), validating the pair (hooray).

在进入密钥交换阶段之前,我想使用它,并更改了Curve25519的参数,如代码中注释掉的质数所示.我期望两个平台在同一私钥上看到错误或计算出不同的公钥.但是不,ECDiffieHellman总是会计算出控制库确认的密钥对.我将曲线参数更改为错误,被交换或置零,然后对每个参数进行了此操作,清理并重建了项目,但是每次的情况都是相同的.即使我进入了密钥交换阶段,ECDiffieHellman仍计算出与控制库相同的共享密钥材料.

Before proceeding to key exchange phase, I wanted to play with it, and altered the parameters of Curve25519, as in commented-out prime at the code. I expected to see an error or calculation of different public keys from the same private key by the 2 platforms. But no, ECDiffieHellman always calculated key pairs that control library confirms. I altered curve parameters to be wrong, swapped or zeroed, and I did this for every parameter, cleaned and rebuilt the project, but the case was the same every time. Even when I proceeded to key exchange phase, ECDiffieHellman calculated the same shared secret key material as the control library.

为什么ECDiffieHellman/Curve25519会以某种方式生成与控件库一致的正确密钥对和共享机密,即使其定义参数有误,但似乎忽略了它们?还是这与.Net Core的ECDH实施有关?

Why does ECDiffieHellman/Curve25519 somehow generate correct key pairs and shared secret, which are coherent with the control library, even though its definition parameters are wrong, seemingly ignoring them? Or maybe this is about .Net Core's ECDH implementation?

推荐答案

我不知道您提到的库,但是我确实对 curve25519 有一点了解.

I don't know the libs you mention, but I do know a fair bit about curve25519.

ECDH当然是获取对方公钥的行为(实际上是 k [G] ,其中 k 是他们的私钥(固定的 256-bit 数字)和 G 是曲线的生成点),然后将其乘以您的私钥,得到 yourK *他们的K * G .

ECDH is of course the act of taking a counterparts public key point (really k[G], where k is their private key (a clamped 256-bit number) and G is the curve's generator point), and multiplying it by your private key, yielding yourK * theirK * G.

此过程是可交换的,这就是为什么当对方使用您的公共密钥和私有密钥进行相同操作时会起作用的原因.

This process is commutative which is why it works when the counterpart does the same with your public key and their private key.

现在,为什么曲线参数似乎无关紧要. curve25519 是一个高度优化的椭圆曲线密码系统.标量乘法已优化(可变基数标量乘法用于ECDH),优化点算法等.仅使用 X坐标和微分加法执行乘法.有关详细信息,请参见此处.

Now, as to why the curve parameters seemingly don't matter. curve25519 is a highly highly optimised elliptic curve crypto-system. The scalar multiplication is optimised (variable base scalar multiplication used for ECDH), the point arithmetic is optimised, etc. The multiplication is executed using only the X-coordinate and differential additions. See here for details.

X25519 (curve25519 + ECDH)仅使用仅X"标量乘法,其中点仅由其 X 坐标表示.这是在恒定时间内进行密钥交换的最快,最简单的方法之一,恒定时间对于边信道定时攻击很重要.

X25519 (curve25519+ECDH) exclusively uses "X-only" scalar multiplication, where points are represented only by their X coordinate. This is one of the fastest and simplest way to do key exchange in constant time, constant time is important for side-channel timing attacks.

真正需要曲线的唯一时间是当我们执行 EdDSA 点解压缩时. EdDSA 点线格式由Y坐标和 X 坐标的符号组成.

The only time the curve is actually needed is when we execute EdDSA point decompression. EdDSA points wire format is made of the Y coordinate, and the sign of the X coordinate.

并不是要忽略曲线,当然,椭圆曲线运算必须尊重其所依据的基础曲线以及定义该曲线的Galois字段,更多的是要保证所使用的计算能够按定义停留在曲线上.

It's not that the curve is ignored, of course, elliptic curve operations must respect the underlying curve over which they operate and indeed the Galois field over which that curve is defined, it's more that the computation which is being used is guaranteed to stay on the curve by definition.

如果要将所有所有参数清零,那很奇怪,但是如果您仍要将该字段(在本例中为 Prime )保留为 2 ^255-19 ,这足以让ECDH类知道该怎么做.

If you're zeroing all parameters, that's weird, but if you're still leaving the field (Prime in your case), as 2^255 - 19, this must be enough for the ECDH class to know what to do.

因此,简而言之,我 可能实际上没有在ECDH计算中使用曲线方程式.

Thus, in short, I think it's likely not actually using the curve equation in the ECDH calculations.

这篇关于为什么Curve25519即使参数错误也可以正确计算密钥对?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆