我发现不同的Wireguard私钥可以生成相同的公钥。在"不同的键"下我的意思是私钥的第一个字节中的最后四个比特在计算公钥时被忽略。
如果有人能解释一下这种奇怪的行为,我会很感激的。的例子:
❯ echo "Mp4S2elbVWEo2xzGtefU8eIccYMkX3XD8y3yNGeOMXE=" | wg pubkey
YG8wJtIMuqTmO7l4OMDBkT516y8NigBilaqZt3fDdCU=
❯ echo "MJ4S2elbVWEo2xzGtefU8eIccYMkX3XD8y3yNGeOMXE=" | wg pubkey
YG8wJtIMuqTmO7l4OMDBkT516y8NigBilaqZt3fDdCU=
❯ echo "MZ4S2elbVWEo2xzGtefU8eIccYMkX3XD8y3yNGeOMXE=" | wg pubkey
YG8wJtIMuqTmO7l4OMDBkT516y8NigBilaqZt3fDdCU=
❯ echo "M54S2elbVWEo2xzGtefU8eIccYMkX3XD8y3yNGeOMXE=" | wg pubkey
YG8wJtIMuqTmO7l4OMDBkT516y8NigBilaqZt3fDdCU=
这是由于Curve25519夹紧。你可以在Neil Madden的博客文章中读到关于它的所有内容:
https://neilmadden.blog/2020/05/28/whats-the-curve25519-clamping-all-about/
您正在使用256位私钥(32字节)。这是一个完全随机的数。出于安全考虑,并非所有这些可能的数字都适合作为curve25519私钥的标量值。
- 该值需要在2251和2252-1 之间
- 下3位需要为零
256位随机数的箝位函数执行以下步骤:
// clear least-significant 3 bits
t[0] &= 248;
// clear most significant 1 bit (ensure t < 2^252)
t[31] &= 127;
// set the second-most significant bit (ensures t >= 2^251)
t[31] |= 64;
在获得公钥之前执行这些步骤。即使你有一个256位的密钥,也只有2个251个不同的密钥。
因此,不仅第一个字节的最后四位的值无关紧要,而且最后一个字节的前两位的值也无关紧要。