Skip to content
This repository has been archived by the owner on Apr 23, 2019. It is now read-only.

Make SEC256K1 key interfaces consistent with sodium #31

Merged
merged 2 commits into from
Aug 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 36 additions & 19 deletions bytes/src/main/java/net/consensys/cava/bytes/Bytes.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
Expand Down Expand Up @@ -343,7 +344,7 @@ static Bytes minimalBytes(long value) {
* @return The value corresponding to {@code str}.
* @throws IllegalArgumentException if {@code str} does not correspond to valid hexadecimal representation.
*/
static Bytes fromHexStringLenient(String str) {
static Bytes fromHexStringLenient(CharSequence str) {
checkNotNull(str);
return BytesValues.fromHexString(str, -1, true);
}
Expand All @@ -363,7 +364,7 @@ static Bytes fromHexStringLenient(String str) {
* @throws IllegalArgumentException if {@code str} does not correspond to valid hexadecimal representation, represents
* more bytes than {@code destinationSize} or {@code destinationSize < 0}.
*/
static Bytes fromHexStringLenient(String str, int destinationSize) {
static Bytes fromHexStringLenient(CharSequence str, int destinationSize) {
checkNotNull(str);
checkArgument(destinationSize >= 0, "Invalid negative destination size %s", destinationSize);
return BytesValues.fromHexString(str, destinationSize, true);
Expand All @@ -380,7 +381,7 @@ static Bytes fromHexStringLenient(String str, int destinationSize) {
* @throws IllegalArgumentException if {@code str} does not correspond to valid hexadecimal representation, or is of
* an odd length.
*/
static Bytes fromHexString(String str) {
static Bytes fromHexString(CharSequence str) {
checkNotNull(str);
return BytesValues.fromHexString(str, -1, false);
}
Expand All @@ -401,7 +402,7 @@ static Bytes fromHexString(String str) {
* @throws IllegalArgumentException if {@code str} does not correspond to valid hexadecimal representation, or is of
* an odd length, or represents more bytes than {@code destinationSize} or {@code destinationSize < 0}.
*/
static Bytes fromHexString(String str, int destinationSize) {
static Bytes fromHexString(CharSequence str, int destinationSize) {
checkNotNull(str);
checkArgument(destinationSize >= 0, "Invalid negative destination size %s", destinationSize);
return BytesValues.fromHexString(str, destinationSize, false);
Expand Down Expand Up @@ -1020,6 +1021,24 @@ default void appendTo(Buffer buffer) {
}
}

/**
* Append this value as a sequence of hexadecimal characters.
*
* @param appendable The appendable
* @param <T> The appendable type.
* @return The appendable.
* @throws IOException If an IO error occurs.
*/
default <T extends Appendable> T appendHexTo(T appendable) throws IOException {
int size = size();
for (int i = 0; i < size; i++) {
byte b = get(i);
appendable.append(AbstractBytes.HEX_CODE[b >> 4 & 15]);
appendable.append(AbstractBytes.HEX_CODE[b & 15]);
}
return appendable;
}

/**
* Return the number of bytes in common between this set of bytes and another.
*
Expand Down Expand Up @@ -1115,27 +1134,25 @@ default byte[] toArrayUnsafe() {
* @return This value represented as hexadecimal, starting with "0x".
*/
default String toHexString() {
int size = size();
StringBuilder r = new StringBuilder(2 + size * 2);
r.append("0x");

for (int i = 0; i < size; i++) {
byte b = get(i);
r.append(AbstractBytes.HEX_CODE[b >> 4 & 15]);
r.append(AbstractBytes.HEX_CODE[b & 15]);
try {
return appendHexTo(new StringBuilder("0x")).toString();
} catch (IOException e) {
// not thrown
throw new RuntimeException(e);
}

return r.toString();
}

/** @return This value represented as a minimal hexadecimal string (without any leading zero). */
default String toShortHexString() {
String hex = toString();
// Skipping '0x'
if (hex.charAt(2) != '0')
return hex;
StringBuilder hex;
try {
hex = appendHexTo(new StringBuilder());
} catch (IOException e) {
// not thrown
throw new RuntimeException(e);
}

int i = 3;
int i = 0;
while (i < hex.length() && hex.charAt(i) == '0') {
i++;
}
Expand Down
6 changes: 3 additions & 3 deletions bytes/src/main/java/net/consensys/cava/bytes/Bytes32.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ static Bytes32 leftPad(Bytes value) {
* @throws IllegalArgumentException if {@code str} does not correspond to valid hexadecimal representation or contains
* more than 32 bytes.
*/
static Bytes32 fromHexStringLenient(String str) {
static Bytes32 fromHexStringLenient(CharSequence str) {
checkNotNull(str);
return wrap(BytesValues.fromRawHexString(str, SIZE, true));
}
Expand All @@ -160,7 +160,7 @@ static Bytes32 fromHexStringLenient(String str) {
* @throws IllegalArgumentException if {@code str} does not correspond to valid hexadecimal representation, is of an
* odd length, or contains more than 32 bytes.
*/
static Bytes32 fromHexString(String str) {
static Bytes32 fromHexString(CharSequence str) {
checkNotNull(str);
return wrap(BytesValues.fromRawHexString(str, SIZE, false));
}
Expand All @@ -177,7 +177,7 @@ static Bytes32 fromHexString(String str) {
* @throws IllegalArgumentException if {@code str} does not correspond to valid hexadecimal representation, is of an
* odd length or does not contain exactly 32 bytes.
*/
static Bytes32 fromHexStringStrict(String str) {
static Bytes32 fromHexStringStrict(CharSequence str) {
checkNotNull(str);
return wrap(BytesValues.fromRawHexString(str, -1, false));
}
Expand Down
32 changes: 13 additions & 19 deletions bytes/src/main/java/net/consensys/cava/bytes/BytesValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,22 @@ private BytesValues() {}
static final int MAX_UNSIGNED_SHORT = (1 << 16) - 1;
static final long MAX_UNSIGNED_INT = (1L << 32) - 1;

static Bytes fromHexString(String str, int destSize, boolean lenient) {
static Bytes fromHexString(CharSequence str, int destSize, boolean lenient) {
return Bytes.wrap(fromRawHexString(str, destSize, lenient));
}

static byte[] fromRawHexString(String str, int destSize, boolean lenient) {
String hex = str;
if (str.startsWith("0x")) {
hex = str.substring(2);
static byte[] fromRawHexString(CharSequence str, int destSize, boolean lenient) {
int len = str.length();
CharSequence hex = str;
if (len >= 2 && str.charAt(0) == '0' && str.charAt(1) == 'x') {
hex = str.subSequence(2, len);
len -= 2;
}

int len = hex.length();
int idxShift = 0;
if (len % 2 != 0) {
if (!lenient) {
throw new IllegalArgumentException("Invalid odd-length hex binary representation '" + str + "'");
throw new IllegalArgumentException("Invalid odd-length hex binary representation");
}

hex = "0" + hex;
Expand All @@ -46,12 +47,7 @@ static byte[] fromRawHexString(String str, int destSize, boolean lenient) {
if (destSize < 0) {
destSize = size;
} else {
checkArgument(
size <= destSize,
"Hex value %s is too big: expected at most %s bytes but got %s",
str,
destSize,
size);
checkArgument(size <= destSize, "Hex value is too large: expected at most %s bytes but got %s", destSize, size);
}

byte[] out = new byte[destSize];
Expand All @@ -63,18 +59,16 @@ static byte[] fromRawHexString(String str, int destSize, boolean lenient) {
if (h == -1) {
throw new IllegalArgumentException(
String.format(
"Illegal character '%c' found at index %d in hex binary representation '%s'",
"Illegal character '%c' found at index %d in hex binary representation",
hex.charAt(i),
i - idxShift,
str));
i - idxShift));
}
if (l == -1) {
throw new IllegalArgumentException(
String.format(
"Illegal character '%c' found at index %d in hex binary representation '%s'",
"Illegal character '%c' found at index %d in hex binary representation",
hex.charAt(i + 1),
i + 1 - idxShift,
str));
i + 1 - idxShift));
}

out[destOffset + (i / 2)] = (byte) (h * 16 + l);
Expand Down
16 changes: 8 additions & 8 deletions bytes/src/test/java/net/consensys/cava/bytes/BytesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ void fromHexStringLenient() {
@Test
void fromHexStringLenientInvalidInput() {
Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexStringLenient("foo"));
assertEquals("Illegal character 'o' found at index 1 in hex binary representation 'foo'", exception.getMessage());
assertEquals("Illegal character 'o' found at index 1 in hex binary representation", exception.getMessage());
}

@Test
Expand All @@ -303,13 +303,13 @@ void fromHexStringLenientLeftPadding() {
@Test
void fromHexStringLenientLeftPaddingInvalidInput() {
Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexStringLenient("foo", 10));
assertEquals("Illegal character 'o' found at index 1 in hex binary representation 'foo'", exception.getMessage());
assertEquals("Illegal character 'o' found at index 1 in hex binary representation", exception.getMessage());
}

@Test
void fromHexStringLenientLeftPaddingInvalidSize() {
Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexStringLenient("0x001F34", 2));
assertEquals("Hex value 0x001F34 is too big: expected at most 2 bytes but got 3", exception.getMessage());
assertEquals("Hex value is too large: expected at most 2 bytes but got 3", exception.getMessage());
}

@Test
Expand All @@ -327,13 +327,13 @@ void fromHexString() {
@Test
void fromHexStringInvalidInput() {
Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexString("fooo"));
assertEquals("Illegal character 'o' found at index 1 in hex binary representation 'fooo'", exception.getMessage());
assertEquals("Illegal character 'o' found at index 1 in hex binary representation", exception.getMessage());
}

@Test
void fromHexStringNotLenient() {
Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexString("0x100"));
assertEquals("Invalid odd-length hex binary representation '0x100'", exception.getMessage());
assertEquals("Invalid odd-length hex binary representation", exception.getMessage());
}

@Test
Expand All @@ -353,18 +353,18 @@ void fromHexStringLeftPadding() {
@Test
void fromHexStringLeftPaddingInvalidInput() {
Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexString("fooo", 4));
assertEquals("Illegal character 'o' found at index 1 in hex binary representation 'fooo'", exception.getMessage());
assertEquals("Illegal character 'o' found at index 1 in hex binary representation", exception.getMessage());
}

@Test
void fromHexStringLeftPaddingNotLenient() {
Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexString("0x100", 4));
assertEquals("Invalid odd-length hex binary representation '0x100'", exception.getMessage());
assertEquals("Invalid odd-length hex binary representation", exception.getMessage());
}

@Test
void fromHexStringLeftPaddingInvalidSize() {
Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexStringLenient("0x001F34", 2));
assertEquals("Hex value 0x001F34 is too big: expected at most 2 bytes but got 3", exception.getMessage());
assertEquals("Hex value is too large: expected at most 2 bytes but got 3", exception.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
/**
* Exception thrown when reading a store that contains an invalid SEC256K1 private keys.
*/
public final class InvalidSEC256K1PrivateKeyStoreException extends RuntimeException {
public final class InvalidSEC256K1SecretKeyStoreException extends RuntimeException {
}