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

查看:36
本文介绍了为什么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) + "
" + BitConverter.ToString(ecdhParamsOwn.Q.X) + "
" + 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 生成的私钥(第一行),控制库计算相同的公钥(第二行),验证该对(万岁).

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 number) 和 G 是曲线的生成点),然后乘以你的私钥,得到 yourK * theirK * 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-coordinate和微分加法执行.请参阅此处了解详情.

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-only";标量乘法,其中点仅由它们的 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.

不是忽略曲线,当然,椭圆曲线运算必须尊重它们运算的基础曲线,实际上是定义该曲线的伽罗瓦域,更多的是保证正在使用的计算根据定义保持在曲线上.

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天全站免登陆