处理问题的BigInteger [英] Processing BigInteger issues
问题描述
假设以下的Diffie-Hellman信息也可在此的页面
1)p
字符串givenp =00e655cc9e04f3bebae76ecca77143ef5c4451876615a9f8b4f712b8f3bdf47ee7f717c09bb5b2b66450831367d9dcf85f9f0528bcd5318fb1dab2f23ce77c48b6b7381eed13e80a14cca6b30b5e37ffe53db15e2d6b727a2efcee51893678d50e9a89166a359e574c4c3ca5e59fae79924fe6f186b36a2ebde9bf09fe4de50453;
的BigInteger P =新的BigInteger(HexToBytesv2(givenp));
2)G
的BigInteger G =新的BigInteger(2);
3)商家私钥
字符串merchantPrivateKeyHEX =48887dfd090d175e33beea29e7b38334299289069f9ab492b67807905faa98d96d22d79205bef03f14af093f1797b904734132c34a388fdc79e20497bfa1465fec2aac4fabdf3bb0c9be8685d20f7bfe0346a9abdf7fa89838c3fa9ca6abdb70bea66795ab6699cc154db59490e4159f142f7bddff603c1d3d6c4fff8177e11d;
BigInteger的一个=新的BigInteger(HexToBytesv2(merchantPrivateKeyHEX));
使用公式公钥= G ^一个模p
我应该得到的初始链路提供的公共密钥,但在执行时
的BigInteger A = BigInteger.ModPow(克,一,对);
ToHex(A.ToByteArray())
结果我得到的是
00f85c41e84446ecfe43c9911df31d3cf60d83642afd496b741363290139badf75f8b8c5c010dda2446dd483dc553b6c2698c16c9d082391677785f81d54bc9c7c45f8b6d5bdb3e49fec7f5522b880c8c753fb7d3ff2c81e47dcb27d52842def40a812dc95cc679575baf237a955ee9944bd0797326f2a0a58c6c087f9b0b9e82c
而不是
00d9abd78c93dfddeb920d57d6513126d8f1118c9237a45101408dbffe6cfd95b011a016e4e0ab8aef0601e836a452b8bb88be7ca71e4f22f97aa65f8358ee69348d1227d65db6e53641d1a6542aa4be4b4adc75fac816af79a8e3f5097f8313e7b725df37eadc8c774e2033dfa99c95ccef333bf402b066198c30481e2a83875c
任何想法?我必须失去了很明显的,但我不知道是什么,可能是。
P.S。添加功能使用:
公共静态的byte [] HexToBytesv2(此字符串十六进制)
{
如果(hex.Length%2 == 1)
十六进制='0'+六角;
字节[] = RET新字节[hex.Length / 2];
的for(int i = 0; I< ret.Length;我++)
RET [I] = Convert.ToByte(hex.Substring(我* 2,2),16) ;
返回RET;
}
公共静态字符串ToHex(字节[] BA)
{
StringBuilder的十六进制=新的StringBuilder(ba.Length * 2);
的foreach(巴字节B)
hex.AppendFormat({0:X2},B);
返回hex.ToString();
}
这是一个。尾数问题
我已经调整你的编码和解码,现在得到你正在寻找的答案:
公共静态的byte [] HexToBytesv2(十六进制字符串)
{
如果(hex.Length%2 == 1)
十六进制='0' +六角;
字节[] = RET新字节[hex.Length / 2];
的for(int i = 0; I< ret.Length;我++)
RET [I] = Convert.ToByte(hex.Substring(hex.Length - 第(i + 1) * 2,2),16);
返回RET;
}
公共静态字符串ToHex(字节[]字节)
{
变种某人=新的StringBuilder();
的foreach(在bytes.Reverse变种B())
{
sb.AppendFormat({0:X2},B);
}
返回sb.ToString();
}
FYI我用LinqPad和主要方法是从问题的代码(如调整后)与数据没有在路上丢了什么东西检查:
无效的主要()
{
串givenp =00e655cc9e04f3bebae76ecca77143ef5c4451876615a9f8b4f712b8f3bdf47ee7f717c09bb5b2b66450831367d9dcf85f9f0528bcd5318fb1dab2f23ce77c48b6b7381eed13e80a14cca6b30b5e37ffe53db15e2d6b727a2efcee51893678d50e9a89166a359e574c4c3ca5e59fae79924fe6f186b36a2ebde9bf09fe4de50453;
的BigInteger P =新的BigInteger(HexToBytesv2(givenp));
(ToHex(p.ToByteArray())==00e655cc9e04f3bebae76ecca77143ef5c4451876615a9f8b4f712b8f3bdf47ee7f717c09bb5b2b66450831367d9dcf85f9f0528bcd5318fb1dab2f23ce77c48b6b7381eed13e80a14cca6b30b5e37ffe53db15e2d6b727a2efcee51893678d50e9a89166a359e574c4c3ca5e59fae79924fe6f186b36a2ebde9bf09fe4de50453)转储()。
的BigInteger G =新的BigInteger(2);
串merchantPrivateKeyHEX =48887dfd090d175e33beea29e7b38334299289069f9ab492b67807905faa98d96d22d79205bef03f14af093f1797b904734132c34a388fdc79e20497bfa1465fec2aac4fabdf3bb0c9be8685d20f7bfe0346a9abdf7fa89838c3fa9ca6abdb70bea66795ab6699cc154db59490e4159f142f7bddff603c1d3d6c4fff8177e11d;
BigInteger的一个=新的BigInteger(HexToBytesv2(merchantPrivateKeyHEX));
(ToHex(a.ToByteArray())==48887dfd090d175e33beea29e7b38334299289069f9ab492b67807905faa98d96d22d79205bef03f14af093f1797b904734132c34a388fdc79e20497bfa1465fec2aac4fabdf3bb0c9be8685d20f7bfe0346a9abdf7fa89838c3fa9ca6abdb70bea66795ab6699cc154db59490e4159f142f7bddff603c1d3d6c4fff8177e11d)转储()。
的BigInteger A = BigInteger.ModPow(G,A,P);
(ToHex(A.ToByteArray())==00f85c41e84446ecfe43c9911df31d3cf60d83642afd496b741363290139badf75f8b8c5c010dda2446dd483dc553b6c2698c16c9d082391677785f81d54bc9c7c45f8b6d5bdb3e49fec7f5522b880c8c753fb7d3ff2c81e47dcb27d52842def40a812dc95cc679575baf237a955ee9944bd0797326f2a0a58c6c087f9b0b9e82c)转储()。
(ToHex(A.ToByteArray())==00d9abd78c93dfddeb920d57d6513126d8f1118c9237a45101408dbffe6cfd95b011a016e4e0ab8aef0601e836a452b8bb88be7ca71e4f22f97aa65f8358ee69348d1227d65db6e53641d1a6542aa4be4b4adc75fac816af79a8e3f5097f8313e7b725df37eadc8c774e2033dfa99c95ccef333bf402b066198c30481e2a83875c)转储()。
}
在我调换顺序,并列入。 CONCAT(新字节[] {0})ToArray的()
从原来的问题,产量为:
<预类=郎无prettyprint-覆盖>
真
真
真
错
和现在是:
<预类=郎无prettyprint-覆盖>
真
真
错
真
您所看到的另一个问题是 BigInteger.Parse
和字节[]
构造总是期待的前半部分还是最后一个字节的最高位分别是符号位。所以,你需要分别包括额外 0
字符或字节为避免这种情况。
Assume the following Diffie-Hellman info which can also be found on this page
1)P
string givenp = "00e655cc9e04f3bebae76ecca77143ef5c4451876615a9f8b4f712b8f3bdf47ee7f717c09bb5b2b66450831367d9dcf85f9f0528bcd5318fb1dab2f23ce77c48b6b7381eed13e80a14cca6b30b5e37ffe53db15e2d6b727a2efcee51893678d50e9a89166a359e574c4c3ca5e59fae79924fe6f186b36a2ebde9bf09fe4de50453";
BigInteger p = new BigInteger(HexToBytesv2(givenp));
2)G
BigInteger g = new BigInteger(2);
3)Merchant private key
string merchantPrivateKeyHEX = "48887dfd090d175e33beea29e7b38334299289069f9ab492b67807905faa98d96d22d79205bef03f14af093f1797b904734132c34a388fdc79e20497bfa1465fec2aac4fabdf3bb0c9be8685d20f7bfe0346a9abdf7fa89838c3fa9ca6abdb70bea66795ab6699cc154db59490e4159f142f7bddff603c1d3d6c4fff8177e11d";
BigInteger a = new BigInteger(HexToBytesv2(merchantPrivateKeyHEX));
Using the formula publickey = g ^ a mod p
I should get the public key provided in the initial link, yet when executing
BigInteger A = BigInteger.ModPow(g, a, p);
ToHex(A.ToByteArray())
the result I get is
00f85c41e84446ecfe43c9911df31d3cf60d83642afd496b741363290139badf75f8b8c5c010dda2446dd483dc553b6c2698c16c9d082391677785f81d54bc9c7c45f8b6d5bdb3e49fec7f5522b880c8c753fb7d3ff2c81e47dcb27d52842def40a812dc95cc679575baf237a955ee9944bd0797326f2a0a58c6c087f9b0b9e82c
instead of
00d9abd78c93dfddeb920d57d6513126d8f1118c9237a45101408dbffe6cfd95b011a016e4e0ab8aef0601e836a452b8bb88be7ca71e4f22f97aa65f8358ee69348d1227d65db6e53641d1a6542aa4be4b4adc75fac816af79a8e3f5097f8313e7b725df37eadc8c774e2033dfa99c95ccef333bf402b066198c30481e2a83875c
Any ideas? I must be missing pretty obvious but I am not sure what that might be.
P.S. Adding the function being used:
public static byte[] HexToBytesv2(this string hex)
{
if (hex.Length % 2 == 1)
hex = '0' + hex;
byte[] ret = new byte[hex.Length / 2];
for (int i = 0; i < ret.Length; i++)
ret[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
return ret;
}
public static string ToHex(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
It's an endian problem.
I've adjusted your encoding and decoding and now get the answer you're looking for:
public static byte[] HexToBytesv2(string hex)
{
if (hex.Length % 2 == 1)
hex = '0' + hex;
byte[] ret = new byte[hex.Length / 2];
for (int i = 0; i < ret.Length; i++)
ret[i] = Convert.ToByte(hex.Substring(hex.Length - (i+1) * 2, 2), 16);
return ret;
}
public static string ToHex( byte[] bytes)
{
var sb = new StringBuilder();
foreach (var b in bytes.Reverse())
{
sb.AppendFormat("{0:x2}", b);
}
return sb.ToString();
}
FYI I used LinqPad and the main method is your code from the question (as adjusted) with checks that the data has not lost anything on the way:
void Main()
{
string givenp = "00e655cc9e04f3bebae76ecca77143ef5c4451876615a9f8b4f712b8f3bdf47ee7f717c09bb5b2b66450831367d9dcf85f9f0528bcd5318fb1dab2f23ce77c48b6b7381eed13e80a14cca6b30b5e37ffe53db15e2d6b727a2efcee51893678d50e9a89166a359e574c4c3ca5e59fae79924fe6f186b36a2ebde9bf09fe4de50453";
BigInteger p = new BigInteger(HexToBytesv2(givenp));
(ToHex(p.ToByteArray()) == "00e655cc9e04f3bebae76ecca77143ef5c4451876615a9f8b4f712b8f3bdf47ee7f717c09bb5b2b66450831367d9dcf85f9f0528bcd5318fb1dab2f23ce77c48b6b7381eed13e80a14cca6b30b5e37ffe53db15e2d6b727a2efcee51893678d50e9a89166a359e574c4c3ca5e59fae79924fe6f186b36a2ebde9bf09fe4de50453").Dump();
BigInteger g = new BigInteger(2);
string merchantPrivateKeyHEX = "48887dfd090d175e33beea29e7b38334299289069f9ab492b67807905faa98d96d22d79205bef03f14af093f1797b904734132c34a388fdc79e20497bfa1465fec2aac4fabdf3bb0c9be8685d20f7bfe0346a9abdf7fa89838c3fa9ca6abdb70bea66795ab6699cc154db59490e4159f142f7bddff603c1d3d6c4fff8177e11d";
BigInteger a = new BigInteger(HexToBytesv2(merchantPrivateKeyHEX));
(ToHex(a.ToByteArray()) == "48887dfd090d175e33beea29e7b38334299289069f9ab492b67807905faa98d96d22d79205bef03f14af093f1797b904734132c34a388fdc79e20497bfa1465fec2aac4fabdf3bb0c9be8685d20f7bfe0346a9abdf7fa89838c3fa9ca6abdb70bea66795ab6699cc154db59490e4159f142f7bddff603c1d3d6c4fff8177e11d").Dump();
BigInteger A = BigInteger.ModPow(g, a, p);
(ToHex(A.ToByteArray()) == "00f85c41e84446ecfe43c9911df31d3cf60d83642afd496b741363290139badf75f8b8c5c010dda2446dd483dc553b6c2698c16c9d082391677785f81d54bc9c7c45f8b6d5bdb3e49fec7f5522b880c8c753fb7d3ff2c81e47dcb27d52842def40a812dc95cc679575baf237a955ee9944bd0797326f2a0a58c6c087f9b0b9e82c").Dump();
(ToHex(A.ToByteArray()) == "00d9abd78c93dfddeb920d57d6513126d8f1118c9237a45101408dbffe6cfd95b011a016e4e0ab8aef0601e836a452b8bb88be7ca71e4f22f97aa65f8358ee69348d1227d65db6e53641d1a6542aa4be4b4adc75fac816af79a8e3f5097f8313e7b725df37eadc8c774e2033dfa99c95ccef333bf402b066198c30481e2a83875c").Dump();
}
Before I swapped the ordering, and included the .Concat(new byte[] { 0 }).ToArray()
from your original question, the output was:
True
True
True
False
And now it's:
True
True
False
True
The other issue you're seeing is BigInteger.Parse
and the Byte[]
constructor always expect the top bit of the first nibble or last byte respectively to be the sign bit. So you need to include the extra 0
character or byte respectively to avoid that.
这篇关于处理问题的BigInteger的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!