Details
-
Bug
-
Status: Closed
-
P4
-
Resolution: Not an Issue
-
8, 11, 16
-
None
Description
ADDITIONAL SYSTEM INFORMATION :
win10
A DESCRIPTION OF THE PROBLEM :
// Find first non-sign (0xff) byte of input
for (keep=0; keep < byteLength && a[keep] == -1; keep++)
;
makePositive finds the first ff. If ff follows another ff, that is ffff, the later ff was also changed to 0. This causes the failure of Elliptic Curve Digital Signature Algorithm verification.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Elliptic Curve Digital Signature Algorithm uses schnorr which uses biginteger to save private key. When the private key stars with FFFF. The lost of 1st FF can be 00. But the 2nd FF is changed to 00 which causes the verification failure.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
00ffc37874ca020e496a6080fdea0a9af4d3584dca0014e9d6b070621105a492
ACTUAL -
0000c37874ca020e496a6080fdea0a9af4d3584dca0014e9d6b070621105a492
---------- BEGIN SOURCE ----------
private static final char HexCharArr[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
private static final String HexStr = "0123456789abcdef";
public static String byteArrToHex(byte[] btArr) {
char strArr[] = new char[btArr.length * 2];
int i = 0;
for (byte bt : btArr) {
strArr[i++] = HexCharArr[bt>>>4 & 0xf];
strArr[i++] = HexCharArr[bt & 0xf];
}
return new String(strArr);
}
public static byte[] hexToByteArr(String hexStr) {
char[] charArr = hexStr.toCharArray();
byte btArr[] = new byte[charArr.length / 2];
int index = 0;
for (int i = 0; i < charArr.length; i++) {
int highBit = HexStr.indexOf(charArr[i]);
int lowBit = HexStr.indexOf(charArr[++i]);
btArr[index] = (byte) (highBit << 4 | lowBit);
index++;
}
return btArr;
}
public static byte[] bigIntegerToBytes(BigInteger b, int numBytes) {
if (b == null)
return null;
byte[] bytes = new byte[numBytes];
byte[] biBytes = b.toByteArray();
if (numBytes == biBytes.length)
return biBytes;
int start = (biBytes.length == numBytes + 1) ? 1 : 0;
int length = Math.min(biBytes.length, numBytes);
System.arraycopy(biBytes, start, bytes, numBytes - length, length);
return bytes;
}
public static void main(String[] args) {
String str="ffffc37874ca020e496a6080fdea0a9af4d3584dca0014e9d6b070621105a492";
BigInteger x= new BigInteger(hexToByteArr(str));
System.out.println(byteArrToHex(bigIntegerToBytes(x,32)));
}
---------- END SOURCE ----------
win10
A DESCRIPTION OF THE PROBLEM :
// Find first non-sign (0xff) byte of input
for (keep=0; keep < byteLength && a[keep] == -1; keep++)
;
makePositive finds the first ff. If ff follows another ff, that is ffff, the later ff was also changed to 0. This causes the failure of Elliptic Curve Digital Signature Algorithm verification.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Elliptic Curve Digital Signature Algorithm uses schnorr which uses biginteger to save private key. When the private key stars with FFFF. The lost of 1st FF can be 00. But the 2nd FF is changed to 00 which causes the verification failure.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
00ffc37874ca020e496a6080fdea0a9af4d3584dca0014e9d6b070621105a492
ACTUAL -
0000c37874ca020e496a6080fdea0a9af4d3584dca0014e9d6b070621105a492
---------- BEGIN SOURCE ----------
private static final char HexCharArr[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
private static final String HexStr = "0123456789abcdef";
public static String byteArrToHex(byte[] btArr) {
char strArr[] = new char[btArr.length * 2];
int i = 0;
for (byte bt : btArr) {
strArr[i++] = HexCharArr[bt>>>4 & 0xf];
strArr[i++] = HexCharArr[bt & 0xf];
}
return new String(strArr);
}
public static byte[] hexToByteArr(String hexStr) {
char[] charArr = hexStr.toCharArray();
byte btArr[] = new byte[charArr.length / 2];
int index = 0;
for (int i = 0; i < charArr.length; i++) {
int highBit = HexStr.indexOf(charArr[i]);
int lowBit = HexStr.indexOf(charArr[++i]);
btArr[index] = (byte) (highBit << 4 | lowBit);
index++;
}
return btArr;
}
public static byte[] bigIntegerToBytes(BigInteger b, int numBytes) {
if (b == null)
return null;
byte[] bytes = new byte[numBytes];
byte[] biBytes = b.toByteArray();
if (numBytes == biBytes.length)
return biBytes;
int start = (biBytes.length == numBytes + 1) ? 1 : 0;
int length = Math.min(biBytes.length, numBytes);
System.arraycopy(biBytes, start, bytes, numBytes - length, length);
return bytes;
}
public static void main(String[] args) {
String str="ffffc37874ca020e496a6080fdea0a9af4d3584dca0014e9d6b070621105a492";
BigInteger x= new BigInteger(hexToByteArr(str));
System.out.println(byteArrToHex(bigIntegerToBytes(x,32)));
}
---------- END SOURCE ----------