c# - NBitcoin 生成重复的比特币地址,对应于等于 1 和 256 的私钥和
问题描述
我正在使用 NBitcoin Nuget 开发一个解决方案,突然我发现它为一些等于 1 和 256 的私钥生成了重复的地址......我用于生成比特币地址的代码如下:
_bitcoin_address=_private_key.PubKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main).ToString();
当 _private_key=1 或 _private_key=512 生成相同的地址例如 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH 时,当 _private_key=4 或 _private_key=256 时会出现同样的问题。
这是一个错误还是我犯了一个错误?
您可以使用以下代码作为 POC:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using NBitcoin;
namespace Bitcoin_address_generation
{
class Program
{
static void Main(string[] args)
{
//generating a private key that is equal to 1
byte[] _priv_bytes1 = IntegerToBytes(1, 32);
Key _private_key1 = new Key();
_private_key1.FromBytes(_priv_bytes1);
//generating a private key that is equal to 256
byte[] _priv_bytes256 = IntegerToBytes(256, 32);
Key _private_key256 = new Key();
_private_key256.FromBytes(_priv_bytes1);
Console.WriteLine(_private_key1.PubKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main).ToString());
Console.WriteLine(_private_key256.PubKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main).ToString());
Console.ReadKey();
}
/// <summary>
/// convert a big integer to byte array
/// </summary>
/// <param name="s"></param>
/// <param name="qLength"></param>
/// <returns></returns>
public static byte[] IntegerToBytes(BigInteger s, int qLength)
{
byte[] bytes = s.ToByteArray();
if (qLength < bytes.Length)
{
byte[] tmp = new byte[qLength];
Array.Copy(bytes, bytes.Length - tmp.Length, tmp, 0, tmp.Length);
return tmp;
}
if (qLength > bytes.Length)
{
byte[] tmp = new byte[qLength];
Array.Copy(bytes, 0, tmp, tmp.Length - bytes.Length, bytes.Length);
return tmp;
}
return bytes;
}
}
}
解决方案
经过一些问题/回答后,我发现 NBitcoin 没有任何错误,但以下功能是有罪的:
public static byte[] IntegerToBytes(BigInteger s, int qLength)
{
byte[] bytes = s.ToByteArray();
if (qLength < bytes.Length)
{
byte[] tmp = new byte[qLength];
Array.Copy(bytes, bytes.Length - tmp.Length, tmp, 0, tmp.Length);
return tmp;
}
if (qLength > bytes.Length)
{
byte[] tmp = new byte[qLength];
Array.Copy(bytes, 0, tmp, tmp.Length - bytes.Length, bytes.Length);
return tmp;
}
return bytes;
}
修正后的函数必须如下:
/// <summary>
/// convert a big integer to byte array
/// </summary>
/// <param name="s"></param>
/// <param name="qLength"></param>
/// <returns></returns>
public static byte[] convert_integer_to_byte(BigInteger _input, int qlength)
{
byte[] _temp_byte = _input.ToByteArray();
_temp_byte.Reverse();
byte[] _result_byte;
if (_temp_byte.Length < qlength)
{
_result_byte = new byte[qlength];
_temp_byte.Reverse();
_temp_byte.CopyTo(_result_byte, 0);
}
else
{
_result_byte = new byte[qlength];
_temp_byte.CopyTo(_result_byte, 0);
}
//_result_byte.Reverse();
return _result_byte;
}
最后感谢Lucas Ontivero和Dan Gershony,他们帮助我找到并解决了问题。
推荐阅读
- ios - 动画后屏幕上残留的iOS模拟器鬼影边缘
- angular - Angular 5 [ngForOf] 仅显示循环中的最后一条记录
- java - Equals 语句对同一个字母的大写和小写都有效
- php - 尝试使用 PHP 在所有网站页面中包含相同的标题(mac)
- sql-server - 如何将 TimeSpan 添加到 SQL Server 中的时间列
- android-studio - 两个视图,无法选择 ListView
- c# - 在 C# 中验证小费计算器中的数据
- identityserver4 - 生产中 https 上的身份服务器 4 错误
- autofac - Autofac 参数从模型解析到存储库
- php - 带有 Twig trans 的转换器组件