Skip to content

Commit

Permalink
feat: add fromBytes function to Key (#1880)
Browse files Browse the repository at this point in the history
Signed-off-by: Ivan Ivanov <[email protected]>
  • Loading branch information
0xivanov authored Jul 4, 2024
1 parent 1555eb5 commit 7692c83
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 1 deletion.
12 changes: 12 additions & 0 deletions sdk/src/main/java/com/hedera/hashgraph/sdk/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package com.hedera.hashgraph.sdk;

import com.google.protobuf.InvalidProtocolBufferException;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.sec.SECNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
Expand Down Expand Up @@ -95,4 +96,15 @@ static Key fromProtobufKey(com.hedera.hashgraph.sdk.proto.Key key) {
public byte[] toBytes() {
return toProtobufKey().toByteArray();
}

/**
* Create Key from proto.Key byte array
*
* @param bytes
* @return Key representation
* @throws InvalidProtocolBufferException
*/
public static Key fromBytes(byte[] bytes) throws InvalidProtocolBufferException {
return fromProtobufKey(com.hedera.hashgraph.sdk.proto.Key.parseFrom(bytes));
}
}
99 changes: 98 additions & 1 deletion sdk/src/test/java/com/hedera/hashgraph/sdk/KeyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.math.BigInteger;
import java.util.List;

import static com.hedera.hashgraph.sdk.Key.fromBytes;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
Expand Down Expand Up @@ -114,7 +115,7 @@ void fromProtoKeyEd25519() {
var cut = PublicKey.fromProtobufKey(protoKey);

assertThat(cut.getClass()).isEqualTo(PublicKeyED25519.class);
assertThat(((PublicKey) cut).toBytes()).containsExactly(keyBytes);
assertThat(cut.toBytes()).containsExactly(keyBytes);
}

@Test
Expand Down Expand Up @@ -275,4 +276,100 @@ void keyListMethods() {
keyList.removeAll(List.of(key2, key3));
assertThat(keyList).isEmpty();
}

@Test
@DisplayName("can convert from bytes ED25519 key to Key")
void fromBytesEd25519() throws InvalidProtocolBufferException {
var keyBytes = Hex.decode("0011223344556677889900112233445566778899001122334455667788990011");
var protoKey = Key.newBuilder().setEd25519(ByteString.copyFrom(keyBytes)).build();
var bytes = protoKey.toByteArray();

var cut = fromBytes(bytes);

assertThat(cut.getClass()).isEqualTo(PublicKeyED25519.class);
assertThat(cut.toBytes()).containsExactly(keyBytes);
}

@Test
@DisplayName("can convert from bytes ECDSA key to Key")
void fromBytesECDSA() throws InvalidProtocolBufferException {
var keyBytes = Hex.decode("3a21034e0441201f2bf9c7d9873c2a9dc3fd451f64b7c05e17e4d781d916e3a11dfd99");

var cut = fromBytes(keyBytes);

assertThat(cut.getClass()).isEqualTo(PublicKeyECDSA.class);
assertThat(cut.toProtobufKey().toByteArray()).containsExactly(keyBytes);
}

@Test
@DisplayName("can convert from bytes key list to Key")
void fromBytesKeyList() throws InvalidProtocolBufferException {
var keyBytes = new byte[][]{
Hex.decode("0011223344556677889900112233445566778899001122334455667788990011"),
Hex.decode("aa11223344556677889900112233445566778899001122334455667788990011")
};

var protoKeyList = KeyList.newBuilder();

for (byte[] kb : keyBytes) {
protoKeyList.addKeys(Key.newBuilder().setEd25519(ByteString.copyFrom(kb)));
}

var protoKey = Key.newBuilder().setKeyList(protoKeyList).build();
var bytes = protoKey.toByteArray();

var cut = fromBytes(bytes);

assertThat(cut.getClass()).isEqualTo(com.hedera.hashgraph.sdk.KeyList.class);

var keyList = (com.hedera.hashgraph.sdk.KeyList) cut;
var actual = keyList.toProtobufKey().getKeyList();

assertThat(actual.getKeysCount()).isEqualTo(2);
assertThat(actual.getKeys(0).getEd25519().toByteArray()).containsExactly(keyBytes[0]);
assertThat(actual.getKeys(1).getEd25519().toByteArray()).containsExactly(keyBytes[1]);
}

@Test
@DisplayName("can convert from bytes threshold key to Key")
void fromBytesThresholdKey() throws InvalidProtocolBufferException {
var keyBytes = new byte[][]{
Hex.decode("0011223344556677889900112233445566778899001122334455667788990011"),
Hex.decode("aa11223344556677889900112233445566778899001122334455667788990011")
};

var protoKeyList = KeyList.newBuilder();

for (byte[] kb : keyBytes) {
protoKeyList.addKeys(Key.newBuilder().setEd25519(ByteString.copyFrom(kb)));
}

var protoThresholdKey = ThresholdKey.newBuilder().setThreshold(1).setKeys(protoKeyList);
var protoKey = Key.newBuilder().setThresholdKey(protoThresholdKey).build();
var bytes = protoKey.toByteArray();

var cut = fromBytes(bytes);

assertThat(cut.getClass()).isEqualTo(com.hedera.hashgraph.sdk.KeyList.class);

var thresholdKey = (com.hedera.hashgraph.sdk.KeyList) cut;
var actual = thresholdKey.toProtobufKey().getThresholdKey();

assertThat(actual.getThreshold()).isEqualTo(1);
assertThat(actual.getKeys().getKeysCount()).isEqualTo(2);
assertThat(actual.getKeys().getKeys(0).getEd25519().toByteArray()).containsExactly(keyBytes[0]);
assertThat(actual.getKeys().getKeys(1).getEd25519().toByteArray()).containsExactly(keyBytes[1]);
}

@Test
@DisplayName("Throws given unsupported key")
void throwsUnsupportedKeyFromBytes() {
byte[] keyBytes = {0, 1, 2};
var protoKey = Key.newBuilder().setRSA3072(ByteString.copyFrom(keyBytes)).build();
var bytes = protoKey.toByteArray();

assertThatExceptionOfType(IllegalStateException.class).isThrownBy(
() -> fromBytes(bytes)
);
}
}

0 comments on commit 7692c83

Please sign in to comment.