> getItem() {
- return item;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/SignerResponse.java b/src/main/java/org/torusresearch/torusutils/apis/SignerResponse.java
deleted file mode 100644
index ff120db..0000000
--- a/src/main/java/org/torusresearch/torusutils/apis/SignerResponse.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.torusresearch.torusutils.apis;
-
-import com.google.gson.annotations.SerializedName;
-
-public class SignerResponse {
- @SerializedName("torus-timestamp")
- private final String torus_timestamp;
- @SerializedName("torus-nonce")
- private final String torus_nonce;
- @SerializedName("torus-signature")
- private final String torus_signature;
-
- public SignerResponse(String _torus_timestamp, String _torus_nonce, String _torus_signature) {
- torus_timestamp = _torus_timestamp;
- torus_nonce = _torus_nonce;
- torus_signature = _torus_signature;
- }
-
- public String getTorus_timestamp() {
- return torus_timestamp;
- }
-
- public String getTorus_nonce() {
- return torus_nonce;
- }
-
- public String getTorus_signature() {
- return torus_signature;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/VerifierLookupItem.java b/src/main/java/org/torusresearch/torusutils/apis/VerifierLookupItem.java
deleted file mode 100644
index 4c1ae64..0000000
--- a/src/main/java/org/torusresearch/torusutils/apis/VerifierLookupItem.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.torusresearch.torusutils.apis;
-
-public class VerifierLookupItem {
- private final String key_index;
- private final String pub_key_X;
- private final String pub_key_Y;
- private final String address;
-
- public String getKey_index() {
- return key_index;
- }
-
- public String getPub_key_X() {
- return pub_key_X;
- }
-
- public String getPub_key_Y() {
- return pub_key_Y;
- }
-
- public String getAddress() {
- return address;
- }
-
- public VerifierLookupItem(String _key_index, String _pub_key_X, String _pub_key_Y, String _address) {
- key_index = _key_index;
- pub_key_X = _pub_key_X;
- pub_key_Y = _pub_key_Y;
- address = _address;
- }
-
-}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/VerifierLookupRequestParams.java b/src/main/java/org/torusresearch/torusutils/apis/VerifierLookupRequestParams.java
deleted file mode 100644
index 0b1b200..0000000
--- a/src/main/java/org/torusresearch/torusutils/apis/VerifierLookupRequestParams.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.torusresearch.torusutils.apis;
-
-public class VerifierLookupRequestParams {
- private final String verifier;
- private final String verifier_id;
-
- public VerifierLookupRequestParams(String _verifier, String _verifier_id) {
- verifier = _verifier;
- verifier_id = _verifier_id;
- }
-
- public String getVerifier() {
- return verifier;
- }
-
- public String getVerifier_id() {
- return verifier_id;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/VerifierLookupRequestResult.java b/src/main/java/org/torusresearch/torusutils/apis/VerifierLookupRequestResult.java
deleted file mode 100644
index 85a7b96..0000000
--- a/src/main/java/org/torusresearch/torusutils/apis/VerifierLookupRequestResult.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.torusresearch.torusutils.apis;
-
-public class VerifierLookupRequestResult {
- private final VerifierLookupItem[] keys;
- public VerifierLookupRequestResult(VerifierLookupItem[] _keys) {
- keys = _keys;
- }
- public VerifierLookupItem[] getKeys() {
- return keys;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/CommitmentRequestParams.java b/src/main/java/org/torusresearch/torusutils/apis/requests/CommitmentRequestParams.java
new file mode 100644
index 0000000..7bc64d1
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/CommitmentRequestParams.java
@@ -0,0 +1,22 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class CommitmentRequestParams {
+ public final String messageprefix;
+ public final String tokencommitment;
+ public final String temppubx;
+ public final String temppuby;
+ public final String timestamp;
+ public final String verifieridentifier;
+
+ public CommitmentRequestParams(@NotNull String messageprefix, @NotNull String tokencommitment, @NotNull String temppubx, @NotNull String temppuby, @Nullable String timestamp, @NotNull String verifieridentifier) {
+ this.messageprefix = messageprefix;
+ this.tokencommitment = tokencommitment;
+ this.temppubx = temppubx;
+ this.temppuby = temppuby;
+ this.timestamp = timestamp;
+ this.verifieridentifier = verifieridentifier;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/GetMetadataParams.java b/src/main/java/org/torusresearch/torusutils/apis/requests/GetMetadataParams.java
new file mode 100644
index 0000000..09ca111
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/GetMetadataParams.java
@@ -0,0 +1,13 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.NotNull;
+
+public class GetMetadataParams {
+ public final String pub_key_X;
+ public final String pub_key_Y;
+
+ public GetMetadataParams(@NotNull String pub_key_X, @NotNull String pub_key_Y) {
+ this.pub_key_X = pub_key_X;
+ this.pub_key_Y = pub_key_Y;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/GetNonceParams.java b/src/main/java/org/torusresearch/torusutils/apis/requests/GetNonceParams.java
new file mode 100644
index 0000000..b234ec0
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/GetNonceParams.java
@@ -0,0 +1,15 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.NotNull;
+
+public class GetNonceParams {
+ public final String pub_key_X;
+ public final String pub_key_Y;
+ public final GetNonceSetDataParams set_data;
+
+ public GetNonceParams(@NotNull String pub_key_X, @NotNull String pub_key_Y, @NotNull GetNonceSetDataParams set_data) {
+ this.pub_key_X = pub_key_X;
+ this.pub_key_Y = pub_key_Y;
+ this.set_data = set_data;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/GetNonceSetDataParams.java b/src/main/java/org/torusresearch/torusutils/apis/requests/GetNonceSetDataParams.java
new file mode 100644
index 0000000..dc6785e
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/GetNonceSetDataParams.java
@@ -0,0 +1,11 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.NotNull;
+
+public class GetNonceSetDataParams {
+ public final String data;
+
+ public GetNonceSetDataParams(@NotNull String data) {
+ this.data = data;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/GetOrSetKeyParams.java b/src/main/java/org/torusresearch/torusutils/apis/requests/GetOrSetKeyParams.java
new file mode 100644
index 0000000..12b1a02
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/GetOrSetKeyParams.java
@@ -0,0 +1,26 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class GetOrSetKeyParams {
+ public final Boolean distributed_metadata;
+ public final String verifier;
+ public final String verifier_id;
+ @Nullable
+ public final String extended_verifier_id;
+ public final Boolean one_key_flow;
+ public final Boolean fetch_node_index;
+ @Nullable
+ public final String client_time;
+
+ public GetOrSetKeyParams(@NotNull Boolean distributed_metadata, @NotNull String verifier, @NotNull String verifier_id, @Nullable String extended_verifier_id, @NotNull Boolean one_key_flow, @NotNull Boolean fetch_node_index, @Nullable String client_time) {
+ this.distributed_metadata = distributed_metadata;
+ this.verifier = verifier;
+ this.verifier_id = verifier_id;
+ this.extended_verifier_id = extended_verifier_id;
+ this.one_key_flow = one_key_flow;
+ this.fetch_node_index = fetch_node_index;
+ this.client_time = client_time;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/MetadataParams.java b/src/main/java/org/torusresearch/torusutils/apis/requests/MetadataParams.java
new file mode 100644
index 0000000..ac26920
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/MetadataParams.java
@@ -0,0 +1,25 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.torusutils.types.common.TorusKeyType;
+
+public class MetadataParams {
+ @Nullable
+ public final String namespace;
+ public final String pub_key_X;
+ public final String pub_key_Y;
+ @Nullable
+ public final TorusKeyType key_type;
+ public final SetData set_data;
+ public final String signature;
+
+ public MetadataParams(@NotNull String pub_key_X, @NotNull String pub_key_Y, @NotNull SetData set_data, @NotNull String signature, @Nullable String namespace, @Nullable TorusKeyType key_type) {
+ this.pub_key_X = pub_key_X;
+ this.pub_key_Y = pub_key_Y;
+ this.set_data = set_data;
+ this.signature = signature;
+ this.key_type = key_type;
+ this.namespace = namespace;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/NonceMetadataParams.java b/src/main/java/org/torusresearch/torusutils/apis/requests/NonceMetadataParams.java
new file mode 100644
index 0000000..a2e8c10
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/NonceMetadataParams.java
@@ -0,0 +1,32 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.torusutils.types.common.TorusKeyType;
+
+public class NonceMetadataParams {
+ @Nullable
+ public final String namespace;
+ public final String pub_key_X;
+ public final String pub_key_Y;
+ public final SetNonceData set_data;
+ @Nullable
+ public final TorusKeyType keyType;
+
+ public final String signature;
+ public final String encodedData;
+ @Nullable
+ public final String seed;
+
+ public NonceMetadataParams(@NotNull String pub_key_X, @NotNull String pub_key_Y, @NotNull SetNonceData set_data, @NotNull String encodedData, @NotNull String signature, @Nullable String namespace, @Nullable TorusKeyType keyType, @Nullable String seed) {
+ this.pub_key_X = pub_key_X;
+ this.pub_key_Y = pub_key_Y;
+ this.set_data = set_data;
+ this.encodedData = encodedData;
+ this.signature = signature;
+ this.namespace = namespace;
+ this.keyType = keyType;
+ this.seed = seed;
+ }
+}
+
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/SetData.java b/src/main/java/org/torusresearch/torusutils/apis/requests/SetData.java
new file mode 100644
index 0000000..fef2b76
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/SetData.java
@@ -0,0 +1,13 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.NotNull;
+
+public class SetData {
+ public final String data;
+ public final String timestamp;
+
+ public SetData(@NotNull String data, @NotNull String timestamp) {
+ this.data = data;
+ this.timestamp = timestamp;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/SetNonceData.java b/src/main/java/org/torusresearch/torusutils/apis/requests/SetNonceData.java
new file mode 100644
index 0000000..74b8722
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/SetNonceData.java
@@ -0,0 +1,23 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.Nullable;
+
+public class SetNonceData {
+ @Nullable
+ public final String data;
+ @Nullable
+ public final String operation;
+
+ public String seed = "";
+ @Nullable
+ public final String timestamp;
+
+ public SetNonceData(@Nullable String operation, @Nullable String data, @Nullable String seed, @Nullable String timestamp) {
+ this.data = data;
+ this.operation = operation;
+ if (seed != null) {
+ this.seed = seed;
+ }
+ this.timestamp = timestamp;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/ShareRequestItem.java b/src/main/java/org/torusresearch/torusutils/apis/requests/ShareRequestItem.java
new file mode 100644
index 0000000..077115b
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/ShareRequestItem.java
@@ -0,0 +1,104 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.torusutils.apis.responses.CommitmentRequestResult;
+import org.torusresearch.torusutils.types.TorusUtilsExtraParams;
+import org.torusresearch.torusutils.types.VerifyParams;
+import org.torusresearch.torusutils.types.common.TorusKeyType;
+import org.torusresearch.torusutils.types.common.ecies.EciesHexOmitCipherText;
+
+public class ShareRequestItem {
+ public final String verifieridentifier;
+ @Nullable
+ public final String verifier_id;
+ @Nullable
+ public final String extended_verifier_id;
+ public final String idtoken;
+ @Nullable
+ public final CommitmentRequestResult[] nodesignatures;
+ @Nullable
+ public final String pub_key_x;
+ @Nullable
+ public final String pub_key_y;
+ @Nullable
+ public final String signing_pub_key_x;
+ @Nullable
+ public final String signing_pub_key_y;
+ @Nullable
+ public final String encrypted_share;
+ @Nullable
+ public final EciesHexOmitCipherText encrypted_share_metadata;
+ @Nullable
+ public final Integer node_index;
+ @Nullable
+ public final TorusKeyType key_type;
+ @Nullable
+ public final String nonce_data;
+ @Nullable
+ public final String nonce_signature;
+ @Nullable
+ public final String[] sub_verifier_ids;
+ public Integer session_token_exp_second = 86400;
+ @Nullable
+ public final VerifyParams[] verify_params;
+ @Nullable
+ public final String sss_endpoint;
+ @Nullable
+ public final String nonce;
+ @Nullable
+ public final String message;
+ @Nullable
+ public final String signature;
+ @Nullable
+ public final String clientDataJson;
+ @Nullable
+ public final String authenticatorData;
+ @Nullable
+ public final String publicKey;
+ @Nullable
+ public final String challenge;
+ @Nullable
+ public final String rpOrigin;
+ @Nullable
+ public final String rpId;
+ @Nullable
+ public final Integer timestamp;
+
+ public ShareRequestItem(@NotNull String verifieridentifier, @Nullable String verifier_id, @Nullable String extended_verifier_id, @NotNull String idtoken, @NotNull TorusUtilsExtraParams extraParams, @Nullable CommitmentRequestResult[] nodesignatures, @Nullable String pub_key_x,
+ @Nullable String pub_key_y, @Nullable String signing_pub_key_x, @Nullable String signing_pub_key_y, @Nullable String encrypted_share, @Nullable EciesHexOmitCipherText encrypted_share_metadata, @Nullable Integer node_index,
+ @Nullable TorusKeyType key_type, @Nullable String nonce_data, @Nullable String nonce_signature, @Nullable String[] sub_verifier_ids, @Nullable VerifyParams[] verifyParams, @Nullable String sss_endpoint ) {
+ this.verifieridentifier = verifieridentifier;
+ this.verifier_id = verifier_id;
+ this.extended_verifier_id = extended_verifier_id;
+ this.idtoken = idtoken;
+ this.nodesignatures = nodesignatures;
+ this.pub_key_x = pub_key_x;
+ this.pub_key_y = pub_key_y;
+ this.signing_pub_key_x = signing_pub_key_x;
+ this.signing_pub_key_y = signing_pub_key_y;
+ this.encrypted_share = encrypted_share;
+ this.encrypted_share_metadata = encrypted_share_metadata;
+ this.node_index = node_index;
+ this.key_type = key_type;
+ this.nonce_data = nonce_data;
+ this.nonce_signature = nonce_signature;
+ this.sub_verifier_ids = sub_verifier_ids;
+ if (extraParams.session_token_exp_second == null) {
+ this.session_token_exp_second = extraParams.session_token_exp_second;
+ }
+ this.verify_params = verifyParams;
+ this.sss_endpoint = sss_endpoint;
+
+ this.nonce = extraParams.nonce;
+ this.message = extraParams.message;
+ this.signature = extraParams.signature;
+ this.clientDataJson = extraParams.clientDataJson;
+ this.authenticatorData = extraParams.authenticatorData;
+ this.publicKey = extraParams.publicKey;
+ this.challenge = extraParams.challenge;
+ this.rpOrigin = extraParams.rpOrigin;
+ this.rpId = extraParams.rpId;
+ this.timestamp = extraParams.timestamp;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/requests/ShareRequestParams.java b/src/main/java/org/torusresearch/torusutils/apis/requests/ShareRequestParams.java
new file mode 100644
index 0000000..6c0ebc8
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/requests/ShareRequestParams.java
@@ -0,0 +1,21 @@
+package org.torusresearch.torusutils.apis.requests;
+
+import org.jetbrains.annotations.NotNull;
+
+public class ShareRequestParams {
+ @SuppressWarnings("unused")
+ public final String encrypted = "yes";
+ @SuppressWarnings("unused")
+ public final boolean one_key_flow = true;
+ @SuppressWarnings("unused")
+ public final boolean use_temp = true;
+ @SuppressWarnings("unused")
+ public final boolean distributed_metadata = true;
+ public final String client_time;
+ public final ShareRequestItem[] item;
+
+ public ShareRequestParams(@NotNull ShareRequestItem[] item, @NotNull String client_time) {
+ this.item = item;
+ this.client_time = client_time;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/responses/CommitmentRequestResult.java b/src/main/java/org/torusresearch/torusutils/apis/responses/CommitmentRequestResult.java
new file mode 100644
index 0000000..81c5815
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/responses/CommitmentRequestResult.java
@@ -0,0 +1,19 @@
+package org.torusresearch.torusutils.apis.responses;
+
+import org.jetbrains.annotations.NotNull;
+
+public class CommitmentRequestResult {
+ public final String signature;
+ public final String data;
+ public final String nodepubx;
+ public final String nodepuby;
+ public final String nodeindex;
+
+ public CommitmentRequestResult(@NotNull String data, @NotNull String nodepubx, @NotNull String nodepuby, @NotNull String signature, @NotNull String nodeindex) {
+ this.data = data;
+ this.nodeindex = nodeindex;
+ this.signature = signature;
+ this.nodepubx = nodepubx;
+ this.nodepuby = nodepuby;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/responses/GetMetadataResponse.java b/src/main/java/org/torusresearch/torusutils/apis/responses/GetMetadataResponse.java
new file mode 100644
index 0000000..fc29455
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/responses/GetMetadataResponse.java
@@ -0,0 +1,11 @@
+package org.torusresearch.torusutils.apis.responses;
+
+import org.jetbrains.annotations.NotNull;
+
+public class GetMetadataResponse {
+ public final String message;
+
+ public GetMetadataResponse(@NotNull String message) {
+ this.message = message;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/responses/GetOrSetNonceResult.java b/src/main/java/org/torusresearch/torusutils/apis/responses/GetOrSetNonceResult.java
new file mode 100644
index 0000000..51866bb
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/responses/GetOrSetNonceResult.java
@@ -0,0 +1,27 @@
+package org.torusresearch.torusutils.apis.responses;
+
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
+import org.torusresearch.torusutils.types.common.PubNonce;
+
+public class GetOrSetNonceResult {
+ @Nullable
+ public final TypeOfUser typeOfUser;
+ @Nullable
+ public String nonce; // This is not final as in one case the nonce needs to be removed.
+
+ @Nullable
+ public final PubNonce pubNonce;
+ @Nullable
+ public final String ipfs;
+ @Nullable
+ public final Boolean upgraded;
+
+ public GetOrSetNonceResult(@Nullable TypeOfUser typeOfUser, @Nullable String nonce, @Nullable PubNonce pubNonce, @Nullable String ipfs, @Nullable Boolean upgraded) {
+ this.typeOfUser = typeOfUser;
+ this.nonce = nonce;
+ this.pubNonce = pubNonce;
+ this.ipfs = ipfs;
+ this.upgraded = upgraded;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/responses/KeyAssignment.java b/src/main/java/org/torusresearch/torusutils/apis/responses/KeyAssignment.java
new file mode 100644
index 0000000..5857992
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/responses/KeyAssignment.java
@@ -0,0 +1,28 @@
+package org.torusresearch.torusutils.apis.responses;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.torusutils.apis.PubKey;
+import org.torusresearch.torusutils.types.common.ecies.EciesHexOmitCipherText;
+
+public class KeyAssignment {
+ public final String index;
+ public final PubKey public_key;
+ public final Integer threshold;
+ public final Integer node_index;
+ public final String share; // Note: This is in base64, must be decoded before decrypting
+ public final EciesHexOmitCipherText share_metadata;
+ @Nullable
+ public final GetOrSetNonceResult nonce_data;
+
+ public KeyAssignment(@NotNull String index, @NotNull PubKey public_key, @NotNull Integer threshold, @NotNull Integer node_index, @NotNull String share, @NotNull EciesHexOmitCipherText share_metadata, @Nullable GetOrSetNonceResult nonce_data) {
+ this.index = index;
+ this.public_key = public_key;
+ this.threshold = threshold;
+ this.node_index = node_index;
+ this.share = share;
+ this.share_metadata = share_metadata;
+ this.nonce_data = nonce_data;
+ }
+}
+
diff --git a/src/main/java/org/torusresearch/torusutils/apis/responses/ShareRequestResult.java b/src/main/java/org/torusresearch/torusutils/apis/responses/ShareRequestResult.java
new file mode 100644
index 0000000..8085825
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/responses/ShareRequestResult.java
@@ -0,0 +1,35 @@
+package org.torusresearch.torusutils.apis.responses;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.torusutils.types.common.ecies.EciesHexOmitCipherText;
+
+public class ShareRequestResult {
+ public final KeyAssignment[] keys;
+ public final String[] session_tokens;
+ public final EciesHexOmitCipherText[] session_token_metadata;
+ public final String[] session_token_sigs;
+ public final EciesHexOmitCipherText[] session_token_sig_metadata;
+ public final String node_pubx;
+ public final String node_puby;
+ public final Boolean is_new_key;
+ public String server_time_offset; // this is not final, it is modified by code
+
+ public ShareRequestResult(@NotNull KeyAssignment[] keys, @NotNull String[] session_tokens, @NotNull EciesHexOmitCipherText[] session_token_metadata,
+ @NotNull String[] session_token_sigs, @NotNull EciesHexOmitCipherText[] session_token_sig_metadata, @NotNull String node_pubx,
+ @NotNull String node_puby, @NotNull Boolean is_new_key, @Nullable String server_time_offset) {
+ this.keys = keys;
+ this.session_tokens = session_tokens;
+ this.session_token_metadata = session_token_metadata;
+ this.session_token_sigs = session_token_sigs;
+ this.session_token_sig_metadata = session_token_sig_metadata;
+ this.node_pubx = node_pubx;
+ this.node_puby = node_puby;
+ this.is_new_key = is_new_key;
+ if (server_time_offset == null) {
+ this.server_time_offset = "0";
+ } else{
+ this.server_time_offset = server_time_offset;
+ }
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/LegacyVerifierKey.java b/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/LegacyVerifierKey.java
new file mode 100644
index 0000000..f20ca13
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/LegacyVerifierKey.java
@@ -0,0 +1,16 @@
+package org.torusresearch.torusutils.apis.responses.VerifierLookupResponse;
+
+import org.jetbrains.annotations.NotNull;
+
+public class LegacyVerifierKey {
+ public final String pub_key_X;
+ public final String pub_key_Y;
+ public final String address;
+
+ public LegacyVerifierKey(@NotNull String pub_key_X, @NotNull String pub_key_Y, @NotNull String address) {
+ this.pub_key_X = pub_key_X;
+ this.pub_key_Y = pub_key_Y;
+ this.address = address;
+
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/LegacyVerifierLookupResponse.java b/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/LegacyVerifierLookupResponse.java
new file mode 100644
index 0000000..38eaecc
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/LegacyVerifierLookupResponse.java
@@ -0,0 +1,15 @@
+package org.torusresearch.torusutils.apis.responses.VerifierLookupResponse;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class LegacyVerifierLookupResponse {
+ public final LegacyVerifierKey[] keys;
+ @Nullable
+ public final String server_time_offset;
+
+ public LegacyVerifierLookupResponse(@NotNull LegacyVerifierKey[] keys, @Nullable String server_time_offset) {
+ this.server_time_offset = server_time_offset;
+ this.keys = keys;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/VerifierKey.java b/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/VerifierKey.java
new file mode 100644
index 0000000..6635d18
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/VerifierKey.java
@@ -0,0 +1,23 @@
+package org.torusresearch.torusutils.apis.responses.VerifierLookupResponse;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.torusutils.apis.responses.GetOrSetNonceResult;
+
+public class VerifierKey {
+ public final String pub_key_X;
+ public final String pub_key_Y;
+ public final String address;
+ @Nullable
+ public final GetOrSetNonceResult nonce_data;
+ @Nullable
+ public final String created_at;
+
+ public VerifierKey(@NotNull String pub_key_X, @NotNull String pub_key_Y, @NotNull String address, @Nullable GetOrSetNonceResult nonce_data, @Nullable String created_at) {
+ this.pub_key_X = pub_key_X;
+ this.pub_key_Y = pub_key_Y;
+ this.address = address;
+ this.nonce_data = nonce_data;
+ this.created_at = created_at;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/VerifierLookupResponse.java b/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/VerifierLookupResponse.java
new file mode 100644
index 0000000..4741234
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/apis/responses/VerifierLookupResponse/VerifierLookupResponse.java
@@ -0,0 +1,21 @@
+package org.torusresearch.torusutils.apis.responses.VerifierLookupResponse;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class VerifierLookupResponse {
+ public final VerifierKey[] keys;
+ @Nullable
+ public final Boolean is_new_key;
+
+ public final String node_index;
+ @Nullable
+ public final String server_time_offset;
+
+ public VerifierLookupResponse(@NotNull VerifierKey[] keys, @Nullable Boolean is_new_key, @NotNull String node_index, @Nullable String server_time_offset) {
+ this.node_index = node_index;
+ this.keys = keys;
+ this.is_new_key = is_new_key;
+ this.server_time_offset = server_time_offset;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/AES256CBC.java b/src/main/java/org/torusresearch/torusutils/helpers/AES256CBC.java
deleted file mode 100644
index 2c762ed..0000000
--- a/src/main/java/org/torusresearch/torusutils/helpers/AES256CBC.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.torusresearch.torusutils.helpers;
-
-import org.torusresearch.torusutils.types.TorusException;
-
-import javax.crypto.Cipher;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import java.math.BigInteger;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.ECFieldFp;
-import java.security.spec.EllipticCurve;
-import java.util.Arrays;
-
-public class AES256CBC {
- private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
- private final byte[] AES_ENCRYPTION_KEY;
- private final byte[] ENCRYPTION_IV;
-
- public AES256CBC(String privateKeyHex, String ephemPublicKeyHex, String encryptionIvHex) throws NoSuchAlgorithmException {
- byte[] hash = SHA512.digest(toByteArray(ecdh(privateKeyHex, ephemPublicKeyHex)));
- byte[] encKeyBytes = Arrays.copyOfRange(hash, 0, 32);
- AES_ENCRYPTION_KEY = encKeyBytes;
- ENCRYPTION_IV = toByteArray(encryptionIvHex);
- }
-
- /**
- * Utility method to convert a BigInteger to a byte array in unsigned
- * format as needed in the handshake messages. BigInteger uses
- * 2's complement format, i.e. it prepends an extra zero if the MSB
- * is set. We remove that.
- */
- public static byte[] toByteArray(BigInteger bi) {
- byte[] b = bi.toByteArray();
- if (b.length > 1 && b[0] == 0) {
- int n = b.length - 1;
- byte[] newArray = new byte[n];
- System.arraycopy(b, 1, newArray, 0, n);
- b = newArray;
- }
- return b;
- }
-
- public static byte[] toByteArray(String s) {
- int len = s.length();
- byte[] data = new byte[len / 2];
- for (int i = 0; i < len; i += 2) {
- data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
- + Character.digit(s.charAt(i+1), 16));
- }
- return data;
- }
-
- public String encrypt(byte[] src) throws TorusException {
- Cipher cipher;
- try {
- cipher = Cipher.getInstance(TRANSFORMATION);
- cipher.init(Cipher.ENCRYPT_MODE, makeKey(), makeIv());
- return Base64.encodeBytes(cipher.doFinal(src));
- } catch (Exception e) {
- e.printStackTrace();
- throw new TorusException("Torus Internal Error", e);
- }
- }
-
- public byte[] decrypt(String src) throws TorusException {
- Cipher cipher;
- try {
- cipher = Cipher.getInstance(TRANSFORMATION);
- cipher.init(Cipher.DECRYPT_MODE, makeKey(), makeIv());
- return cipher.doFinal(Base64.decode(src));
- } catch (Exception e) {
- e.printStackTrace();
- throw new TorusException("Torus Internal Error", e);
- }
-
- }
-
- private BigInteger ecdh(String privateKeyHex, String ephemPublicKeyHex) {
- String affineX = ephemPublicKeyHex.substring(2, 66);
- String affineY = ephemPublicKeyHex.substring(66);
-
- ECPointArithmetic ecPoint = new ECPointArithmetic(new EllipticCurve(
- new ECFieldFp(new BigInteger("115792089237316195423570985008687907853269984665640564039457584007908834671663")),
- new BigInteger("0"),
- new BigInteger("7")), new BigInteger(affineX, 16), new BigInteger(affineY, 16), null);
- return ecPoint.multiply(new BigInteger(privateKeyHex, 16)).getX();
- }
-
- private Key makeKey() {
- return new SecretKeySpec(AES_ENCRYPTION_KEY, "AES");
- }
-
- private AlgorithmParameterSpec makeIv() {
- return new IvParameterSpec(ENCRYPTION_IV);
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/Base64.java b/src/main/java/org/torusresearch/torusutils/helpers/Base64.java
deleted file mode 100644
index 4040918..0000000
--- a/src/main/java/org/torusresearch/torusutils/helpers/Base64.java
+++ /dev/null
@@ -1,1953 +0,0 @@
-package org.torusresearch.torusutils.helpers;
-
-import java.nio.charset.StandardCharsets;
-
-public class Base64 {
-
- /* ******** P U B L I C F I E L D S ******** */
-
-
- /**
- * No options specified. Value is zero.
- */
- public final static int NO_OPTIONS = 0;
-
- /**
- * Specify encoding in first bit. Value is one.
- */
- public final static int ENCODE = 1;
-
-
- /**
- * Specify decoding in first bit. Value is zero.
- */
- public final static int DECODE = 0;
-
-
- /**
- * Specify that data should be gzip-compressed in second bit. Value is two.
- */
- public final static int GZIP = 2;
-
- /**
- * Specify that gzipped data should not be automatically gunzipped.
- */
- public final static int DONT_GUNZIP = 4;
-
-
- /**
- * Do break lines when encoding. Value is 8.
- */
- public final static int DO_BREAK_LINES = 8;
-
- /**
- * Encode using Base64-like encoding that is URL- and Filename-safe as described
- * in Section 4 of RFC3548:
- * http://www.faqs.org/rfcs/rfc3548.html.
- * It is important to note that data encoded this way is not officially valid Base64,
- * or at the very least should not be called Base64 without also specifying that is
- * was encoded using the URL- and Filename-safe dialect.
- */
- public final static int URL_SAFE = 16;
-
-
- /**
- * Encode using the special "ordered" dialect of Base64 described here:
- * http://www.faqs.org/qa/rfcc-1940.html.
- */
- public final static int ORDERED = 32;
-
-
- /* ******** P R I V A T E F I E L D S ******** */
-
-
- /**
- * Maximum line length (76) of Base64 output.
- */
- private final static int MAX_LINE_LENGTH = 76;
-
-
- /**
- * The equals sign (=) as a byte.
- */
- private final static byte EQUALS_SIGN = (byte) '=';
-
-
- /**
- * The new line character (\n) as a byte.
- */
- private final static byte NEW_LINE = (byte) '\n';
-
-
- /**
- * Preferred encoding.
- */
- private final static String PREFERRED_ENCODING = "US-ASCII";
-
-
- private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding
- private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding
-
-
- /* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */
-
- /**
- * The 64 valid Base64 values.
- */
- /* Host platform me be something funny like EBCDIC, so we hardcode these values. */
- private final static byte[] _STANDARD_ALPHABET = {
- (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
- (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
- (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
- (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
- (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g',
- (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
- (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
- (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
- (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5',
- (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/'
- };
-
-
- /**
- * Translates a Base64 value to either its 6-bit reconstruction value
- * or a negative number indicating some other meaning.
- **/
- private final static byte[] _STANDARD_DECODABET = {
- -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
- 62, // Plus sign at decimal 43
- -9, -9, -9, // Decimal 44 - 46
- 63, // Slash at decimal 47
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
- -9, -9, -9, -9, -9, -9, // Decimal 91 - 96
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
- -9, -9, -9, -9, -9 // Decimal 123 - 127
- , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255
- };
-
-
- /* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */
-
- /**
- * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548:
- * http://www.faqs.org/rfcs/rfc3548.html.
- * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash."
- */
- private final static byte[] _URL_SAFE_ALPHABET = {
- (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
- (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
- (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
- (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
- (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g',
- (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
- (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
- (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
- (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5',
- (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '-', (byte) '_'
- };
-
- /**
- * Used in decoding URL- and Filename-safe dialects of Base64.
- */
- private final static byte[] _URL_SAFE_DECODABET = {
- -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
- -9, // Plus sign at decimal 43
- -9, // Decimal 44
- 62, // Minus sign at decimal 45
- -9, // Decimal 46
- -9, // Slash at decimal 47
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
- -9, -9, -9, -9, // Decimal 91 - 94
- 63, // Underscore at decimal 95
- -9, // Decimal 96
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
- -9, -9, -9, -9, -9 // Decimal 123 - 127
- , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255
- };
-
-
-
- /* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */
-
- /**
- * I don't get the point of this technique, but someone requested it,
- * and it is described here:
- * http://www.faqs.org/qa/rfcc-1940.html.
- */
- private final static byte[] _ORDERED_ALPHABET = {
- (byte) '-',
- (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4',
- (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9',
- (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
- (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
- (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
- (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
- (byte) '_',
- (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g',
- (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
- (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
- (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z'
- };
-
- /**
- * Used in decoding the "ordered" dialect of Base64.
- */
- private final static byte[] _ORDERED_DECODABET = {
- -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
- -9, // Plus sign at decimal 43
- -9, // Decimal 44
- 0, // Minus sign at decimal 45
- -9, // Decimal 46
- -9, // Slash at decimal 47
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, // Letters 'A' through 'M'
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, // Letters 'N' through 'Z'
- -9, -9, -9, -9, // Decimal 91 - 94
- 37, // Underscore at decimal 95
- -9, // Decimal 96
- 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, // Letters 'a' through 'm'
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // Letters 'n' through 'z'
- -9, -9, -9, -9, -9 // Decimal 123 - 127
- , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255
- };
-
-
- /* ******** D E T E R M I N E W H I C H A L H A B E T ******** */
-
-
- /**
- * Defeats instantiation.
- */
- private Base64() {
- }
-
- /**
- * Returns one of the _SOMETHING_ALPHABET byte arrays depending on
- * the options specified.
- * It's possible, though silly, to specify ORDERED and URLSAFE
- * in which case one of them will be picked, though there is
- * no guarantee as to which one will be picked.
- */
- private static byte[] getAlphabet(int options) {
- if ((options & URL_SAFE) == URL_SAFE) {
- return _URL_SAFE_ALPHABET;
- } else if ((options & ORDERED) == ORDERED) {
- return _ORDERED_ALPHABET;
- } else {
- return _STANDARD_ALPHABET;
- }
- } // end getAlphabet
-
- /**
- * Returns one of the _SOMETHING_DECODABET byte arrays depending on
- * the options specified.
- * It's possible, though silly, to specify ORDERED and URL_SAFE
- * in which case one of them will be picked, though there is
- * no guarantee as to which one will be picked.
- */
- private static byte[] getDecodabet(int options) {
- if ((options & URL_SAFE) == URL_SAFE) {
- return _URL_SAFE_DECODABET;
- } else if ((options & ORDERED) == ORDERED) {
- return _ORDERED_DECODABET;
- } else {
- return _STANDARD_DECODABET;
- }
- } // end getAlphabet
-
-
-
-
- /* ******** E N C O D I N G M E T H O D S ******** */
-
- /**
- * Encodes up to the first three bytes of array threeBytes
- * and returns a four-byte array in Base64 notation.
- * The actual number of significant bytes in your array is
- * given by numSigBytes.
- * The array threeBytes needs only be as big as
- * numSigBytes.
- * Code can reuse a byte array by passing a four-byte array as b4.
- *
- * @param b4 A reusable byte array to reduce array instantiation
- * @param threeBytes the array to convert
- * @param numSigBytes the number of significant bytes in your array
- * @return four byte array in Base64 notation.
- * @since 1.5.1
- */
- private static byte[] encode3to4(byte[] b4, byte[] threeBytes, int numSigBytes, int options) {
- encode3to4(threeBytes, 0, numSigBytes, b4, 0, options);
- return b4;
- } // end encode3to4
-
-
- /**
- * Encodes up to three bytes of the array source
- * and writes the resulting four Base64 bytes to destination.
- * The source and destination arrays can be manipulated
- * anywhere along their length by specifying
- * srcOffset and destOffset.
- * This method does not check to make sure your arrays
- * are large enough to accomodate srcOffset + 3 for
- * the source array or destOffset + 4 for
- * the destination array.
- * The actual number of significant bytes in your array is
- * given by numSigBytes.
- * This is the lowest level of the encoding methods with
- * all possible parameters.
- *
- * @param source the array to convert
- * @param srcOffset the index where conversion begins
- * @param numSigBytes the number of significant bytes in your array
- * @param destination the array to hold the conversion
- * @param destOffset the index where output will be put
- * @return the destination array
- * @since 1.3
- */
- private static byte[] encode3to4(
- byte[] source, int srcOffset, int numSigBytes,
- byte[] destination, int destOffset, int options) {
-
- byte[] ALPHABET = getAlphabet(options);
-
- // 1 2 3
- // 01234567890123456789012345678901 Bit position
- // --------000000001111111122222222 Array position from threeBytes
- // --------| || || || | Six bit groups to index ALPHABET
- // >>18 >>12 >> 6 >> 0 Right shift necessary
- // 0x3f 0x3f 0x3f Additional AND
-
- // Create buffer with zero-padding if there are only one or two
- // significant bytes passed in the array.
- // We have to shift left 24 in order to flush out the 1's that appear
- // when Java treats a value as negative that is cast from a byte to an int.
- int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
- | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
- | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
-
- switch (numSigBytes) {
- case 3:
- destination[destOffset] = ALPHABET[(inBuff >>> 18)];
- destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
- destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f];
- return destination;
-
- case 2:
- destination[destOffset] = ALPHABET[(inBuff >>> 18)];
- destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
- destination[destOffset + 3] = EQUALS_SIGN;
- return destination;
-
- case 1:
- destination[destOffset] = ALPHABET[(inBuff >>> 18)];
- destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = EQUALS_SIGN;
- destination[destOffset + 3] = EQUALS_SIGN;
- return destination;
-
- default:
- return destination;
- } // end switch
- } // end encode3to4
-
-
- /**
- * Performs Base64 encoding on the raw ByteBuffer,
- * writing it to the encoded ByteBuffer.
- * This is an experimental feature. Currently it does not
- * pass along any options (such as {@link #DO_BREAK_LINES}
- * or {@link #GZIP}.
- *
- * @param raw input buffer
- * @param encoded output buffer
- * @since 2.3
- */
- public static void encode(java.nio.ByteBuffer raw, java.nio.ByteBuffer encoded) {
- byte[] raw3 = new byte[3];
- byte[] enc4 = new byte[4];
-
- while (raw.hasRemaining()) {
- int rem = Math.min(3, raw.remaining());
- raw.get(raw3, 0, rem);
- Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS);
- encoded.put(enc4);
- } // end input remaining
- }
-
-
- /**
- * Performs Base64 encoding on the raw ByteBuffer,
- * writing it to the encoded CharBuffer.
- * This is an experimental feature. Currently it does not
- * pass along any options (such as {@link #DO_BREAK_LINES}
- * or {@link #GZIP}.
- *
- * @param raw input buffer
- * @param encoded output buffer
- * @since 2.3
- */
- public static void encode(java.nio.ByteBuffer raw, java.nio.CharBuffer encoded) {
- byte[] raw3 = new byte[3];
- byte[] enc4 = new byte[4];
-
- while (raw.hasRemaining()) {
- int rem = Math.min(3, raw.remaining());
- raw.get(raw3, 0, rem);
- Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS);
- for (int i = 0; i < 4; i++) {
- encoded.put((char) (enc4[i] & 0xFF));
- }
- } // end input remaining
- }
-
-
- /**
- * Serializes an object and returns the Base64-encoded
- * version of that serialized object.
- *
- * As of v 2.3, if the object
- * cannot be serialized or there is another error,
- * the method will throw an java.io.IOException. This is new to v2.3!
- * In earlier versions, it just returned a null value, but
- * in retrospect that's a pretty poor way to handle it.
- *
- * The object is not GZip-compressed before being encoded.
- *
- * @param serializableObject The object to encode
- * @return The Base64-encoded object
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if serializedObject is null
- * @since 1.4
- */
- public static String encodeObject(java.io.Serializable serializableObject)
- throws java.io.IOException {
- return encodeObject(serializableObject, NO_OPTIONS);
- } // end encodeObject
-
-
- /**
- * Serializes an object and returns the Base64-encoded
- * version of that serialized object.
- *
- *
As of v 2.3, if the object
- * cannot be serialized or there is another error,
- * the method will throw an java.io.IOException. This is new to v2.3!
- * In earlier versions, it just returned a null value, but
- * in retrospect that's a pretty poor way to handle it.
- *
- * The object is not GZip-compressed before being encoded.
- *
- * Example options:
- * GZIP: gzip-compresses object before encoding it.
- * DO_BREAK_LINES: break lines at 76 characters
- *
- *
- * Example: encodeObject( myObj, Base64.GZIP ) or
- *
- * Example: encodeObject( myObj, Base64.GZIP | Base64.DO_BREAK_LINES )
- *
- * @param serializableObject The object to encode
- * @param options Specified options
- * @return The Base64-encoded object
- * @throws java.io.IOException if there is an error
- * @see Base64#GZIP
- * @see Base64#DO_BREAK_LINES
- * @since 2.0
- */
- public static String encodeObject(java.io.Serializable serializableObject, int options)
- throws java.io.IOException {
-
- if (serializableObject == null) {
- throw new NullPointerException("Cannot serialize a null object.");
- } // end if: null
-
- // Streams
- java.io.ByteArrayOutputStream baos = null;
- java.io.OutputStream b64os = null;
- java.util.zip.GZIPOutputStream gzos = null;
- java.io.ObjectOutputStream oos = null;
-
-
- try {
- // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
- baos = new java.io.ByteArrayOutputStream();
- b64os = new Base64.OutputStream(baos, ENCODE | options);
- if ((options & GZIP) != 0) {
- // Gzip
- gzos = new java.util.zip.GZIPOutputStream(b64os);
- oos = new java.io.ObjectOutputStream(gzos);
- } else {
- // Not gzipped
- oos = new java.io.ObjectOutputStream(b64os);
- }
- oos.writeObject(serializableObject);
- } // end try
- catch (java.io.IOException e) {
- // Catch it and then throw it immediately so that
- // the finally{} block is called for cleanup.
- throw e;
- } // end catch
- finally {
- try {
- oos.close();
- } catch (Exception ignored) {
- }
- try {
- gzos.close();
- } catch (Exception e) {
- }
- try {
- b64os.close();
- } catch (Exception e) {
- }
- try {
- baos.close();
- } catch (Exception e) {
- }
- } // end finally
-
- // Return value according to relevant encoding.
- try {
- return new String(baos.toByteArray(), PREFERRED_ENCODING);
- } // end try
- catch (java.io.UnsupportedEncodingException uue) {
- // Fall back to some Java default
- return new String(baos.toByteArray());
- } // end catch
-
- } // end encode
-
-
- /**
- * Encodes a byte array into Base64 notation.
- * Does not GZip-compress data.
- *
- * @param source The data to convert
- * @return The data in Base64-encoded form
- * @throws NullPointerException if source array is null
- * @since 1.4
- */
- public static String encodeBytes(byte[] source) {
- // Since we're not going to have the GZIP encoding turned on,
- // we're not going to have an java.io.IOException thrown, so
- // we should not force the user to have to catch it.
- String encoded = null;
- try {
- encoded = encodeBytes(source, 0, source.length, NO_OPTIONS);
- } catch (java.io.IOException ex) {
- assert false : ex.getMessage();
- } // end catch
- assert encoded != null;
- return encoded;
- } // end encodeBytes
-
-
- /**
- * Encodes a byte array into Base64 notation.
- *
- * Example options:
- * GZIP: gzip-compresses object before encoding it.
- * DO_BREAK_LINES: break lines at 76 characters
- * Note: Technically, this makes your encoding non-compliant.
- *
- *
- * Example: encodeBytes( myData, Base64.GZIP ) or
- *
- * Example: encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )
- *
- *
- *
As of v 2.3, if there is an error with the GZIP stream,
- * the method will throw an java.io.IOException. This is new to v2.3!
- * In earlier versions, it just returned a null value, but
- * in retrospect that's a pretty poor way to handle it.
- *
- * @param source The data to convert
- * @param options Specified options
- * @return The Base64-encoded data as a String
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if source array is null
- * @see Base64#GZIP
- * @see Base64#DO_BREAK_LINES
- * @since 2.0
- */
- public static String encodeBytes(byte[] source, int options) throws java.io.IOException {
- return encodeBytes(source, 0, source.length, options);
- } // end encodeBytes
-
-
- /**
- * Encodes a byte array into Base64 notation.
- * Does not GZip-compress data.
- *
- * As of v 2.3, if there is an error,
- * the method will throw an java.io.IOException. This is new to v2.3!
- * In earlier versions, it just returned a null value, but
- * in retrospect that's a pretty poor way to handle it.
- *
- * @param source The data to convert
- * @param off Offset in array where conversion should begin
- * @param len Length of data to convert
- * @return The Base64-encoded data as a String
- * @throws NullPointerException if source array is null
- * @throws IllegalArgumentException if source array, offset, or length are invalid
- * @since 1.4
- */
- public static String encodeBytes(byte[] source, int off, int len) {
- // Since we're not going to have the GZIP encoding turned on,
- // we're not going to have an java.io.IOException thrown, so
- // we should not force the user to have to catch it.
- String encoded = null;
- try {
- encoded = encodeBytes(source, off, len, NO_OPTIONS);
- } catch (java.io.IOException ex) {
- assert false : ex.getMessage();
- } // end catch
- assert encoded != null;
- return encoded;
- } // end encodeBytes
-
-
- /**
- * Encodes a byte array into Base64 notation.
- *
- * Example options:
- * GZIP: gzip-compresses object before encoding it.
- * DO_BREAK_LINES: break lines at 76 characters
- * Note: Technically, this makes your encoding non-compliant.
- *
- *
- * Example: encodeBytes( myData, Base64.GZIP ) or
- *
- * Example: encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )
- *
- *
- *
As of v 2.3, if there is an error with the GZIP stream,
- * the method will throw an java.io.IOException. This is new to v2.3!
- * In earlier versions, it just returned a null value, but
- * in retrospect that's a pretty poor way to handle it.
- *
- * @param source The data to convert
- * @param off Offset in array where conversion should begin
- * @param len Length of data to convert
- * @param options Specified options
- * @return The Base64-encoded data as a String
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if source array is null
- * @throws IllegalArgumentException if source array, offset, or length are invalid
- * @see Base64#GZIP
- * @see Base64#DO_BREAK_LINES
- * @since 2.0
- */
- public static String encodeBytes(byte[] source, int off, int len, int options) throws java.io.IOException {
- byte[] encoded = encodeBytesToBytes(source, off, len, options);
-
- // Return value according to relevant encoding.
- try {
- return new String(encoded, PREFERRED_ENCODING);
- } // end try
- catch (java.io.UnsupportedEncodingException uue) {
- return new String(encoded);
- } // end catch
-
- } // end encodeBytes
-
-
- /**
- * Similar to {@link #encodeBytes(byte[])} but returns
- * a byte array instead of instantiating a String. This is more efficient
- * if you're working with I/O streams and have large data sets to encode.
- *
- * @param source The data to convert
- * @return The Base64-encoded data as a byte[] (of ASCII characters)
- * @throws NullPointerException if source array is null
- * @since 2.3.1
- */
- public static byte[] encodeBytesToBytes(byte[] source) {
- byte[] encoded = null;
- try {
- encoded = encodeBytesToBytes(source, 0, source.length, Base64.NO_OPTIONS);
- } catch (java.io.IOException ex) {
- assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
- }
- return encoded;
- }
-
-
- /**
- * Similar to {@link #encodeBytes(byte[], int, int, int)} but returns
- * a byte array instead of instantiating a String. This is more efficient
- * if you're working with I/O streams and have large data sets to encode.
- *
- * @param source The data to convert
- * @param off Offset in array where conversion should begin
- * @param len Length of data to convert
- * @param options Specified options
- * @return The Base64-encoded data as a String
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if source array is null
- * @throws IllegalArgumentException if source array, offset, or length are invalid
- * @see Base64#GZIP
- * @see Base64#DO_BREAK_LINES
- * @since 2.3.1
- */
- public static byte[] encodeBytesToBytes(byte[] source, int off, int len, int options) throws java.io.IOException {
-
- if (source == null) {
- throw new NullPointerException("Cannot serialize a null array.");
- } // end if: null
-
- if (off < 0) {
- throw new IllegalArgumentException("Cannot have negative offset: " + off);
- } // end if: off < 0
-
- if (len < 0) {
- throw new IllegalArgumentException("Cannot have length offset: " + len);
- } // end if: len < 0
-
- if (off + len > source.length) {
- throw new IllegalArgumentException(
- String.format("Cannot have offset of %d and length of %d with array of length %d", off, len, source.length));
- } // end if: off < 0
-
-
- // Compress?
- if ((options & GZIP) != 0) {
- java.io.ByteArrayOutputStream baos = null;
- java.util.zip.GZIPOutputStream gzos = null;
- Base64.OutputStream b64os = null;
-
- try {
- // GZip -> Base64 -> ByteArray
- baos = new java.io.ByteArrayOutputStream();
- b64os = new Base64.OutputStream(baos, ENCODE | options);
- gzos = new java.util.zip.GZIPOutputStream(b64os);
-
- gzos.write(source, off, len);
- gzos.close();
- } // end try
- catch (java.io.IOException e) {
- // Catch it and then throw it immediately so that
- // the finally{} block is called for cleanup.
- throw e;
- } // end catch
- finally {
- try {
- gzos.close();
- } catch (Exception e) {
- }
- try {
- b64os.close();
- } catch (Exception e) {
- }
- try {
- baos.close();
- } catch (Exception e) {
- }
- } // end finally
-
- return baos.toByteArray();
- } // end if: compress
-
- // Else, don't compress. Better not to use streams at all then.
- else {
- boolean breakLines = (options & DO_BREAK_LINES) != 0;
-
- //int len43 = len * 4 / 3;
- //byte[] outBuff = new byte[ ( len43 ) // Main 4:3
- // + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding
- // + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines
- // Try to determine more precisely how big the array needs to be.
- // If we get it right, we don't have to do an array copy, and
- // we save a bunch of memory.
- int encLen = (len / 3) * 4 + (len % 3 > 0 ? 4 : 0); // Bytes needed for actual encoding
- if (breakLines) {
- encLen += encLen / MAX_LINE_LENGTH; // Plus extra newline characters
- }
- byte[] outBuff = new byte[encLen];
-
-
- int d = 0;
- int e = 0;
- int len2 = len - 2;
- int lineLength = 0;
- for (; d < len2; d += 3, e += 4) {
- encode3to4(source, d + off, 3, outBuff, e, options);
-
- lineLength += 4;
- if (breakLines && lineLength >= MAX_LINE_LENGTH) {
- outBuff[e + 4] = NEW_LINE;
- e++;
- lineLength = 0;
- } // end if: end of line
- } // en dfor: each piece of array
-
- if (d < len) {
- encode3to4(source, d + off, len - d, outBuff, e, options);
- e += 4;
- } // end if: some padding needed
-
-
- // Only resize array if we didn't guess it right.
- if (e <= outBuff.length - 1) {
- // If breaking lines and the last byte falls right at
- // the line length (76 bytes per line), there will be
- // one extra byte, and the array will need to be resized.
- // Not too bad of an estimate on array size, I'd say.
- byte[] finalOut = new byte[e];
- System.arraycopy(outBuff, 0, finalOut, 0, e);
- //System.err.println("Having to resize array from " + outBuff.length + " to " + e );
- return finalOut;
- } else {
- //System.err.println("No need to resize array.");
- return outBuff;
- }
-
- } // end else: don't compress
-
- } // end encodeBytesToBytes
-
-
-
-
-
- /* ******** D E C O D I N G M E T H O D S ******** */
-
-
- /**
- * Decodes four bytes from array source
- * and writes the resulting bytes (up to three of them)
- * to destination.
- * The source and destination arrays can be manipulated
- * anywhere along their length by specifying
- * srcOffset and destOffset.
- * This method does not check to make sure your arrays
- * are large enough to accomodate srcOffset + 4 for
- * the source array or destOffset + 3 for
- * the destination array.
- * This method returns the actual number of bytes that
- * were converted from the Base64 encoding.
- * This is the lowest level of the decoding methods with
- * all possible parameters.
- *
- * @param source the array to convert
- * @param srcOffset the index where conversion begins
- * @param destination the array to hold the conversion
- * @param destOffset the index where output will be put
- * @param options alphabet type is pulled from this (standard, url-safe, ordered)
- * @return the number of decoded bytes converted
- * @throws NullPointerException if source or destination arrays are null
- * @throws IllegalArgumentException if srcOffset or destOffset are invalid
- * or there is not enough room in the array.
- * @since 1.3
- */
- private static int decode4to3(
- byte[] source, int srcOffset,
- byte[] destination, int destOffset, int options) {
-
- // Lots of error checking and exception throwing
- if (source == null) {
- throw new NullPointerException("Source array was null.");
- } // end if
- if (destination == null) {
- throw new NullPointerException("Destination array was null.");
- } // end if
- if (srcOffset < 0 || srcOffset + 3 >= source.length) {
- throw new IllegalArgumentException(String.format(
- "Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset));
- } // end if
- if (destOffset < 0 || destOffset + 2 >= destination.length) {
- throw new IllegalArgumentException(String.format(
- "Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset));
- } // end if
-
-
- byte[] DECODABET = getDecodabet(options);
-
- // Example: Dk==
- if (source[srcOffset + 2] == EQUALS_SIGN) {
- // Two ways to do the same thing. Don't know which way I like best.
- //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 )
- // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 );
- int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
- | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12);
-
- destination[destOffset] = (byte) (outBuff >>> 16);
- return 1;
- }
-
- // Example: DkL=
- else if (source[srcOffset + 3] == EQUALS_SIGN) {
- // Two ways to do the same thing. Don't know which way I like best.
- //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 )
- // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
- // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 );
- int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
- | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
- | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6);
-
- destination[destOffset] = (byte) (outBuff >>> 16);
- destination[destOffset + 1] = (byte) (outBuff >>> 8);
- return 2;
- }
-
- // Example: DkLE
- else {
- // Two ways to do the same thing. Don't know which way I like best.
- //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 )
- // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
- // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 )
- // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 );
- int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
- | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
- | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6)
- | ((DECODABET[source[srcOffset + 3]] & 0xFF));
-
-
- destination[destOffset] = (byte) (outBuff >> 16);
- destination[destOffset + 1] = (byte) (outBuff >> 8);
- destination[destOffset + 2] = (byte) (outBuff);
-
- return 3;
- }
- } // end decodeToBytes
-
-
- /**
- * Low-level access to decoding ASCII characters in
- * the form of a byte array. Ignores GUNZIP option, if
- * it's set. This is not generally a recommended method,
- * although it is used internally as part of the decoding process.
- * Special case: if len = 0, an empty array is returned. Still,
- * if you need more speed and reduced memory footprint (and aren't
- * gzipping), consider this method.
- *
- * @param source The Base64 encoded data
- * @return decoded data
- * @since 2.3.1
- */
- public static byte[] decode(byte[] source)
- throws java.io.IOException {
- byte[] decoded = null;
-// try {
- decoded = decode(source, 0, source.length, Base64.NO_OPTIONS);
-// } catch( java.io.IOException ex ) {
-// assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
-// }
- return decoded;
- }
-
-
- /**
- * Low-level access to decoding ASCII characters in
- * the form of a byte array. Ignores GUNZIP option, if
- * it's set. This is not generally a recommended method,
- * although it is used internally as part of the decoding process.
- * Special case: if len = 0, an empty array is returned. Still,
- * if you need more speed and reduced memory footprint (and aren't
- * gzipping), consider this method.
- *
- * @param source The Base64 encoded data
- * @param off The offset of where to begin decoding
- * @param len The length of characters to decode
- * @param options Can specify options such as alphabet type to use
- * @return decoded data
- * @throws java.io.IOException If bogus characters exist in source data
- * @since 1.3
- */
- public static byte[] decode(byte[] source, int off, int len, int options)
- throws java.io.IOException {
-
- // Lots of error checking and exception throwing
- if (source == null) {
- throw new NullPointerException("Cannot decode null source array.");
- } // end if
- if (off < 0 || off + len > source.length) {
- throw new IllegalArgumentException(String.format(
- "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len));
- } // end if
-
- if (len == 0) {
- return new byte[0];
- } else if (len < 4) {
- throw new IllegalArgumentException(
- "Base64-encoded string must have at least four characters, but length specified was " + len);
- } // end if
-
- byte[] DECODABET = getDecodabet(options);
-
- int len34 = len * 3 / 4; // Estimate on array size
- byte[] outBuff = new byte[len34]; // Upper limit on size of output
- int outBuffPosn = 0; // Keep track of where we're writing
-
- byte[] b4 = new byte[4]; // Four byte buffer from source, eliminating white space
- int b4Posn = 0; // Keep track of four byte input buffer
- int i = 0; // Source array counter
- byte sbiDecode = 0; // Special value from DECODABET
-
- for (i = off; i < off + len; i++) { // Loop through source
-
- sbiDecode = DECODABET[source[i] & 0xFF];
-
- // White space, Equals sign, or legit Base64 character
- // Note the values such as -5 and -9 in the
- // DECODABETs at the top of the file.
- if (sbiDecode >= WHITE_SPACE_ENC) {
- if (sbiDecode >= EQUALS_SIGN_ENC) {
- b4[b4Posn++] = source[i]; // Save non-whitespace
- if (b4Posn > 3) { // Time to decode?
- outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options);
- b4Posn = 0;
-
- // If that was the equals sign, break out of 'for' loop
- if (source[i] == EQUALS_SIGN) {
- break;
- } // end if: equals sign
- } // end if: quartet built
- } // end if: equals sign or better
- } // end if: white space, equals sign or better
- else {
- // There's a bad input character in the Base64 stream.
- throw new java.io.IOException(String.format(
- "Bad Base64 input character decimal %d in array position %d", ((int) source[i]) & 0xFF, i));
- } // end else:
- } // each input character
-
- byte[] out = new byte[outBuffPosn];
- System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
- return out;
- } // end decode
-
-
- /**
- * Decodes data from Base64 notation, automatically
- * detecting gzip-compressed data and decompressing it.
- *
- * @param s the string to decode
- * @return the decoded data
- * @throws java.io.IOException If there is a problem
- * @since 1.4
- */
- public static byte[] decode(String s) throws java.io.IOException {
- return decode(s, NO_OPTIONS);
- }
-
-
- /**
- * Decodes data from Base64 notation, automatically
- * detecting gzip-compressed data and decompressing it.
- *
- * @param s the string to decode
- * @param options encode options such as URL_SAFE
- * @return the decoded data
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if s is null
- * @since 1.4
- */
- public static byte[] decode(String s, int options) throws java.io.IOException {
-
- if (s == null) {
- throw new NullPointerException("Input string was null.");
- } // end if
-
- byte[] bytes;
- try {
- bytes = s.getBytes(PREFERRED_ENCODING);
- } // end try
- catch (java.io.UnsupportedEncodingException uee) {
- bytes = s.getBytes();
- } // end catch
- //
-
- // Decode
- bytes = decode(bytes, 0, bytes.length, options);
-
- // Check to see if it's gzip-compressed
- // GZIP Magic Two-Byte Number: 0x8b1f (35615)
- boolean dontGunzip = (options & DONT_GUNZIP) != 0;
- if ((bytes != null) && (bytes.length >= 4) && (!dontGunzip)) {
-
- int head = ((int) bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
- if (java.util.zip.GZIPInputStream.GZIP_MAGIC == head) {
- java.io.ByteArrayInputStream bais = null;
- java.util.zip.GZIPInputStream gzis = null;
- java.io.ByteArrayOutputStream baos = null;
- byte[] buffer = new byte[2048];
- int length = 0;
-
- try {
- baos = new java.io.ByteArrayOutputStream();
- bais = new java.io.ByteArrayInputStream(bytes);
- gzis = new java.util.zip.GZIPInputStream(bais);
-
- while ((length = gzis.read(buffer)) >= 0) {
- baos.write(buffer, 0, length);
- } // end while: reading input
-
- // No error? Get new bytes.
- bytes = baos.toByteArray();
-
- } // end try
- catch (java.io.IOException e) {
- e.printStackTrace();
- // Just return originally-decoded bytes
- } // end catch
- finally {
- try {
- baos.close();
- } catch (Exception e) {
- }
- try {
- gzis.close();
- } catch (Exception e) {
- }
- try {
- bais.close();
- } catch (Exception e) {
- }
- } // end finally
-
- } // end if: gzipped
- } // end if: bytes.length >= 2
-
- return bytes;
- } // end decode
-
-
- /**
- * Attempts to decode Base64 data and deserialize a Java
- * Object within. Returns null if there was an error.
- *
- * @param encodedObject The Base64 data to decode
- * @return The decoded and deserialized object
- * @throws NullPointerException if encodedObject is null
- * @throws java.io.IOException if there is a general error
- * @throws ClassNotFoundException if the decoded object is of a
- * class that cannot be found by the JVM
- * @since 1.5
- */
- public static Object decodeToObject(String encodedObject)
- throws java.io.IOException, ClassNotFoundException {
- return decodeToObject(encodedObject, NO_OPTIONS, null);
- }
-
-
- /**
- * Attempts to decode Base64 data and deserialize a Java
- * Object within. Returns null if there was an error.
- * If loader is not null, it will be the class loader
- * used when deserializing.
- *
- * @param encodedObject The Base64 data to decode
- * @param options Various parameters related to decoding
- * @param loader Optional class loader to use in deserializing classes.
- * @return The decoded and deserialized object
- * @throws NullPointerException if encodedObject is null
- * @throws java.io.IOException if there is a general error
- * @throws ClassNotFoundException if the decoded object is of a
- * class that cannot be found by the JVM
- * @since 2.3.4
- */
- public static Object decodeToObject(
- String encodedObject, int options, final ClassLoader loader)
- throws java.io.IOException, ClassNotFoundException {
-
- // Decode and gunzip if necessary
- byte[] objBytes = decode(encodedObject, options);
-
- java.io.ByteArrayInputStream bais = null;
- java.io.ObjectInputStream ois = null;
- Object obj = null;
-
- try {
- bais = new java.io.ByteArrayInputStream(objBytes);
-
- // If no custom class loader is provided, use Java's builtin OIS.
- if (loader == null) {
- ois = new java.io.ObjectInputStream(bais);
- } // end if: no loader provided
-
- // Else make a customized object input stream that uses
- // the provided class loader.
- else {
- ois = new java.io.ObjectInputStream(bais) {
- @Override
- public Class> resolveClass(java.io.ObjectStreamClass streamClass)
- throws java.io.IOException, ClassNotFoundException {
- Class c = Class.forName(streamClass.getName(), false, loader);
- if (c == null) {
- return super.resolveClass(streamClass);
- } else {
- return c; // Class loader knows of this class.
- } // end else: not null
- } // end resolveClass
- }; // end ois
- } // end else: no custom class loader
-
- obj = ois.readObject();
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and throw in order to execute finally{}
- } // end catch
- catch (ClassNotFoundException e) {
- throw e; // Catch and throw in order to execute finally{}
- } // end catch
- finally {
- try {
- bais.close();
- } catch (Exception e) {
- }
- try {
- ois.close();
- } catch (Exception e) {
- }
- } // end finally
-
- return obj;
- } // end decodeObject
-
-
- /**
- * Convenience method for encoding data to a file.
- *
- * As of v 2.3, if there is a error,
- * the method will throw an java.io.IOException. This is new to v2.3!
- * In earlier versions, it just returned false, but
- * in retrospect that's a pretty poor way to handle it.
- *
- * @param dataToEncode byte array of data to encode in base64 form
- * @param filename Filename for saving encoded data
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if dataToEncode is null
- * @since 2.1
- */
- public static void encodeToFile(byte[] dataToEncode, String filename)
- throws java.io.IOException {
-
- if (dataToEncode == null) {
- throw new NullPointerException("Data to encode was null.");
- } // end iff
-
- Base64.OutputStream bos = null;
- try {
- bos = new Base64.OutputStream(
- new java.io.FileOutputStream(filename), Base64.ENCODE);
- bos.write(dataToEncode);
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and throw to execute finally{} block
- } // end catch: java.io.IOException
- finally {
- try {
- bos.close();
- } catch (Exception e) {
- }
- } // end finally
-
- } // end encodeToFile
-
-
- /**
- * Convenience method for decoding data to a file.
- *
- * As of v 2.3, if there is a error,
- * the method will throw an java.io.IOException. This is new to v2.3!
- * In earlier versions, it just returned false, but
- * in retrospect that's a pretty poor way to handle it.
- *
- * @param dataToDecode Base64-encoded data as a string
- * @param filename Filename for saving decoded data
- * @throws java.io.IOException if there is an error
- * @since 2.1
- */
- public static void decodeToFile(String dataToDecode, String filename)
- throws java.io.IOException {
-
- Base64.OutputStream bos = null;
- try {
- bos = new Base64.OutputStream(
- new java.io.FileOutputStream(filename), Base64.DECODE);
- bos.write(dataToDecode.getBytes(PREFERRED_ENCODING));
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and throw to execute finally{} block
- } // end catch: java.io.IOException
- finally {
- try {
- bos.close();
- } catch (Exception e) {
- }
- } // end finally
-
- } // end decodeToFile
-
-
- /**
- * Convenience method for reading a base64-encoded
- * file and decoding it.
- *
- * As of v 2.3, if there is a error,
- * the method will throw an java.io.IOException. This is new to v2.3!
- * In earlier versions, it just returned false, but
- * in retrospect that's a pretty poor way to handle it.
- *
- * @param filename Filename for reading encoded data
- * @return decoded byte array
- * @throws java.io.IOException if there is an error
- * @since 2.1
- */
- public static byte[] decodeFromFile(String filename)
- throws java.io.IOException {
-
- byte[] decodedData = null;
- Base64.InputStream bis = null;
- try {
- // Set up some useful variables
- java.io.File file = new java.io.File(filename);
- byte[] buffer = null;
- int length = 0;
- int numBytes = 0;
-
- // Check for size of file
- if (file.length() > Integer.MAX_VALUE) {
- throw new java.io.IOException("File is too big for this convenience method (" + file.length() + " bytes).");
- } // end if: file too big for int index
- buffer = new byte[(int) file.length()];
-
- // Open a stream
- bis = new Base64.InputStream(
- new java.io.BufferedInputStream(
- new java.io.FileInputStream(file)), Base64.DECODE);
-
- // Read until done
- while ((numBytes = bis.read(buffer, length, 4096)) >= 0) {
- length += numBytes;
- } // end while
-
- // Save in a variable to return
- decodedData = new byte[length];
- System.arraycopy(buffer, 0, decodedData, 0, length);
-
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and release to execute finally{}
- } // end catch: java.io.IOException
- finally {
- try {
- bis.close();
- } catch (Exception e) {
- }
- } // end finally
-
- return decodedData;
- } // end decodeFromFile
-
-
- /**
- * Convenience method for reading a binary file
- * and base64-encoding it.
- *
- * As of v 2.3, if there is a error,
- * the method will throw an java.io.IOException. This is new to v2.3!
- * In earlier versions, it just returned false, but
- * in retrospect that's a pretty poor way to handle it.
- *
- * @param filename Filename for reading binary data
- * @return base64-encoded string
- * @throws java.io.IOException if there is an error
- * @since 2.1
- */
- public static String encodeFromFile(String filename)
- throws java.io.IOException {
-
- String encodedData = null;
- Base64.InputStream bis = null;
- try {
- // Set up some useful variables
- java.io.File file = new java.io.File(filename);
- byte[] buffer = new byte[Math.max((int) (file.length() * 1.4 + 1), 40)]; // Need max() for math on small files (v2.2.1); Need +1 for a few corner cases (v2.3.5)
- int length = 0;
- int numBytes = 0;
-
- // Open a stream
- bis = new Base64.InputStream(
- new java.io.BufferedInputStream(
- new java.io.FileInputStream(file)), Base64.ENCODE);
-
- // Read until done
- while ((numBytes = bis.read(buffer, length, 4096)) >= 0) {
- length += numBytes;
- } // end while
-
- // Save in a variable to return
- encodedData = new String(buffer, 0, length, Base64.PREFERRED_ENCODING);
-
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and release to execute finally{}
- } // end catch: java.io.IOException
- finally {
- try {
- bis.close();
- } catch (Exception e) {
- }
- } // end finally
-
- return encodedData;
- } // end encodeFromFile
-
- /**
- * Reads infile and encodes it to outfile.
- *
- * @param infile Input file
- * @param outfile Output file
- * @throws java.io.IOException if there is an error
- * @since 2.2
- */
- public static void encodeFileToFile(String infile, String outfile)
- throws java.io.IOException {
-
- String encoded = Base64.encodeFromFile(infile);
- java.io.OutputStream out = null;
- try {
- out = new java.io.BufferedOutputStream(
- new java.io.FileOutputStream(outfile));
- out.write(encoded.getBytes(StandardCharsets.US_ASCII)); // Strict, 7-bit output.
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and release to execute finally{}
- } // end catch
- finally {
- try {
- out.close();
- } catch (Exception ex) {
- }
- } // end finally
- } // end encodeFileToFile
-
-
- /**
- * Reads infile and decodes it to outfile.
- *
- * @param infile Input file
- * @param outfile Output file
- * @throws java.io.IOException if there is an error
- * @since 2.2
- */
- public static void decodeFileToFile(String infile, String outfile)
- throws java.io.IOException {
-
- byte[] decoded = Base64.decodeFromFile(infile);
- java.io.OutputStream out = null;
- try {
- out = new java.io.BufferedOutputStream(
- new java.io.FileOutputStream(outfile));
- out.write(decoded);
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and release to execute finally{}
- } // end catch
- finally {
- try {
- out.close();
- } catch (Exception ex) {
- }
- } // end finally
- } // end decodeFileToFile
-
-
- /* ******** I N N E R C L A S S I N P U T S T R E A M ******** */
-
-
- /**
- * A {@link Base64.InputStream} will read data from another
- * java.io.InputStream, given in the constructor,
- * and encode/decode to/from Base64 notation on the fly.
- *
- * @see Base64
- * @since 1.3
- */
- public static class InputStream extends java.io.FilterInputStream {
-
- private final boolean encode; // Encoding or decoding
- private final byte[] buffer; // Small buffer holding converted data
- private final int bufferLength; // Length of buffer (3 or 4)
- private final boolean breakLines; // Break lines at less than 80 characters
- private final int options; // Record options used to create the stream.
- private final byte[] decodabet; // Local copies to avoid extra method calls
- private int position; // Current position in the buffer
- private int numSigBytes; // Number of meaningful bytes in the buffer
- private int lineLength;
-
-
- /**
- * Constructs a {@link Base64.InputStream} in DECODE mode.
- *
- * @param in the java.io.InputStream from which to read data.
- * @since 1.3
- */
- public InputStream(java.io.InputStream in) {
- this(in, DECODE);
- } // end constructor
-
-
- /**
- * Constructs a {@link Base64.InputStream} in
- * either ENCODE or DECODE mode.
- *
- * Valid options:
- * ENCODE or DECODE: Encode or Decode as data is read.
- * DO_BREAK_LINES: break lines at 76 characters
- * (only meaningful when encoding)
- *
- *
- * Example: new Base64.InputStream( in, Base64.DECODE )
- *
- * @param in the java.io.InputStream from which to read data.
- * @param options Specified options
- * @see Base64#ENCODE
- * @see Base64#DECODE
- * @see Base64#DO_BREAK_LINES
- * @since 2.0
- */
- public InputStream(java.io.InputStream in, int options) {
-
- super(in);
- this.options = options; // Record for later
- this.breakLines = (options & DO_BREAK_LINES) > 0;
- this.encode = (options & ENCODE) > 0;
- this.bufferLength = encode ? 4 : 3;
- this.buffer = new byte[bufferLength];
- this.position = -1;
- this.lineLength = 0;
- this.decodabet = getDecodabet(options);
- } // end constructor
-
- /**
- * Reads enough of the input stream to convert
- * to/from Base64 and returns the next byte.
- *
- * @return next byte
- * @since 1.3
- */
- @Override
- public int read() throws java.io.IOException {
-
- // Do we need to get data?
- if (position < 0) {
- if (encode) {
- byte[] b3 = new byte[3];
- int numBinaryBytes = 0;
- for (int i = 0; i < 3; i++) {
- int b = in.read();
-
- // If end of stream, b is -1.
- if (b >= 0) {
- b3[i] = (byte) b;
- numBinaryBytes++;
- } else {
- break; // out of for loop
- } // end else: end of stream
-
- } // end for: each needed input byte
-
- if (numBinaryBytes > 0) {
- encode3to4(b3, 0, numBinaryBytes, buffer, 0, options);
- position = 0;
- numSigBytes = 4;
- } // end if: got data
- else {
- return -1; // Must be end of stream
- } // end else
- } // end if: encoding
-
- // Else decoding
- else {
- byte[] b4 = new byte[4];
- int i = 0;
- for (i = 0; i < 4; i++) {
- // Read four "meaningful" bytes:
- int b = 0;
- do {
- b = in.read();
- }
- while (b >= 0 && decodabet[b & 0x7f] <= WHITE_SPACE_ENC);
-
- if (b < 0) {
- break; // Reads a -1 if end of stream
- } // end if: end of stream
-
- b4[i] = (byte) b;
- } // end for: each needed input byte
-
- if (i == 4) {
- numSigBytes = decode4to3(b4, 0, buffer, 0, options);
- position = 0;
- } // end if: got four characters
- else if (i == 0) {
- return -1;
- } // end else if: also padded correctly
- else {
- // Must have broken out from above.
- throw new java.io.IOException("Improperly padded Base64 input.");
- } // end
-
- } // end else: decode
- } // end else: get data
-
- // Got data?
- if (position >= 0) {
- // End of relevant data?
- if ( /*!encode &&*/ position >= numSigBytes) {
- return -1;
- } // end if: got data
-
- if (encode && breakLines && lineLength >= MAX_LINE_LENGTH) {
- lineLength = 0;
- return '\n';
- } // end if
- else {
- lineLength++; // This isn't important when decoding
- // but throwing an extra "if" seems
- // just as wasteful.
-
- int b = buffer[position++];
-
- if (position >= bufferLength) {
- position = -1;
- } // end if: end
-
- return b & 0xFF; // This is how you "cast" a byte that's
- // intended to be unsigned.
- } // end else
- } // end if: position >= 0
-
- // Else error
- else {
- throw new java.io.IOException("Error in Base64 code reading stream.");
- } // end else
- } // end read
-
-
- /**
- * Calls {@link #read()} repeatedly until the end of stream
- * is reached or len bytes are read.
- * Returns number of bytes read into array or -1 if
- * end of stream is encountered.
- *
- * @param dest array to hold values
- * @param off offset for array
- * @param len max number of bytes to read into array
- * @return bytes read into array or -1 if end of stream is encountered.
- * @since 1.3
- */
- @Override
- public int read(byte[] dest, int off, int len)
- throws java.io.IOException {
- int i;
- int b;
- for (i = 0; i < len; i++) {
- b = read();
-
- if (b >= 0) {
- dest[off + i] = (byte) b;
- } else if (i == 0) {
- return -1;
- } else {
- break; // Out of 'for' loop
- } // Out of 'for' loop
- } // end for: each byte read
- return i;
- } // end read
-
- } // end inner class InputStream
-
-
-
-
-
-
- /* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */
-
-
- /**
- * A {@link Base64.OutputStream} will write data to another
- * java.io.OutputStream, given in the constructor,
- * and encode/decode to/from Base64 notation on the fly.
- *
- * @see Base64
- * @since 1.3
- */
- public static class OutputStream extends java.io.FilterOutputStream {
-
- private final boolean encode;
- private final int bufferLength;
- private final boolean breakLines;
- private final byte[] b4; // Scratch used in a few places
- private final int options; // Record for later
- private final byte[] decodabet; // Local copies to avoid extra method calls
- private int position;
- private boolean suspendEncoding;
- private byte[] buffer;
- private int lineLength;
-
- /**
- * Constructs a {@link Base64.OutputStream} in ENCODE mode.
- *
- * @param out the java.io.OutputStream to which data will be written.
- * @since 1.3
- */
- public OutputStream(java.io.OutputStream out) {
- this(out, ENCODE);
- } // end constructor
-
-
- /**
- * Constructs a {@link Base64.OutputStream} in
- * either ENCODE or DECODE mode.
- *
- * Valid options:
- * ENCODE or DECODE: Encode or Decode as data is read.
- * DO_BREAK_LINES: don't break lines at 76 characters
- * (only meaningful when encoding)
- *
- *
- * Example: new Base64.OutputStream( out, Base64.ENCODE )
- *
- * @param out the java.io.OutputStream to which data will be written.
- * @param options Specified options.
- * @see Base64#ENCODE
- * @see Base64#DECODE
- * @see Base64#DO_BREAK_LINES
- * @since 1.3
- */
- public OutputStream(java.io.OutputStream out, int options) {
- super(out);
- this.breakLines = (options & DO_BREAK_LINES) != 0;
- this.encode = (options & ENCODE) != 0;
- this.bufferLength = encode ? 3 : 4;
- this.buffer = new byte[bufferLength];
- this.position = 0;
- this.lineLength = 0;
- this.suspendEncoding = false;
- this.b4 = new byte[4];
- this.options = options;
- this.decodabet = getDecodabet(options);
- } // end constructor
-
-
- /**
- * Writes the byte to the output stream after
- * converting to/from Base64 notation.
- * When encoding, bytes are buffered three
- * at a time before the output stream actually
- * gets a write() call.
- * When decoding, bytes are buffered four
- * at a time.
- *
- * @param theByte the byte to write
- * @since 1.3
- */
- @Override
- public void write(int theByte)
- throws java.io.IOException {
- // Encoding suspended?
- if (suspendEncoding) {
- this.out.write(theByte);
- return;
- } // end if: supsended
-
- // Encode?
- if (encode) {
- buffer[position++] = (byte) theByte;
- if (position >= bufferLength) { // Enough to encode.
-
- this.out.write(encode3to4(b4, buffer, bufferLength, options));
-
- lineLength += 4;
- if (breakLines && lineLength >= MAX_LINE_LENGTH) {
- this.out.write(NEW_LINE);
- lineLength = 0;
- } // end if: end of line
-
- position = 0;
- } // end if: enough to output
- } // end if: encoding
-
- // Else, Decoding
- else {
- // Meaningful Base64 character?
- if (decodabet[theByte & 0x7f] > WHITE_SPACE_ENC) {
- buffer[position++] = (byte) theByte;
- if (position >= bufferLength) { // Enough to output.
-
- int len = Base64.decode4to3(buffer, 0, b4, 0, options);
- out.write(b4, 0, len);
- position = 0;
- } // end if: enough to output
- } // end if: meaningful base64 character
- else if (decodabet[theByte & 0x7f] != WHITE_SPACE_ENC) {
- throw new java.io.IOException("Invalid character in Base64 data.");
- } // end else: not white space either
- } // end else: decoding
- } // end write
-
-
- /**
- * Calls {@link #write(int)} repeatedly until len
- * bytes are written.
- *
- * @param theBytes array from which to read bytes
- * @param off offset for array
- * @param len max number of bytes to read into array
- * @since 1.3
- */
- @Override
- public void write(byte[] theBytes, int off, int len)
- throws java.io.IOException {
- // Encoding suspended?
- if (suspendEncoding) {
- this.out.write(theBytes, off, len);
- return;
- } // end if: supsended
-
- for (int i = 0; i < len; i++) {
- write(theBytes[off + i]);
- } // end for: each byte written
-
- } // end write
-
-
- /**
- * Method added by PHIL. [Thanks, PHIL. -Rob]
- * This pads the buffer without closing the stream.
- *
- * @throws java.io.IOException if there's an error.
- */
- public void flushBase64() throws java.io.IOException {
- if (position > 0) {
- if (encode) {
- out.write(encode3to4(b4, buffer, position, options));
- position = 0;
- } // end if: encoding
- else {
- throw new java.io.IOException("Base64 input not properly padded.");
- } // end else: decoding
- } // end if: buffer partially full
-
- } // end flush
-
-
- /**
- * Flushes and closes (I think, in the superclass) the stream.
- *
- * @since 1.3
- */
- @Override
- public void close() throws java.io.IOException {
- // 1. Ensure that pending characters are written
- flushBase64();
-
- // 2. Actually close the stream
- // Base class both flushes and closes.
- super.close();
-
- buffer = null;
- out = null;
- } // end close
-
-
- /**
- * Suspends encoding of the stream.
- * May be helpful if you need to embed a piece of
- * base64-encoded data in a stream.
- *
- * @throws java.io.IOException if there's an error flushing
- * @since 1.5.1
- */
- public void suspendEncoding() throws java.io.IOException {
- flushBase64();
- this.suspendEncoding = true;
- } // end suspendEncoding
-
-
- /**
- * Resumes encoding of the stream.
- * May be helpful if you need to embed a piece of
- * base64-encoded data in a stream.
- *
- * @since 1.5.1
- */
- public void resumeEncoding() {
- this.suspendEncoding = false;
- } // end resumeEncoding
-
-
- } // end inner class OutputStream
-
-
-} // end class Base64
\ No newline at end of file
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/Common.java b/src/main/java/org/torusresearch/torusutils/helpers/Common.java
new file mode 100644
index 0000000..32da76c
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/helpers/Common.java
@@ -0,0 +1,111 @@
+package org.torusresearch.torusutils.helpers;
+
+import org.jetbrains.annotations.NotNull;
+import org.torusresearch.torusutils.apis.responses.VerifierLookupResponse.VerifierKey;
+import org.torusresearch.torusutils.apis.responses.VerifierLookupResponse.VerifierLookupResponse;
+import org.torusresearch.torusutils.types.common.KeyLookup.KeyResult;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class Common {
+ private Common() {
+ }
+
+ public static KeyResult normalizeKeyResult(@NotNull VerifierLookupResponse result) {
+ Boolean isNewKey = false;
+ if (result.is_new_key != null) {
+ isNewKey = result.is_new_key;
+ }
+ KeyResult finalResult = new KeyResult(isNewKey);
+ if (result.keys.length > 0) {
+ VerifierKey finalKey = result.keys[0];
+ finalResult.keys = new VerifierKey[]{ finalKey };
+ }
+ return finalResult;
+ }
+
+ public static String padLeft(@NotNull String inputString, @NotNull Character padChar, int length) {
+ StringBuilder sb = new StringBuilder(inputString);
+ int count = length - sb.length();
+ while(count > 0) {
+ sb.insert(0, padChar);
+ count--;
+ }
+ return sb.toString();
+ }
+
+ public static String trimLeadingZeros(String source) {
+ for (int i = 0; i < source.length(); ++i) {
+ char c = source.charAt(i);
+ if (c != '0') {
+ return source.substring(i);
+ }
+ }
+ return "0";
+ }
+
+ public static List> kCombinations(@NotNull List set, int k) {
+ List> combs = new ArrayList<>();
+
+ if ((k == 0) || k > set.size())
+ {
+ return combs;
+ }
+
+ if (k == set.size()) {
+ combs.add(set);
+ return combs;
+ }
+
+ if (k == 1) {
+ for (Integer i : set) {
+ ArrayList arrList = new ArrayList<>();
+ arrList.add(i);
+ combs.add(arrList);
+ }
+ return combs;
+ }
+
+ for (int i = 0; i < ((set.size() - k) + 1); i++) {
+ List> tailCombs = kCombinations(set.subList(i + 1, set.size()), k - 1);
+ for (List tailComb : tailCombs) {
+ List prependedComb = new ArrayList<>();
+ prependedComb.add(set.get(i));
+ prependedComb.addAll(tailComb);
+ combs.add(prependedComb);
+ }
+ }
+ return combs;
+ }
+
+ public static Integer calculateMedian(@NotNull List arr) {
+ int arrSize = arr.size();
+
+ if (arrSize == 0) return 0;
+
+ Collections.sort(arr);
+
+ // odd length
+ if (arrSize % 2 != 0) {
+ return arr.get(arrSize / 2);
+ }
+
+ // return average of two mid values in case of even arrSize
+ Integer mid1 = arr.get(arrSize / 2 - 1);
+ Integer mid2 = arr.get(arrSize / 2);
+ return (mid1+mid2)/2;
+ }
+
+ public static String strip04Prefix(@NotNull String pubKey) {
+ if (pubKey.startsWith("04")) {
+ return pubKey.substring(2);
+ }
+ return pubKey;
+ }
+
+ public static boolean isEmpty(@org.jetbrains.annotations.Nullable final CharSequence cs) {
+ return cs == null || cs.length() == 0;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/ECPointArithmetic.java b/src/main/java/org/torusresearch/torusutils/helpers/ECPointArithmetic.java
deleted file mode 100644
index 3d1a349..0000000
--- a/src/main/java/org/torusresearch/torusutils/helpers/ECPointArithmetic.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package org.torusresearch.torusutils.helpers;
-
-import java.math.BigInteger;
-import java.security.spec.ECFieldFp;
-import java.security.spec.EllipticCurve;
-
-// http://stackoverflow.com/questions/11190860/point-multiplication-in-elliptic-curvves
-public class ECPointArithmetic {
- EllipticCurve ec;
- ECFieldFp ef;
- private final BigInteger x;
- private final BigInteger y;
- private final BigInteger z;
- private BigInteger zinv;
- private final BigInteger one = BigInteger.ONE;
- private final BigInteger zero = BigInteger.ZERO;
- private boolean infinity;
-
- public ECPointArithmetic(EllipticCurve ec, BigInteger x, BigInteger y, BigInteger z) {
- this.ec = ec;
- this.x = x;
- this.y = y;
- this.ef = (ECFieldFp) ec.getField();
-
- // Projective coordinates: either zinv == null or z * zinv == 1
- // z and zinv are just BigIntegers, not fieldElements
- if (z == null) {
- this.z = BigInteger.ONE;
- } else {
- this.z = z;
- }
- this.zinv = null;
- infinity = false;
- }
-
- public BigInteger getX() {
- if (this.zinv == null) {
- this.zinv = this.z.modInverse(this.ef.getP());
- }
- return this.x.multiply(this.zinv).mod(this.ef.getP());
- }
-
- public BigInteger getY() {
- if (this.zinv == null) {
- this.zinv = this.z.modInverse(this.ef.getP());
- }
- return this.y.multiply(this.zinv).mod(this.ef.getP());
- }
-
- public boolean pointEquals(ECPointArithmetic other) {
- if (other == this) {
- return true;
- }
- if (this.isInfinity()) {
- return other.isInfinity();
- }
- if (other.isInfinity()) {
- return this.isInfinity();
- }
- BigInteger u, v;
- // u = Y2 * Z1 - Y1 * Z2
- u = other.y.multiply(this.z).subtract(this.y.multiply(other.z)).mod(this.ef.getP());
- if (!u.equals(BigInteger.ZERO)) {
- return false;
- }
- // v = X2 * Z1 - X1 * Z2
- v = other.x.multiply(this.z).subtract(this.x.multiply(other.z)).mod(this.ef.getP());
- return v.equals(BigInteger.ZERO);
- }
-
- public boolean isInfinity() {
-
- if ((this.x == zero) && (this.y == zero)) {
- return true;
- }
- return this.z.equals(BigInteger.ZERO) && !this.y.equals(BigInteger.ZERO);
-
- }
-
- public ECPointArithmetic negate() {
- return new ECPointArithmetic(this.ec, this.x, this.y.negate(), this.z);
- }
-
- public ECPointArithmetic add(ECPointArithmetic b) {
- if (this.isInfinity()) {
- return b;
- }
- if (b.isInfinity()) {
- return this;
- }
- ECPointArithmetic R = new ECPointArithmetic(this.ec, zero, zero, null);
- // u = Y2 * Z1 - Y1 * Z2
- BigInteger u = b.y.multiply(this.z).subtract(this.y.multiply(b.z)).mod(this.ef.getP());
- // v = X2 * Z1 - X1 * Z2
- BigInteger v = b.x.multiply(this.z).subtract(this.x.multiply(b.z)).mod(this.ef.getP());
-
- if (BigInteger.ZERO.equals(v)) {
- if (BigInteger.ZERO.equals(u)) {
- return this.twice(); // this == b, so double
- }
-
- infinity = true; // this = -b, so infinity
- return R;
- }
-
- BigInteger THREE = new BigInteger("3");
- BigInteger x1 = this.x;
- BigInteger y1 = this.y;
- BigInteger x2 = b.x;
- BigInteger y2 = b.y;
-
- BigInteger v2 = v.pow(2);
- BigInteger v3 = v2.multiply(v);
- BigInteger x1v2 = x1.multiply(v2);
- BigInteger zu2 = u.pow(2).multiply(this.z);
-
- // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3)
- BigInteger x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.ef.getP());
-
- // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3
- BigInteger y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.ef.getP());
-
- // z3 = v^3 * z1 * z2
- BigInteger z3 = v3.multiply(this.z).multiply(b.z).mod(this.ef.getP());
-
- return new ECPointArithmetic(this.ec, x3, y3, z3);
- }
-
- public ECPointArithmetic twice() {
- if (this.isInfinity()) {
- return this;
- }
- ECPointArithmetic R = new ECPointArithmetic(this.ec, zero, zero, null);
- if (this.y.signum() == 0) {
- infinity = true;
- return R;
- }
-
- BigInteger THREE = new BigInteger("3");
- BigInteger x1 = this.x;
- BigInteger y1 = this.y;
-
- BigInteger y1z1 = y1.multiply(this.z);
- BigInteger y1sqz1 = y1z1.multiply(y1).mod(this.ef.getP());
- BigInteger a = this.ec.getA();
-
- // w = 3 * x1^2 + a * z1^2
- BigInteger w = x1.pow(2).multiply(THREE);
-
- if (!BigInteger.ZERO.equals(a)) {
- w = w.add(this.z.pow(2).multiply(a));
- }
-
- w = w.mod(this.ef.getP());
-
- // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1)
- BigInteger x3 = w.pow(2).subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.ef.getP());
-
- // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3
- BigInteger y3 = (w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1))).shiftLeft(2).multiply(y1sqz1).subtract(w.pow(2).multiply(w)).mod(this.ef.getP());
-
- // z3 = 8 * (y1 * z1)^3
- BigInteger z3 = y1z1.pow(2).multiply(y1z1).shiftLeft(3).mod(this.ef.getP());
-
- return new ECPointArithmetic(this.ec, x3, y3, z3);
- }
-
- public ECPointArithmetic multiply(BigInteger k) {
- if (this.isInfinity()) {
- return this;
- }
-
- ECPointArithmetic R = new ECPointArithmetic(this.ec, zero, zero, null);
- if (k.signum() == 0) {
- infinity = true;
- return R;
- }
-
- BigInteger e = k;
- BigInteger h = e.multiply(new BigInteger("3"));
-
- ECPointArithmetic neg = this.negate();
- R = this;
-
- int i;
- for (i = h.bitLength() - 2; i > 0; --i) {
- R = R.twice();
- boolean hBit = h.testBit(i);
- boolean eBit = e.testBit(i);
-
- if (hBit != eBit) {
- R = R.add(hBit ? this : neg);
- }
- }
-
- return R;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/KeyUtils.java b/src/main/java/org/torusresearch/torusutils/helpers/KeyUtils.java
new file mode 100644
index 0000000..e80de63
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/helpers/KeyUtils.java
@@ -0,0 +1,272 @@
+package org.torusresearch.torusutils.helpers;
+import com.google.gson.Gson;
+import org.bouncycastle.crypto.ec.CustomNamedCurves;
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.crypto.signers.ECDSASigner;
+import org.bouncycastle.jce.ECNamedCurveTable;
+import org.bouncycastle.jce.interfaces.ECPrivateKey;
+import org.bouncycastle.jce.interfaces.ECPublicKey;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jce.spec.ECParameterSpec;
+import org.bouncycastle.jce.spec.ECPrivateKeySpec;
+import org.bouncycastle.jce.spec.ECPublicKeySpec;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.util.encoders.Hex;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.fetchnodedetails.types.TorusNodePub;
+import org.torusresearch.torusutils.apis.requests.NonceMetadataParams;
+import org.torusresearch.torusutils.apis.requests.SetNonceData;
+import org.torusresearch.torusutils.helpers.encryption.Encryption;
+import org.torusresearch.torusutils.types.Point;
+import org.torusresearch.torusutils.types.Polynomial;
+import org.torusresearch.torusutils.types.Share;
+import org.torusresearch.torusutils.types.common.ImportedShare;
+import org.torusresearch.torusutils.types.common.PrivateKeyData;
+import org.torusresearch.torusutils.types.common.TorusKeyType;
+import org.torusresearch.torusutils.types.common.ecies.Ecies;
+import org.torusresearch.torusutils.types.common.ecies.EciesHexOmitCipherText;
+import org.web3j.crypto.ECKeyPair;
+import org.web3j.crypto.Hash;
+import org.web3j.crypto.Keys;
+
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.ECGenParameterSpec;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.List;
+import java.util.Map;
+
+public class KeyUtils {
+ static final protected Provider provider = new BouncyCastleProvider();
+ static final protected ECParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256k1");
+
+
+ public static KeyPair generateKeyPair() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
+ KeyPairGenerator kpgen = KeyPairGenerator.getInstance("ECDH", provider);
+ kpgen.initialize(new ECGenParameterSpec("secp256k1"), new SecureRandom());
+ return kpgen.generateKeyPair();
+ }
+
+ public static byte [] serializePublicKey (@NotNull PublicKey key, @NotNull Boolean compressed) {
+ org.bouncycastle.jce.interfaces.ECPublicKey eckey = (ECPublicKey)key;
+ return eckey.getQ().getEncoded(compressed);
+ }
+
+ public static PublicKey deserializePublicKey (@NotNull byte [] data) throws Exception
+ {
+ ECPublicKeySpec pubKey = new ECPublicKeySpec(
+ params.getCurve().decodePoint(data), params);
+ KeyFactory kf = KeyFactory.getInstance("ECDH", provider);
+ return kf.generatePublic(pubKey);
+ }
+
+ public static byte [] serializePrivateKey (@NotNull PrivateKey key) {
+ ECPrivateKey eckey = (ECPrivateKey)key;
+ return eckey.getD().toByteArray();
+ }
+ public static PrivateKey deserializePrivateKey (@NotNull byte [] data) throws Exception {
+ ECPrivateKeySpec prvkey = new org.bouncycastle.jce.spec.ECPrivateKeySpec(new BigInteger(data), params);
+ KeyFactory kf = KeyFactory.getInstance("ECDH", provider);
+ return kf.generatePrivate(prvkey);
+ }
+
+ private static String randomNonce() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
+ KeyPair keyPair = generateKeyPair();
+ return Common.padLeft(Hex.toHexString(KeyUtils.serializePrivateKey(keyPair.getPrivate())), '0', 64);
+ }
+
+ public static BigInteger getOrderOfCurve() {
+ return params.getN();
+ }
+
+ public static String privateToPublic(@NotNull BigInteger key) {
+ return "04" + Common.padLeft(ECKeyPair.create(key).getPublicKey().toString(16), '0', 128);
+ }
+
+ @SuppressWarnings("unused")
+ public static BigInteger generatePrivate() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException {
+ return Keys.createEcKeyPair().getPrivateKey();
+ }
+
+ @SuppressWarnings("unused")
+ public static String generateAddressFromPrivKey(@NotNull String privateKey) throws Exception {
+ PrivateKey privKey = deserializePrivateKey(Hex.decode(privateKey));
+ return Keys.toChecksumAddress(Keys.getAddress(ECKeyPair.create(privKey.getEncoded())));
+ }
+
+ public static String generateAddressFromPubKey(@NotNull String publicKeyX, @NotNull String publicKeyY) {
+ String finalPublicKey = publicKeyX + publicKeyY;
+ return Keys.toChecksumAddress(Keys.getAddress(finalPublicKey));
+ }
+
+ public static String[] getPublicKeyCoords(@NotNull String pubKey) throws TorusUtilError {
+ String publicKeyUnprefixed = pubKey;
+ if (publicKeyUnprefixed.length() > 128) {
+ publicKeyUnprefixed = Common.strip04Prefix(publicKeyUnprefixed);
+ }
+
+ if (publicKeyUnprefixed.length() <= 128) {
+ Common.padLeft(publicKeyUnprefixed, '0', 128);
+ } else {
+ throw new TorusUtilError("Invalid public key size");
+ }
+
+ String xCoord = publicKeyUnprefixed.substring(0, 64);
+ String yCoord = publicKeyUnprefixed.substring(64);
+
+ return new String[]{xCoord, yCoord};
+ }
+
+ public static String getPublicKeyFromCoords(@NotNull String pubKeyX, @NotNull String pubKeyY, boolean prefixed) {
+ String X = Common.padLeft(pubKeyX, '0', 64);
+ String Y = Common.padLeft(pubKeyY,'0', 64);
+
+ return prefixed ? "04" + X + Y : X + Y;
+ }
+
+ public static String combinePublicKeysFromStrings(@NotNull List keys, boolean compressed) throws TorusUtilError {
+ List collection = new ArrayList<>();
+
+ for (String item : keys) {
+ ECPoint point = CustomNamedCurves.getByName("secp256k1").getCurve().decodePoint(Hex.decode(item));
+ collection.add(point);
+ }
+
+ return combinePublicKeys(collection, compressed);
+ }
+
+ public static String combinePublicKeys(@NotNull List extends ECPoint> keys, boolean compressed) throws TorusUtilError {
+ if (keys.isEmpty()) {
+ throw new TorusUtilError("The keys list cannot be empty");
+ }
+
+ ECPoint combinedPoint = keys.get(0);
+ for (int i = 1; i < keys.size(); i++) {
+ combinedPoint = combinedPoint.add(keys.get(i));
+ }
+
+ byte[] serializedPoint = compressed ? combinedPoint.getEncoded(true) : combinedPoint.getEncoded(false);
+ return Hex.toHexString(serializedPoint);
+ }
+
+ public static PrivateKeyData generateKeyData(@NotNull String privateKey) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
+ BigInteger scalar = new BigInteger(privateKey,16);
+ BigInteger randomNonce = new BigInteger(randomNonce(), 16);
+
+ BigInteger oAuthKey = scalar.subtract(randomNonce).mod(getOrderOfCurve());
+
+ return new PrivateKeyData(
+ Common.padLeft(oAuthKey.toString(16), '0', 64),
+ KeyUtils.privateToPublic(oAuthKey),
+ Common.padLeft(randomNonce.toString(16), '0', 64),
+ Common.padLeft(oAuthKey.toString(16), '0', 64),
+ KeyUtils.privateToPublic(oAuthKey),
+ Common.padLeft(scalar.toString(16), '0', 64),
+ KeyUtils.privateToPublic(scalar)
+ );
+ }
+
+ public static NonceMetadataParams generateNonceMetadataParams(@NotNull String operation, @NotNull BigInteger privateKey, @Nullable BigInteger nonce, @NotNull Integer serverTimeOffset) {
+ BigInteger timeSeconds = BigInteger.valueOf(System.currentTimeMillis() / 1000L);
+ BigInteger timestamp = timeSeconds.add(BigInteger.valueOf(serverTimeOffset));
+
+ // Serialize public key into padded X and Y coordinates
+ String derivedPubKeyString = KeyUtils.privateToPublic(privateKey);
+ String derivedPubKeyX = derivedPubKeyString.substring(2, 66);
+ String derivedPubKeyY = derivedPubKeyString.substring(66);
+
+ // Create SetNonceData object with operation and timestamp
+ SetNonceData setNonceData = new SetNonceData(operation, (nonce != null) ? Common.padLeft(nonce.toString(16), '0', 64) : null, null, timestamp.toString(16));
+
+ // Convert SetNonceData object to JSON string
+ Gson gson = new Gson();
+ String encodedData = gson.toJson(setNonceData);
+
+ // Hash the JSON string using keccak256 (SHA-3)
+ byte[] hashedData = Hash.sha3(encodedData.getBytes(StandardCharsets.UTF_8));
+
+ // Sign the hashed data using ECDSA with the private key
+ SecureRandom random = new SecureRandom();
+ ECDSASigner signer = new ECDSASigner();
+ ECDomainParameters domainParams = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH(), params.getSeed());
+ ECPrivateKeyParameters privKeyParams = new ECPrivateKeyParameters(privateKey, domainParams);
+ signer.init(true, new ParametersWithRandom(privKeyParams, random));
+ BigInteger[] signature = signer.generateSignature(hashedData);
+
+ // Format the signature into a padded hexadecimal string
+ String sig = Common.padLeft(signature[0].toString(16), '0', 64) +
+ Common.padLeft(signature[1].toString(16), '0', 64) +
+ Common.padLeft("", '0', 2); // Assuming padding to ensure consistent length
+
+ // Convert the hexadecimal signature string to bytes
+ byte[] sigBytes = Hex.decode(sig);
+
+ // Encode the signature bytes to Base64
+ String finalSig = new String(Base64.getEncoder().encode(sigBytes), StandardCharsets.UTF_8);
+
+ // Return a new NonceMetadataParams object with the derived values
+ return new NonceMetadataParams(derivedPubKeyX, derivedPubKeyY, setNonceData,
+ Base64.getEncoder().encodeToString(encodedData.getBytes(StandardCharsets.UTF_8)), finalSig, null, null, null);
+ }
+
+ public static List generateShares(@NotNull TorusKeyType keyType, @NotNull Integer serverTimeOffset, @NotNull List nodeIndexes, @NotNull List nodePubKeys, @NotNull String privateKey) throws Exception {
+ if (keyType != TorusKeyType.secp256k1) {
+ throw TorusUtilError.RUNTIME_ERROR("Unsupported key type");
+ }
+
+ PrivateKeyData keyData = generateKeyData(privateKey);
+
+ int threshold = (nodePubKeys.size() / 2) + 1;
+ int degree = threshold - 1;
+ List nodeIndexesBN = new ArrayList<>(nodeIndexes);
+
+ Polynomial poly = Lagrange.generateRandomPolynomial(degree, new BigInteger(keyData.getOAuthKey(), 16), null);
+ Map shares = poly.generateShares(nodeIndexesBN.toArray(new BigInteger[0]));
+
+ NonceMetadataParams nonceParams = KeyUtils.generateNonceMetadataParams("getOrSetNonce", new BigInteger(keyData.getSigningKey(), 16), new BigInteger(keyData.getNonce(), 16), serverTimeOffset);
+
+ List encShares = new ArrayList<>();
+ for (int i = 0; i < nodePubKeys.size(); i++) {
+ String indexHex = String.format("%064x", nodeIndexes.get(i));
+ Share shareInfo = shares.get(indexHex);
+ String nodePub = KeyUtils.getPublicKeyFromCoords(nodePubKeys.get(i).getX(), nodePubKeys.get(i).getY(), true);
+ String share = Common.padLeft(shareInfo.getShare().toString(16), '0', 64);
+ Ecies encryptedMsg = Encryption.encrypt(Hex.decode(nodePub), share);
+ encShares.add(encryptedMsg);
+ }
+
+ List sharesData = new ArrayList<>();
+ for (int i = 0; i < nodePubKeys.size(); i++) {
+ Ecies encrypted = encShares.get(i);
+ String[] oAuthPub = getPublicKeyCoords(keyData.getOAuthPubKey());
+ String[] signingPub = getPublicKeyCoords(keyData.getSigningPubKey());
+ String[] finalPub = getPublicKeyCoords(keyData.getFinalPubKey());
+ Point finalPoint = new Point(finalPub[0], finalPub[1]);
+
+ ImportedShare importShare = new ImportedShare(
+ oAuthPub[0], oAuthPub[1], finalPoint,
+ signingPub[0], signingPub[1], encrypted.ciphertext,
+ new EciesHexOmitCipherText(encrypted.iv, encrypted.ephemPublicKey, encrypted.mac, "AES256"), null,
+ Integer.parseInt(nodeIndexes.get(i).toString(16), 16), keyType,
+ nonceParams.encodedData, nonceParams.signature);
+
+ sharesData.add(importShare);
+ }
+ return sharesData;
+ }
+}
+
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/Lagrange.java b/src/main/java/org/torusresearch/torusutils/helpers/Lagrange.java
new file mode 100644
index 0000000..9ea28fe
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/helpers/Lagrange.java
@@ -0,0 +1,206 @@
+package org.torusresearch.torusutils.helpers;
+
+import static org.torusresearch.torusutils.helpers.KeyUtils.getOrderOfCurve;
+
+import org.bouncycastle.util.encoders.Hex;
+import org.jetbrains.annotations.NotNull;
+import org.torusresearch.torusutils.types.Point;
+import org.torusresearch.torusutils.types.Polynomial;
+import org.torusresearch.torusutils.types.Share;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import io.reactivex.annotations.Nullable;
+
+public class Lagrange {
+
+ public static BigInteger generatePrivateExcludingIndexes(@NotNull List shareIndexes) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
+ BigInteger key = new BigInteger(Common.padLeft(Hex.toHexString(KeyUtils.serializePrivateKey(KeyUtils.generateKeyPair().getPrivate())), '0', 64), 16);
+
+ if (shareIndexes.contains(key)) {
+ return generatePrivateExcludingIndexes(shareIndexes);
+ }
+
+ return key;
+ }
+
+ public static BigInteger[] generateEmptyBNArray(int length) {
+ BigInteger[] array = new BigInteger[length];
+ Arrays.fill(array, BigInteger.ZERO);
+ return array;
+ }
+
+ public static BigInteger denominator(int i, @NotNull Point[] innerPoints) {
+ BigInteger result = BigInteger.ONE;
+ BigInteger xi = innerPoints[i].getX();
+ for (int j = 0; j < innerPoints.length; j++) {
+ if (i != j) {
+ BigInteger tmp = xi;
+ tmp = (tmp.subtract(innerPoints[j].getX()).mod(getOrderOfCurve()));
+ result = result.multiply(tmp).mod(getOrderOfCurve());
+ }
+ }
+ return result;
+ }
+
+ public static BigInteger[] interpolationPoly(int i, @NotNull Point[] innerPoints) {
+ BigInteger[] coefficients = generateEmptyBNArray(innerPoints.length);
+ BigInteger d = denominator(i, innerPoints);
+ if (d.equals(BigInteger.ZERO)) {
+ throw new IllegalArgumentException("Denominator for interpolationPoly is 0");
+ }
+
+ coefficients[0] = d.modInverse(getOrderOfCurve());
+
+ for (int k = 0; k < innerPoints.length; k++) {
+ BigInteger[] newCoefficients = generateEmptyBNArray(innerPoints.length);
+ if (k != i) {
+ int j = (k < i) ? k + 1 : k;
+ j -= 1;
+
+ while (j >= 0) {
+ newCoefficients[j + 1] = newCoefficients[j + 1].add(coefficients[j]).mod(getOrderOfCurve());
+ BigInteger tmp = innerPoints[k].getX();
+ tmp = tmp.multiply(coefficients[j]).mod(getOrderOfCurve());
+ newCoefficients[j] = newCoefficients[j].subtract(tmp).mod(getOrderOfCurve());
+ j -= 1;
+ }
+ coefficients = newCoefficients;
+ }
+ }
+
+ return coefficients;
+ }
+
+ public static Point[] pointSort(@NotNull Point[] innerPoints) {
+ Point[] pointsClone = Arrays.copyOf(innerPoints, innerPoints.length);
+ Arrays.sort(pointsClone, Comparator.comparing(Point::getX));
+ return pointsClone;
+ }
+ @SuppressWarnings("unused")
+ private static List pointSort(@NotNull List innerPoints) {
+ List pointArrClone = new ArrayList<>(innerPoints);
+ pointArrClone.sort(Comparator.comparing(Point::getX));
+ return pointArrClone;
+ }
+
+ public static Polynomial lagrange(@NotNull Point[] unsortedPoints) {
+ Point[] sortedPoints = pointSort(unsortedPoints);
+ BigInteger[] polynomial = generateEmptyBNArray(sortedPoints.length);
+ for (int i = 0; i < sortedPoints.length; i++) {
+ BigInteger[] coefficients = interpolationPoly(i, sortedPoints);
+ for (int k = 0; k < sortedPoints.length; k++) {
+ BigInteger tmp = sortedPoints[i].getY();
+ tmp = tmp.multiply(coefficients[k]).mod(getOrderOfCurve());
+ polynomial[k] = polynomial[k].add(tmp).mod(getOrderOfCurve());
+ }
+ }
+ return new Polynomial(polynomial);
+ }
+
+ public static Polynomial lagrangeInterpolatePolynomial(@NotNull Point[] points) {
+ return lagrange(points);
+ }
+
+ public static BigInteger lagrangeInterpolation(@NotNull BigInteger[] shares, @NotNull BigInteger[] nodeIndex) throws TorusUtilError {
+ if (shares.length != nodeIndex.length) {
+ return null;
+ }
+
+ int sharesDecrypt = 0;
+
+ BigInteger secret = BigInteger.ZERO;
+ for (int i = 0; i < shares.length; i++) {
+ BigInteger upper = BigInteger.ONE;
+ BigInteger lower = BigInteger.ONE;
+ for (int j = 0; j < shares.length; j++) {
+ if (i != j) {
+ upper = upper.multiply(nodeIndex[j].negate()).mod(getOrderOfCurve());
+ BigInteger temp = nodeIndex[i].subtract(nodeIndex[j]).mod(getOrderOfCurve());
+ lower = lower.multiply(temp).mod(getOrderOfCurve());
+ }
+ }
+ BigInteger inverse = lower.modInverse(getOrderOfCurve());
+ BigInteger delta = upper.multiply(inverse).mod(getOrderOfCurve());
+ delta = delta.multiply(shares[i]).mod(getOrderOfCurve());
+ secret = secret.add(delta).mod(getOrderOfCurve());
+ sharesDecrypt += 1;
+ }
+
+ if (secret.equals(BigInteger.ZERO)) {
+ throw TorusUtilError.INTERPOLATION_FAILED;
+ }
+
+ if (sharesDecrypt == shares.length) {
+ return secret;
+ }
+
+ throw TorusUtilError.INTERPOLATION_FAILED;
+ }
+
+ public static Polynomial generateRandomPolynomial(int degree, @Nullable BigInteger secret, @Nullable List deterministicShares) throws Exception {
+ BigInteger actualS = secret;
+ if (actualS == null) {
+ List excludeList = new ArrayList<>();
+ excludeList.add(actualS);
+ actualS = generatePrivateExcludingIndexes(excludeList);
+ }
+
+ // If no deterministic shares provided, generate random shares
+ if (deterministicShares == null) {
+ List poly = new ArrayList<>();
+ poly.add(actualS);
+
+ for (int i = 0; i < degree; i++) {
+ BigInteger share = generatePrivateExcludingIndexes(poly);
+ poly.add(share);
+ }
+
+ return new Polynomial(poly.toArray(new BigInteger[0]));
+ }
+
+ // Validate deterministic shares count
+ if (deterministicShares.size() > degree) {
+ throw new Exception("Deterministic shares in generateRandomPolynomial should be less or equal than degree to ensure an element of randomness");
+ }
+
+ // Initialize points map
+ Map points = new LinkedHashMap<>();
+
+ // Add deterministic shares to points map
+ for (Share share : deterministicShares) {
+ points.put(Common.padLeft(share.getShareIndex().toString(16), '0', 64), new Point(share.getShareIndex(), share.getShare()));
+ }
+
+ // Calculate remaining shares to fill the polynomial
+ int remainingDegree = degree - deterministicShares.size();
+ for (int i = 0; i < remainingDegree; i++) {
+ List excludeList = new ArrayList<>();
+ excludeList.add(BigInteger.ZERO);
+ BigInteger shareIndex = generatePrivateExcludingIndexes(excludeList);
+
+ // Ensure unique share index
+ while (points.containsKey(Common.padLeft(shareIndex.toString(16),'0', 64))) {
+ shareIndex = generatePrivateExcludingIndexes(excludeList);
+ }
+
+ String serializedKey = Common.padLeft(Hex.toHexString(KeyUtils.serializePrivateKey(KeyUtils.generateKeyPair().getPrivate())),'0',64);
+ points.put(Common.padLeft(shareIndex.toString(16),'0',64),
+ new Point(shareIndex, new BigInteger(serializedKey, 16)));
+ }
+
+ // Add point for zero index
+ points.put("0", new Point(BigInteger.ZERO, actualS));
+
+ // Interpolate polynomial using Lagrange interpolation
+ return lagrangeInterpolatePolynomial(new ArrayList<>(points.values()).toArray(new Point[0]));
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/MetadataUtils.java b/src/main/java/org/torusresearch/torusutils/helpers/MetadataUtils.java
new file mode 100644
index 0000000..ef8bef9
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/helpers/MetadataUtils.java
@@ -0,0 +1,119 @@
+package org.torusresearch.torusutils.helpers;
+
+import static org.torusresearch.torusutils.helpers.encryption.Encryption.decrypt;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.crypto.signers.ECDSASigner;
+import org.bouncycastle.jce.ECNamedCurveTable;
+import org.bouncycastle.jce.spec.ECParameterSpec;
+import org.bouncycastle.util.encoders.Hex;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.json.JSONObject;
+import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
+import org.torusresearch.torusutils.apis.APIUtils;
+import org.torusresearch.torusutils.apis.requests.GetMetadataParams;
+import org.torusresearch.torusutils.apis.requests.GetNonceParams;
+import org.torusresearch.torusutils.apis.requests.GetNonceSetDataParams;
+import org.torusresearch.torusutils.apis.requests.MetadataParams;
+import org.torusresearch.torusutils.apis.requests.SetData;
+import org.torusresearch.torusutils.apis.responses.GetMetadataResponse;
+import org.torusresearch.torusutils.apis.responses.GetOrSetNonceResult;
+import org.torusresearch.torusutils.types.common.TorusKeyType;
+import org.torusresearch.torusutils.types.common.ecies.Ecies;
+import org.torusresearch.torusutils.types.common.ecies.EciesHexOmitCipherText;
+import org.web3j.crypto.Hash;
+
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
+import java.util.Base64;
+import java.util.concurrent.ExecutionException;
+
+public class MetadataUtils {
+ private MetadataUtils() {
+ }
+
+ public static String decryptNodeData(@NotNull EciesHexOmitCipherText eciesData, @NotNull String ciphertextHex, @NotNull String privKey) throws Exception {
+ Ecies eciesOpts = new Ecies(
+ eciesData.iv,
+ eciesData.ephemPublicKey,
+ ciphertextHex,
+ eciesData.mac
+ );
+ return Hex.toHexString(decrypt(privKey, eciesOpts));
+ }
+
+
+ public static MetadataParams generateMetadataParams(@NotNull Integer serverTimeOffset, @NotNull String message, @NotNull String privateKey, @NotNull String X, @NotNull String Y, @Nullable TorusKeyType keyType) {
+ int timeStamp = serverTimeOffset + (int) (System.currentTimeMillis() / 1000L);
+ SetData setData = new SetData(message, String.valueOf(timeStamp));
+
+ Gson gson = new Gson();
+ String setDataString = gson.toJson(setData);
+ ECParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256k1");
+ BigInteger key = new BigInteger(privateKey, 16);
+ byte[] hashedData = Hash.sha3(setDataString.getBytes(StandardCharsets.UTF_8));
+ // Sign the hashed data using ECDSA with the private key
+ SecureRandom random = new SecureRandom();
+ ECDSASigner signer = new ECDSASigner();
+ ECDomainParameters domainParams = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH(), params.getSeed());
+ ECPrivateKeyParameters privKeyParams = new ECPrivateKeyParameters(key, domainParams);
+ signer.init(true, new ParametersWithRandom(privKeyParams, random));
+ BigInteger[] signature = signer.generateSignature(hashedData);
+
+ String sig = Common.padLeft(signature[0].toString(16), '0', 64) + Common.padLeft(signature[1].toString(16), '0', 64) + Common.padLeft("", '0', 2);
+ byte[] sigBytes = Base64.getEncoder().encode(Hex.decode(sig));
+ String finalSig = new String(sigBytes, StandardCharsets.UTF_8);
+ return new MetadataParams(X, Y, setData, finalSig, null, keyType);
+ }
+
+ public static GetMetadataResponse getMetadata(String legacyMetadataHost, GetMetadataParams data) throws ExecutionException, InterruptedException {
+ Gson gson = new Gson();
+ String metadata = gson.toJson(data, GetMetadataParams.class);
+ String metadataApiResponse = APIUtils.post(legacyMetadataHost + "/get", metadata, true).get();
+ return gson.fromJson(metadataApiResponse, GetMetadataResponse.class);
+ }
+
+ public static GetOrSetNonceResult getOrSetNonce(@NotNull String legacyMetadataHost, @NotNull String X, @NotNull String Y, @NotNull Integer serverTimeOffset, @Nullable String privateKey, Boolean getOnly, @Nullable TorusKeyType keyType) throws Exception {
+ String msg = getOnly ? "getNonce": "getOrSetNonce";
+ Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+ String data;
+ if (privateKey != null) {
+ MetadataParams params = generateMetadataParams(serverTimeOffset, msg, privateKey, X, Y, keyType);
+ data = gson.toJson(params);
+ } else {
+ GetNonceParams params = new GetNonceParams(X, Y , new GetNonceSetDataParams(msg));
+ data = gson.toJson(params);
+ }
+
+ String postResult = APIUtils.post(legacyMetadataHost + "/get_or_set_nonce", data, true).get();
+ JSONObject jsonObject = new JSONObject(postResult);
+ if (jsonObject.has("ipfs")) {
+ jsonObject.remove("ipfs");
+ }
+ return gson.fromJson(jsonObject.toString(), GetOrSetNonceResult.class);
+ }
+
+
+ public static GetOrSetNonceResult getOrSetSapphireMetadataNonce(@NotNull String metadataHost, @NotNull Web3AuthNetwork network, @NotNull String X, @NotNull String Y, @Nullable Integer serverTimeOffset, @Nullable String privateKey, Boolean getOnly, @Nullable TorusKeyType keyType) throws Exception {
+ // fix this comparison in fetchnodedetails, comparison should be against .sapphire()
+ int timeOffset = 0;
+ if (serverTimeOffset != null) {
+ timeOffset = serverTimeOffset;
+ }
+
+ timeOffset += (int) (System.currentTimeMillis() / 1000);
+
+ if (network.name().contains("sapphire")) {
+ return getOrSetNonce(metadataHost, X, Y, timeOffset, privateKey, getOnly, keyType);
+ } else {
+ throw TorusUtilError.METADATA_NONCE_MISSING;
+ }
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/NodeUtils.java b/src/main/java/org/torusresearch/torusutils/helpers/NodeUtils.java
new file mode 100644
index 0000000..fed27b2
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/helpers/NodeUtils.java
@@ -0,0 +1,573 @@
+package org.torusresearch.torusutils.helpers;
+
+import static org.torusresearch.torusutils.helpers.KeyUtils.getOrderOfCurve;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.google.gson.Gson;
+
+import org.bouncycastle.util.encoders.Hex;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
+import org.torusresearch.torusutils.TorusUtils;
+import org.torusresearch.torusutils.apis.APIUtils;
+import org.torusresearch.torusutils.apis.JsonRPCErrorInfo;
+import org.torusresearch.torusutils.apis.JsonRPCResponse;
+import org.torusresearch.torusutils.apis.PubKey;
+import org.torusresearch.torusutils.apis.requests.CommitmentRequestParams;
+import org.torusresearch.torusutils.apis.requests.GetMetadataParams;
+import org.torusresearch.torusutils.apis.requests.GetOrSetKeyParams;
+import org.torusresearch.torusutils.apis.requests.ShareRequestItem;
+import org.torusresearch.torusutils.apis.requests.ShareRequestParams;
+import org.torusresearch.torusutils.apis.responses.CommitmentRequestResult;
+import org.torusresearch.torusutils.apis.responses.GetOrSetNonceResult;
+import org.torusresearch.torusutils.apis.responses.KeyAssignment;
+import org.torusresearch.torusutils.apis.responses.ShareRequestResult;
+import org.torusresearch.torusutils.apis.responses.VerifierLookupResponse.VerifierLookupResponse;
+import org.torusresearch.torusutils.types.FinalKeyData;
+import org.torusresearch.torusutils.types.Metadata;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthKeyData;
+import org.torusresearch.torusutils.types.SessionData;
+import org.torusresearch.torusutils.types.TorusUtilsExtraParams;
+import org.torusresearch.torusutils.types.VerifierParams;
+import org.torusresearch.torusutils.types.common.ImportedShare;
+import org.torusresearch.torusutils.types.common.KeyLookup.KeyLookupResult;
+import org.torusresearch.torusutils.types.common.KeyLookup.KeyResult;
+import org.torusresearch.torusutils.types.common.PubNonce;
+import org.torusresearch.torusutils.types.common.SessionToken;
+import org.torusresearch.torusutils.types.common.TorusKey;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
+import org.web3j.crypto.Hash;
+
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyPair;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+import okhttp3.internal.http2.Header;
+
+public class NodeUtils {
+ private NodeUtils() {
+ }
+
+ public static KeyLookupResult getPubKeyOrKeyAssign(@NotNull String[] endpoints, @NotNull Web3AuthNetwork network, @NotNull String verifier, @NotNull String verifierId, @NotNull String legacyMetdadataHost, @Nullable Integer serverTimeOffset, @Nullable String extendedVerifierId) throws Exception {
+ int threshold = (endpoints.length / 2) + 1;
+
+ BigInteger timeOffset = BigInteger.ZERO;
+ if (serverTimeOffset != null) {
+ timeOffset = BigInteger.valueOf(serverTimeOffset);
+ }
+ timeOffset = timeOffset.add( new BigInteger(String.valueOf(System.currentTimeMillis() / 1000)));
+
+ GetOrSetKeyParams params = new GetOrSetKeyParams(true, verifier, verifierId, extendedVerifierId, true, true, timeOffset.toString());
+ List> lookupPromises = new ArrayList<>();
+ for (int i = 0; i < endpoints.length; i++) {
+ lookupPromises.add(i, APIUtils.post(endpoints[i], APIUtils.generateJsonRPCObject("GetPubKeyOrKeyAssign",
+ params), true));
+ }
+
+ ArrayList> collected = new ArrayList<>();
+
+ JsonRPCErrorInfo errResult = null;
+ KeyResult key = null;
+ List> lookupPubKeys = null;
+ GetOrSetNonceResult nonce = null;
+
+ Gson json = new Gson();
+ for (CompletableFuture lookup: lookupPromises) {
+ try {
+ String result = lookup.get();
+
+ @SuppressWarnings({"unchecked"}) // Due to Type Erasure of Generic Types at Runtime. Java does this to ensure code is compatible with pre-generic versions of Java.
+ JsonRPCResponse response = json.fromJson(result, JsonRPCResponse.class);
+ collected.add(response);
+ lookupPubKeys = collected.stream().filter(item -> item.getError() == null && item.getTypedResult(VerifierLookupResponse.class) != null).collect(Collectors.toList());
+ errResult = (JsonRPCErrorInfo) NodeUtils.thresholdSame(collected.stream().filter(item -> item.getError() != null).toArray(), threshold);
+ ArrayList normalizedKeys = new ArrayList<>();
+ for (JsonRPCResponse item : lookupPubKeys) {
+ VerifierLookupResponse vlr = item.getTypedResult(VerifierLookupResponse.class);
+ normalizedKeys.add(Common.normalizeKeyResult(vlr));
+ }
+ key = (KeyResult) NodeUtils.thresholdSame(normalizedKeys.toArray(), threshold);
+ if (key != null) {
+ break;
+ }
+ } catch (Exception e) {
+ collected.add(null);
+ }
+ }
+
+ if (key != null && nonce == null && extendedVerifierId == null && !TorusUtils.isLegacyNetorkRouteMap(network)) {
+ for (int i = 0; i < lookupPubKeys.size(); i++) {
+ JsonRPCResponse x1 = lookupPubKeys.get(i);
+ if (x1 != null && x1.getError() == null) {
+ VerifierLookupResponse x1Result = x1.getTypedResult(VerifierLookupResponse.class);
+ String currentNodePubKeyX = Common.padLeft(x1Result.keys[0].pub_key_X,'0',64).toLowerCase();
+ String thresholdPubKeyX = Common.padLeft(key.keys[0].pub_key_X,'0',64).toLowerCase();
+ if (x1Result.keys[0].nonce_data != null) {
+ PubNonce pubNonce = x1Result.keys[0].nonce_data.pubNonce;
+ if (pubNonce != null && currentNodePubKeyX.equals(thresholdPubKeyX)) {
+ nonce = x1Result.keys[0].nonce_data;
+ break;
+ }
+ }
+ }
+ }
+
+ if (nonce == null) {
+ nonce = MetadataUtils.getOrSetSapphireMetadataNonce(legacyMetdadataHost, network, key.keys[0].pub_key_X,key.keys[0].pub_key_Y, null, null, false, null);
+ if (nonce.nonce != null) {
+ nonce.nonce = null;
+ }
+ }
+ }
+
+ ArrayList serverTimeOffsets = new ArrayList<>();
+ ArrayList nodeIndexes = new ArrayList<>();
+ if (key != null && (nonce != null || extendedVerifierId != null || TorusUtils.isLegacyNetorkRouteMap(network) || errResult != null)) {
+ for (int i = 0; i < lookupPubKeys.size(); i++) {
+ JsonRPCResponse x1 = lookupPubKeys.get(i);
+ VerifierLookupResponse x1Result = x1.getTypedResult(VerifierLookupResponse.class);
+ if (x1 != null && x1Result != null) {
+ String currentNodePubKey = x1Result.keys[0].pub_key_X.toLowerCase();
+ String thresholdPubKey = key.keys[0].pub_key_X.toLowerCase();
+ if (currentNodePubKey.equals(thresholdPubKey)) {
+ if (x1Result.node_index != null)
+ {
+ nodeIndexes.add(Integer.valueOf(x1Result.node_index));
+ }
+ }
+ if (x1Result.server_time_offset != null) {
+ serverTimeOffsets.add(Integer.valueOf(x1Result.server_time_offset));
+ } else {
+ serverTimeOffsets.add(0);
+ }
+ }
+ }
+ }
+
+ Integer finalServerTimeOffset = 0;
+ if (key != null) {
+ finalServerTimeOffset = Common.calculateMedian(serverTimeOffsets);
+ }
+ return new KeyLookupResult(key, nodeIndexes, finalServerTimeOffset, nonce, errResult);
+ }
+
+ public static TorusKey retrieveOrImportShare(@NotNull String legacyMetadataHost, @Nullable Integer serverTimeOffset,
+ @NotNull Boolean enableOneKey, @NotNull String allowHost, @NotNull Web3AuthNetwork network,
+ @NotNull String clientId, @NotNull String[] endpoints, @NotNull String verifier, @NotNull VerifierParams verifierParams,
+ @NotNull String idToken, @Nullable ImportedShare[] importedShares, @NotNull String apiKey, @Nullable String newPrivateKey, @NotNull TorusUtilsExtraParams extraParams
+ ) throws Exception {
+ int threshold = (endpoints.length / 2) + 1;
+
+ try {
+ APIUtils.get(allowHost, new Header[]{new Header("x-api-key", apiKey), new Header("Origin", verifier), new Header("verifier", verifier), new Header("verifierid", verifierParams.verifier_id), new Header("network", network.name().toLowerCase()),
+ new Header("clientid", clientId), new Header("enablegating", "true")}, true).get();
+ } catch (Exception e) {
+ throw TorusUtilError.GATING_ERROR;
+ }
+
+ KeyPair sessionAuthKey = KeyUtils.generateKeyPair();
+ String sessionAuthKeySerialized = Common.padLeft(Hex.toHexString(KeyUtils.serializePrivateKey(sessionAuthKey.getPrivate())),'0', 64);
+ String pubKey = Hex.toHexString(KeyUtils.serializePublicKey(sessionAuthKey.getPublic(), false));
+ String[] pubKeyCoords = KeyUtils.getPublicKeyCoords(pubKey);
+ String pubKeyX = pubKeyCoords[0];
+ String pubKeyY = pubKeyCoords[1];
+ String tokenCommitment = Hash.sha3String(idToken);
+
+ boolean isImportShareReq = false;
+ int importedShareCount = 0;
+
+ if (importedShares != null && importedShares.length > 0) {
+ if (importedShares.length != endpoints.length) {
+ throw new Error("Invalid imported shares length");
+ }
+ isImportShareReq = true;
+ importedShareCount = importedShares.length;
+ }
+
+ int minRequiredCommitmments = (endpoints.length * 3 / 4) + 1;
+
+
+ List> CommitmentRequests = new ArrayList<>();
+
+ // make commitment requests to endpoints
+ for (int i = 0; i < endpoints.length; i++) {
+ CompletableFuture commitmentRequest = APIUtils.post(endpoints[i], APIUtils.generateJsonRPCObject("CommitmentRequest", new CommitmentRequestParams("mug00", tokenCommitment.replace("0x", ""), pubKeyX, pubKeyY, String.valueOf(System.currentTimeMillis()), verifier)), true);
+ CommitmentRequests.add(i, commitmentRequest);
+ }
+
+ List nodeSigs = new ArrayList<>();
+ int received = 0; // might need to be atomic
+
+ Gson json = new Gson();
+ for (CompletableFuture commitment : CommitmentRequests) {
+ try {
+ String result = commitment.get();
+ @SuppressWarnings({"unchecked"}) // Due to Type Erasure of Generic Types at Runtime. Java does this to ensure code is compatible with pre-generic versions of Java.
+ JsonRPCResponse response = json.fromJson(result, JsonRPCResponse.class);
+ if (response != null && response.getError() == null) {
+ nodeSigs.add(response.getTypedResult(CommitmentRequestResult.class));
+ received++;
+ if (!isImportShareReq) {
+ if (received >= minRequiredCommitmments) {
+ break;
+ }
+ }
+ } else {
+ if (isImportShareReq) {
+ // cannot continue. all must pass for import
+ break;
+ }
+ }
+ } catch (Exception e) {
+ if (isImportShareReq) {
+ // cannot continue. all must pass for import
+ break;
+ }
+ }
+ }
+
+ if (importedShareCount > 0 && (nodeSigs.size() != endpoints.length)) {
+ throw TorusUtilError.COMMITMENT_REQUEST_FAILED;
+ }
+
+ GetOrSetNonceResult thresholdNonceData = null;
+ boolean shareImportSuccess = false;
+
+ List shareResponses = new ArrayList<>();
+ PubKey thresholdPublicKey = null;
+
+ String clientTime = String.valueOf((serverTimeOffset == null) ? 0 : serverTimeOffset) + (System.currentTimeMillis() / 1000L);
+
+ if (isImportShareReq) {
+ ArrayList importedItems = new ArrayList<>();
+ for (int j = 0; j < endpoints.length; j++) {
+ ImportedShare importShare = importedShares[j];
+
+ ShareRequestItem shareRequestItem = new ShareRequestItem(verifier, verifierParams.verifier_id, verifierParams.extended_verifier_id,
+ idToken, extraParams, nodeSigs.toArray(new CommitmentRequestResult[0]), importShare.oauth_pub_key_x, importShare.oauth_pub_key_y,
+ importShare.signing_pub_key_x, importShare.signing_pub_key_y, importShare.encryptedShare,
+ importShare.encryptedShareMetadata, importShare.node_index, importShare.key_type,
+ importShare.nonce_data, importShare.nonce_signature, verifierParams.sub_verifier_ids, verifierParams.verify_params, endpoints[j]
+ );
+ importedItems.add(shareRequestItem);
+ }
+ String req = APIUtils.generateJsonRPCObject("ImportShares", new ShareRequestParams(importedItems.toArray(new ShareRequestItem[0]), clientTime));
+ String result = APIUtils.post(endpoints[NodeUtils.getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id)], req, true).get();
+ @SuppressWarnings({"unchecked"}) // Due to Type Erasure of Generic Types at Runtime. Java does this to ensure code is compatible with pre-generic versions of Java.
+ JsonRPCResponse response = json.fromJson(result, JsonRPCResponse.class);
+ if (response != null && response.getError() == null) {
+ shareImportSuccess = true;
+ }
+
+ if (isImportShareReq && !shareImportSuccess) {
+ throw TorusUtilError.IMPORT_SHARE_FAILED;
+ }
+
+ ShareRequestResult[] shares = response.getTypedResult(ShareRequestResult[].class);
+ shareResponses.addAll(Arrays.asList(shares));
+ thresholdPublicKey = NodeUtils.thresholdSame(Arrays.stream(shares).filter(item -> item.keys.length > 0).map(item -> item.keys[0].public_key).toArray(PubKey[]::new), threshold);
+ } else {
+ ArrayList> shareRequests = new ArrayList<>();
+ for (String endpoint : endpoints) {
+ ShareRequestItem shareRequestItem = new ShareRequestItem(verifier, verifierParams.verifier_id, verifierParams.extended_verifier_id,
+ idToken, extraParams, nodeSigs.toArray(new CommitmentRequestResult[0]), null, null,
+ null, null, null,
+ null, null, null,
+ null, null, verifierParams.sub_verifier_ids, verifierParams.verify_params, null);
+
+ List shareRequestItems = new ArrayList<>();
+ shareRequestItems.add(shareRequestItem);
+ String req = APIUtils.generateJsonRPCObject("GetShareOrKeyAssign", new ShareRequestParams(shareRequestItems.toArray(new ShareRequestItem[0]), clientTime));
+ shareRequests.add(APIUtils.post(endpoint, req, true));
+ }
+
+ for (CompletableFuture item : shareRequests) {
+ try {
+ @SuppressWarnings({"unchecked"}) // Due to Type Erasure of Generic Types at Runtime. Java does this to ensure code is compatible with pre-generic versions of Java.
+ JsonRPCResponse response = json.fromJson(item.get(), JsonRPCResponse.class);
+
+ if (response != null && response.getError() == null) {
+ shareResponses.add(response.getTypedResult(ShareRequestResult.class));
+ }
+
+ thresholdPublicKey = NodeUtils.thresholdSame(shareResponses.stream().filter(res -> res.keys.length > 0).map(res -> res.keys[0].public_key).toArray(PubKey[]::new), threshold);
+
+ if (thresholdPublicKey != null) {
+ break;
+ }
+ } catch (Exception e) {
+ // Continue to try next result
+ }
+ }
+ }
+
+ if (thresholdPublicKey == null) {
+ throw TorusUtilError.RETRIEVE_OR_IMPORT_SHARE_ERROR;
+ }
+
+ ArrayList serverTimeOffsets = new ArrayList<>();
+
+ for (ShareRequestResult item : shareResponses) {
+ if (thresholdNonceData == null && verifierParams.extended_verifier_id == null) {
+ String currentPubKeyX = Common.padLeft(item.keys[0].public_key.getX(), '0', 64);
+ String thresholdPubKeyX = Common.padLeft(thresholdPublicKey.getX(), '0', 64);
+ if (item.keys[0].nonce_data != null) {
+ GetOrSetNonceResult pubnonce = item.keys[0].nonce_data;
+ if (pubnonce != null && currentPubKeyX.equalsIgnoreCase(thresholdPubKeyX)) {
+ thresholdNonceData = pubnonce;
+ }
+ }
+ }
+
+ serverTimeOffsets.add((item.server_time_offset != null && !item.server_time_offset.isEmpty()) ? item.server_time_offset : "0");
+ }
+
+ List serverOffsetTimes = serverTimeOffsets.stream().map(Integer::parseInt).collect(Collectors.toList());
+ Integer serverOffsetResponse = (serverTimeOffset != null) ? serverTimeOffset : Common.calculateMedian(serverOffsetTimes);
+
+ if (thresholdNonceData == null && verifierParams.extended_verifier_id == null && !TorusUtils.isLegacyNetorkRouteMap(network)) {
+ thresholdNonceData = MetadataUtils.getOrSetSapphireMetadataNonce(legacyMetadataHost, network, thresholdPublicKey.getX(), thresholdPublicKey.getY(), serverOffsetResponse, null, false, null);
+ }
+
+ int thresholdReqCount = (importedShares != null && importedShares.length > 0) ? endpoints.length : threshold;
+
+ if (!(shareResponses.size() >= thresholdReqCount && thresholdPublicKey != null && (thresholdNonceData != null || verifierParams.extended_verifier_id != null || TorusUtils.isLegacyNetorkRouteMap(network)))) {
+ throw TorusUtilError.RETRIEVE_OR_IMPORT_SHARE_ERROR;
+ }
+
+ ArrayList shares = new ArrayList<>();
+ ArrayList sessionTokenSigs = new ArrayList<>();
+ ArrayList sessionTokens = new ArrayList<>();
+ ArrayList nodeIndexes = new ArrayList<>();
+ ArrayList sessionTokenDatas = new ArrayList<>();
+ ArrayList isNewKeys = new ArrayList<>();
+
+ for (ShareRequestResult item : shareResponses) {
+ isNewKeys.add(item.is_new_key.toString());
+
+ if (item.session_token_sigs != null && item.session_token_sigs.length > 0) {
+ if (item.session_token_sig_metadata != null && item.session_token_sig_metadata.length > 0) {
+ String decrypted = MetadataUtils.decryptNodeData(item.session_token_sig_metadata[0], item.session_token_sigs[0], sessionAuthKeySerialized);
+ sessionTokenSigs.add(decrypted);
+ } else {
+ sessionTokenSigs.add(item.session_token_sigs[0]);
+ }
+ }
+
+ if (item.session_token_sigs != null && item.session_tokens.length > 0) {
+ if (item.session_token_metadata != null && item.session_token_metadata.length > 0) {
+ String decrypted = MetadataUtils.decryptNodeData(item.session_token_metadata[0], item.session_tokens[0], sessionAuthKeySerialized);
+ sessionTokens.add(decrypted);
+ } else {
+ sessionTokens.add(item.session_tokens[0]);
+ }
+ }
+
+ if (item.keys.length > 0) {
+ KeyAssignment latestKey = item.keys[0];
+ nodeIndexes.add(latestKey.node_index);
+ String decoded = new String(Base64.getDecoder().decode(latestKey.share.getBytes(StandardCharsets.UTF_8)));
+ String decryped = MetadataUtils.decryptNodeData(latestKey.share_metadata, decoded, sessionAuthKeySerialized);
+ shares.add(decryped);
+ }
+ }
+
+ if (verifierParams.extended_verifier_id == null && sessionTokenSigs.size() < threshold) {
+ throw TorusUtilError.RETRIEVE_OR_IMPORT_SHARE_ERROR;
+ }
+
+ if (verifierParams.extended_verifier_id == null && sessionTokens.size() < threshold) {
+ throw TorusUtilError.RUNTIME_ERROR("Insufficient number of signatures from nodes");
+ }
+
+ for (int i = 0; i < sessionTokens.size(); i++) {
+ String token = sessionTokens.get(i);
+ if (token != null) {
+ // decode token, can be either hex or base64
+ try {
+ byte[] tokenBytes = Hex.decode(token);
+ String tokenBase64 = Base64.getEncoder().encodeToString(tokenBytes);
+ sessionTokenDatas.add(new SessionToken(tokenBase64, sessionTokenSigs.get(i), shareResponses.get(i).node_pubx, shareResponses.get(i).node_puby));
+ } catch (Exception e) {
+ sessionTokenDatas.add(new SessionToken(token, sessionTokenSigs.get(i), shareResponses.get(i).node_pubx, shareResponses.get(i).node_puby));
+ }
+ }
+ }
+
+ Map decryptedShares = new HashMap<>();
+ for (int i = 0; i < shares.size(); i++) {
+ if (shares.get(i) != null) {
+ decryptedShares.put(nodeIndexes.get(i), shares.get(i));
+ }
+ }
+
+ List elements = new ArrayList<>();
+ for (int i = 0; i <= Collections.max(decryptedShares.keySet()); i++) {
+ elements.add(i);
+ }
+
+ List> allCombis = Common.kCombinations(elements, threshold);
+
+ BigInteger privateKey = null;
+ for (int j = 0; j < allCombis.size(); j++) {
+ List currentCombi = allCombis.get(j);
+ Map currentCombiShares = decryptedShares.entrySet().stream().filter(entry -> currentCombi.contains(entry.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+ BigInteger derivedPrivateKey = Lagrange.lagrangeInterpolation(new ArrayList<>(currentCombiShares.values()).stream().map(cs -> new BigInteger(cs, 16)).toArray(BigInteger[]::new), new ArrayList<>(currentCombiShares.keySet()).stream().map(is -> new BigInteger(String.valueOf(is))).toArray(BigInteger[]::new));
+ if (derivedPrivateKey == null) {
+ continue;
+ }
+ String decryptedPublicKey = KeyUtils.privateToPublic(derivedPrivateKey);
+ String[] derivedPublicKeyCoords = KeyUtils.getPublicKeyCoords(decryptedPublicKey);
+ String thresholdPubKeyX = Common.padLeft(thresholdPublicKey.getX(), '0', 64);
+ String thresholdPubKeyY = Common.padLeft(thresholdPublicKey.getY(), '0', 64);
+ if (derivedPublicKeyCoords[0].equalsIgnoreCase(thresholdPubKeyX) && derivedPublicKeyCoords[1].equalsIgnoreCase(thresholdPubKeyY)) {
+ privateKey = derivedPrivateKey;
+ break;
+ }
+ }
+
+ if (privateKey == null) {
+ throw TorusUtilError.PRIVATE_KEY_DERIVE_FAILED;
+ }
+
+ String thesholdIsNewKey = thresholdSame(isNewKeys.toArray(new String[0]), threshold);
+
+ String oAuthKey = Common.padLeft(privateKey.toString(16), '0', 64);
+ String oAuthPublicKey = KeyUtils.privateToPublic(privateKey);
+ String[] oAuthPublicKeyCoords = KeyUtils.getPublicKeyCoords(oAuthPublicKey);
+ BigInteger metadataNonce = (thresholdNonceData != null && thresholdNonceData.nonce != null) ? new BigInteger(Common.padLeft(thresholdNonceData.nonce, '0', 64), 16) : BigInteger.ZERO;
+ String finalPublicKey;
+ PubNonce pubNonce = null;
+ TypeOfUser typeOfUser = TypeOfUser.v1;
+
+ if (verifierParams.extended_verifier_id != null) {
+ typeOfUser = TypeOfUser.v2;
+ finalPublicKey = oAuthPublicKey;
+ } else if (TorusUtils.isLegacyNetorkRouteMap(network)) {
+ if (enableOneKey) {
+ Boolean isNewKey = (!(thesholdIsNewKey != null && thesholdIsNewKey.equalsIgnoreCase("true")));
+ GetOrSetNonceResult nonce = MetadataUtils.getOrSetNonce(legacyMetadataHost, thresholdPublicKey.getX(), thresholdPublicKey.getY(), serverOffsetResponse, oAuthKey, isNewKey, null);
+ metadataNonce = (nonce.nonce != null) ? new BigInteger(Common.padLeft(nonce.nonce, '0', 64), 16) : BigInteger.ZERO;
+ typeOfUser = (nonce.typeOfUser != null) ? nonce.typeOfUser : TypeOfUser.v1;
+
+ if (typeOfUser == TypeOfUser.v2) {
+ pubNonce = nonce.pubNonce;
+ if (pubNonce != null && !pubNonce.x.isEmpty() && !pubNonce.y.isEmpty()) {
+ String pubNonceKey = KeyUtils.getPublicKeyFromCoords(pubNonce.x, pubNonce.y, true);
+ finalPublicKey = KeyUtils.combinePublicKeysFromStrings(Arrays.asList(oAuthPublicKey, pubNonceKey), false);
+ } else {
+ throw TorusUtilError.RUNTIME_ERROR("Public nonce is missing");
+ }
+ } else {
+ typeOfUser = TypeOfUser.v1;
+ metadataNonce = new BigInteger(Common.padLeft(MetadataUtils.getMetadata(legacyMetadataHost, new GetMetadataParams(oAuthPublicKeyCoords[0], oAuthPublicKeyCoords[1])).message, '0', 64), 16);
+ BigInteger privateKeyWithNonce = new BigInteger(Common.padLeft(oAuthKey, '0', 64), 16).add(metadataNonce);
+ finalPublicKey = KeyUtils.privateToPublic(privateKeyWithNonce);
+ }
+ } else {
+ // typeOfUser = TypeOfUser.v1; Already assigned previously, left here for clarity
+ metadataNonce = new BigInteger(Common.padLeft(MetadataUtils.getMetadata(legacyMetadataHost, new GetMetadataParams(oAuthPublicKeyCoords[0], oAuthPublicKeyCoords[1])).message, '0', 64), 16);
+ BigInteger privateKeyWithNonce = new BigInteger(Common.padLeft(oAuthKey, '0', 64), 16).add(metadataNonce);
+ finalPublicKey = KeyUtils.privateToPublic(privateKeyWithNonce);
+ }
+ } else {
+ typeOfUser = TypeOfUser.v2;
+ finalPublicKey = oAuthPublicKey;
+ if (thresholdNonceData != null && thresholdNonceData.pubNonce != null && (!(thresholdNonceData.pubNonce.x.isEmpty() || thresholdNonceData.pubNonce.y.isEmpty()))) {
+ PubNonce pubNonceObject = thresholdNonceData.pubNonce;
+ String pubNonceKey = KeyUtils.getPublicKeyFromCoords(pubNonceObject.x, pubNonceObject.y, true);
+ finalPublicKey = KeyUtils.combinePublicKeysFromStrings(Arrays.asList(oAuthPublicKey, pubNonceKey), false);
+ pubNonce = pubNonceObject;
+ } else {
+ throw TorusUtilError.PUB_NONCE_MISSING;
+ }
+ }
+
+ if (finalPublicKey == null) {
+ throw TorusUtilError.RETRIEVE_OR_IMPORT_SHARE_ERROR;
+ }
+
+ String oAuthKeyAddress = KeyUtils.generateAddressFromPubKey(oAuthPublicKeyCoords[0], oAuthPublicKeyCoords[1]);
+ String[] finalPubKeyCoords = KeyUtils.getPublicKeyCoords(finalPublicKey);
+
+ String finalEvmAddress = KeyUtils.generateAddressFromPubKey(finalPubKeyCoords[0], finalPubKeyCoords[1]);
+
+ String finalPrivKey = "";
+
+ if (typeOfUser == TypeOfUser.v1 || (typeOfUser == TypeOfUser.v2 && metadataNonce.compareTo(BigInteger.ZERO) > 0)) {
+ BigInteger privateKeyWithNonce = privateKey.add(metadataNonce).mod(getOrderOfCurve());
+ finalPrivKey = Common.padLeft(privateKeyWithNonce.toString(16), '0', 64);
+
+ }
+
+ // This is a sanity check to make doubly sure we are returning the correct private key after importing a share
+ if (isImportShareReq) {
+ if (newPrivateKey == null) {
+ throw TorusUtilError.RETRIEVE_OR_IMPORT_SHARE_ERROR;
+ } else {
+ if (!finalPrivKey.equalsIgnoreCase(Common.padLeft(newPrivateKey, '0', 64))) {
+ throw TorusUtilError.RETRIEVE_OR_IMPORT_SHARE_ERROR;
+ }
+ }
+ }
+
+ Boolean isUpgraded = null;
+
+ if (typeOfUser == TypeOfUser.v2) {
+ isUpgraded = metadataNonce.equals(BigInteger.ZERO);
+ }
+
+ return new TorusKey(
+ new FinalKeyData(finalEvmAddress, finalPubKeyCoords[0], finalPubKeyCoords[1], finalPrivKey),
+ new OAuthKeyData(oAuthKeyAddress, oAuthPublicKeyCoords[0], oAuthPublicKeyCoords[1], oAuthKey),
+ new SessionData(sessionTokenDatas, sessionAuthKeySerialized),
+ new Metadata(pubNonce, metadataNonce, typeOfUser, isUpgraded, serverOffsetResponse),
+ new NodesData(nodeIndexes));
+ }
+
+ public static T thresholdSame(@NotNull T[] arr, int threshold) throws JsonProcessingException {
+ HashMap hashMap = new HashMap<>();
+ for (T s : arr) {
+ ObjectMapper objectMapper = new ObjectMapper()
+ .configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
+ String value = objectMapper.writeValueAsString(s);
+ Integer index = hashMap.get(value);
+ if (index != null) {
+ hashMap.put(value, index+1);
+ } else {
+ hashMap.put(value, 0);
+ }
+ if (hashMap.get(value) != null && hashMap.get(value) == threshold) {
+ return s;
+ }
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ public static String thresholdSame(@NotNull List list, int threshold) throws JsonProcessingException {
+ String[] arr = new String[list.size()];
+ list.toArray(arr);
+ return NodeUtils.thresholdSame(arr, threshold);
+ }
+
+ public static int getProxyCoordinatorEndpointIndex(@NotNull String[] endpoints, @NotNull String verifier, @NotNull String verifierId) {
+ String verifierIdString = verifier + verifierId;
+ String hashedVerifierId = Hash.sha3(verifierIdString).replace("0x", "");
+ BigInteger proxyEndPointNum = new BigInteger(hashedVerifierId, 16).mod(BigInteger.valueOf(endpoints.length));
+ return proxyEndPointNum.intValue();
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/Predicate.java b/src/main/java/org/torusresearch/torusutils/helpers/Predicate.java
deleted file mode 100644
index e25065a..0000000
--- a/src/main/java/org/torusresearch/torusutils/helpers/Predicate.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.torusresearch.torusutils.helpers;
-
-import java.util.concurrent.CompletableFuture;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public interface Predicate {
- CompletableFuture call(String[] resultArr, AtomicBoolean resolved) throws PredicateFailedException;
-}
\ No newline at end of file
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/PredicateFailedException.java b/src/main/java/org/torusresearch/torusutils/helpers/PredicateFailedException.java
deleted file mode 100644
index 1c7e815..0000000
--- a/src/main/java/org/torusresearch/torusutils/helpers/PredicateFailedException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.torusresearch.torusutils.helpers;
-
-import java.util.concurrent.CompletionException;
-
-public class PredicateFailedException extends CompletionException {
- public PredicateFailedException(String errMessage) {
- super(errMessage);
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/Some.java b/src/main/java/org/torusresearch/torusutils/helpers/Some.java
deleted file mode 100644
index 553ae0a..0000000
--- a/src/main/java/org/torusresearch/torusutils/helpers/Some.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.torusresearch.torusutils.helpers;
-
-import org.torusresearch.torusutils.types.SomeException;
-
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-
-public class Some {
- private final AtomicInteger finishedCount = new AtomicInteger(0);
- private final String[] resultArr;
- private final String[] errorArr;
- private final CompletableFuture completableFuture;
- private final AtomicBoolean resolved = new AtomicBoolean(false);
- private final AtomicReference predicateError = new AtomicReference<>("");
-
- public Some(List> promises, Predicate predicate) {
- resultArr = new String[promises.size()];
- errorArr = new String[promises.size()];
- completableFuture = new CompletableFuture<>();
- for (int i = 0; i < promises.size(); i++) {
- int index = i;
- promises.get(index).whenCompleteAsync((response, e) -> {
- int count = finishedCount.incrementAndGet();
- if (e != null) {
- errorArr[index] = e.getMessage();
- // swallow exceptions due to threshold assumptions
- if (count == promises.size() && !completableFuture.isDone() && !resolved.get()) {
- completableFuture.completeExceptionally(new SomeException(errorArr, resultArr, predicateError.get()));
- }
- return;
- }
- resultArr[index] = response;
- if (resolved.get()) {
- return;
- }
- try {
- T intermediateResult = predicate.call(resultArr.clone(), resolved).get();
- resolved.set(true);
- completableFuture.complete(intermediateResult);
- } catch (Exception e2) {
- predicateError.set(e2.getMessage());
- // swallow exceptions due to threshold assumptions
- // if none of the predicates succeed, we throw at the end
- if (count == promises.size() && !completableFuture.isDone() && !resolved.get()) {
- completableFuture.completeExceptionally(new SomeException(errorArr, resultArr, predicateError.get()));
- }
- }
- });
- }
- }
-
- public CompletableFuture getCompletableFuture() {
- return completableFuture;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/TorusUtilError.java b/src/main/java/org/torusresearch/torusutils/helpers/TorusUtilError.java
new file mode 100644
index 0000000..50befb6
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/helpers/TorusUtilError.java
@@ -0,0 +1,49 @@
+package org.torusresearch.torusutils.helpers;
+
+import org.jetbrains.annotations.NotNull;
+
+public class TorusUtilError extends Exception {
+
+ // Define error cases
+ public static final TorusUtilError CONFIGURATION_ERROR = new TorusUtilError("SDK Configuration incorrect. Network is probably incorrect");
+ public static final TorusUtilError COMMITMENT_REQUEST_FAILED = new TorusUtilError("commitment request failed");
+ public static final TorusUtilError DECRYPTION_FAILED = new TorusUtilError("Decryption Failed");
+ public static final TorusUtilError ENCODING_FAILED = new TorusUtilError("Could not encode data");
+ public static final TorusUtilError DECODING_FAILED = new TorusUtilError("JSON Decoding error");
+ public static final TorusUtilError IMPORT_SHARE_FAILED = new TorusUtilError("import share failed");
+ public static final TorusUtilError PRIVATE_KEY_DERIVE_FAILED = new TorusUtilError("could not derive private key");
+ public static final TorusUtilError INTERPOLATION_FAILED = new TorusUtilError("lagrange interpolation failed");
+ public static final TorusUtilError INVALID_KEY_SIZE = new TorusUtilError("Invalid key size. Expected 32 bytes");
+ public static final TorusUtilError INVALID_PUB_KEY_SIZE = new TorusUtilError("Invalid key size. Expected 64 bytes");
+ public static final TorusUtilError INVALID_INPUT = new TorusUtilError("Input was found to be invalid");
+
+ public static TorusUtilError RUNTIME_ERROR(@NotNull String msg) {
+ return new TorusUtilError(msg);
+ }
+ public static final TorusUtilError RETRIEVE_OR_IMPORT_SHARE_ERROR = new TorusUtilError("retrieve or import share failed");
+ public static final TorusUtilError METADATA_NONCE_MISSING = new TorusUtilError("Unable to fetch metadata nonce");
+ public static final TorusUtilError GATING_ERROR = new TorusUtilError("could not process request");
+ public static final TorusUtilError PUB_NONCE_MISSING = new TorusUtilError("public nonce is missing");
+
+ private final String message;
+
+ public TorusUtilError(@NotNull String message) {
+ super(message);
+ this.message = message;
+ }
+
+ @Override
+ public String toString() {
+ return message;
+ }
+
+ @SuppressWarnings("unused")
+ public String debugDescription() {
+ return message;
+ }
+
+ public String getLocalizedMessage() {
+ return message;
+ }
+}
+
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/Utils.java b/src/main/java/org/torusresearch/torusutils/helpers/Utils.java
deleted file mode 100644
index de96588..0000000
--- a/src/main/java/org/torusresearch/torusutils/helpers/Utils.java
+++ /dev/null
@@ -1,251 +0,0 @@
-package org.torusresearch.torusutils.helpers;
-
-import com.google.gson.Gson;
-
-import org.torusresearch.fetchnodedetails.types.TorusNodePub;
-import org.torusresearch.torusutils.apis.APIUtils;
-import org.torusresearch.torusutils.apis.JsonRPCResponse;
-import org.torusresearch.torusutils.apis.KeyAssignParams;
-import org.torusresearch.torusutils.apis.KeyLookupResult;
-import org.torusresearch.torusutils.apis.SignerResponse;
-import org.torusresearch.torusutils.apis.VerifierLookupRequestParams;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.CompletableFuture;
-
-import okhttp3.internal.http2.Header;
-
-public class Utils {
- private Utils() {
- }
-
- public static String thresholdSame(String[] arr, int threshold) {
- HashMap hashMap = new HashMap<>();
- for (String s : arr) {
- Integer currentCount = hashMap.get(s);
- if (currentCount == null) currentCount = 0;
- int incrementedCount = currentCount + 1;
- if (incrementedCount == threshold) {
- return s;
- }
- hashMap.put(s, currentCount + 1);
- }
- return null;
- }
-
- public static String thresholdSame(List list, int threshold) {
- String[] arr = new String[list.size()];
- list.toArray(arr);
- return Utils.thresholdSame(arr, threshold);
- }
-
- public static List> kCombinations(int s, int k) {
- List set = new ArrayList<>();
- for (int i = 0; i < s; i++) {
- set.add(i);
- }
- return kCombinations(set, k);
- }
-
- public static List> kCombinations(List set, int k) {
- List> combs = new ArrayList<>();
- if (k > set.size()) {
- return combs;
- }
- if (k == set.size()) {
- combs.add(set);
- return combs;
- }
- if (k == 1) {
- for (Integer i : set) {
- ArrayList arrList = new ArrayList<>();
- arrList.add(i);
- combs.add(arrList);
- }
- return combs;
- }
- for (int i = 0; i < set.size() - k + 1; i++) {
- List> tailCombs = Utils.kCombinations(set.subList(i + 1, set.size()), k - 1);
- for (List tailComb : tailCombs) {
- List prependedComb = new ArrayList<>();
- prependedComb.add(set.get(i));
- prependedComb.addAll(tailComb);
- combs.add(prependedComb);
- }
- }
- return combs;
- }
-
- public static CompletableFuture waitKeyLookup(String[] endpoints, String verifier, String verifierId, int timeout) {
- CompletableFuture completableFuture = new CompletableFuture<>();
- try {
- Thread.sleep(timeout);
- } catch (InterruptedException e) {
- completableFuture.completeExceptionally(e);
- }
- Utils.keyLookup(endpoints, verifier, verifierId).whenComplete((res, err) -> {
- if (err != null) {
- completableFuture.completeExceptionally(err);
- }
- completableFuture.complete(res);
- });
- return completableFuture;
- }
-
- public static CompletableFuture keyLookup(String[] endpoints, String verifier, String verifierId) {
- int k = endpoints.length / 2 + 1;
- List> lookupPromises = new ArrayList<>();
- for (int i = 0; i < endpoints.length; i++) {
- lookupPromises.add(i, APIUtils.post(endpoints[i], APIUtils.generateJsonRPCObject("VerifierLookupRequest", new VerifierLookupRequestParams(verifier, verifierId)), false));
- }
- return new Some<>(lookupPromises, (lookupResults, resolved) -> {
- try {
- List errorResults = new ArrayList<>();
- List keyResults = new ArrayList<>();
- Gson gson = new Gson();
- for (String x : lookupResults) {
- if (x != null && !x.equals("")) {
- try {
- JsonRPCResponse response = gson.fromJson(x, JsonRPCResponse.class);
- keyResults.add(Utils.convertToJsonObject(response.getResult()));
- } catch (Exception e) {
- keyResults.add("");
- }
- }
- }
- for (String x : lookupResults) {
- if (x != null && !x.equals("")) {
- try {
- JsonRPCResponse response = gson.fromJson(x, JsonRPCResponse.class);
- errorResults.add(response.getError().getData());
- } catch (Exception e) {
- errorResults.add("");
- }
- }
- }
- String errorResult = thresholdSame(errorResults, k);
- String keyResult = thresholdSame(keyResults, k);
- if ((errorResult != null && !errorResult.equals("")) || (keyResult != null && !keyResult.equals(""))) {
- return CompletableFuture.completedFuture(new KeyLookupResult(keyResult, errorResult));
- }
- CompletableFuture failedFuture = new CompletableFuture<>();
- failedFuture.completeExceptionally(new Exception("invalid results from KeyLookup " + gson.toJson(lookupResults)));
- return failedFuture;
- } catch (Exception e) {
- return null;
- }
- }).getCompletableFuture();
- }
-
- public static CompletableFuture keyAssign(String[] endpoints, TorusNodePub[] torusNodePubs, Integer lastPoint, Integer firstPoint, String verifier, String verifierId, String signerHost, String network) {
- Integer nodeNum, initialPoint = null;
- CompletableFuture completableFuture = new CompletableFuture<>();
-
- if (lastPoint == null) {
- nodeNum = new Random().nextInt(endpoints.length);
- initialPoint = nodeNum;
- } else {
- nodeNum = lastPoint % endpoints.length;
- }
- if (nodeNum.equals(firstPoint)) {
- completableFuture.completeExceptionally(new Exception("Looped through all. No node available for key assignment"));
- return completableFuture;
- }
- if (firstPoint != null) {
- initialPoint = firstPoint;
- }
- String data = APIUtils.generateJsonRPCObject("KeyAssign", new KeyAssignParams(verifier, verifierId));
- Header[] headers = new Header[3];
- headers[0] = new Header("pubkeyx", torusNodePubs[nodeNum].getX());
- headers[1] = new Header("pubkeyy", torusNodePubs[nodeNum].getY());
- headers[2] = new Header("network", network);
- Integer finalInitialPoint = initialPoint;
- CompletableFuture apir = APIUtils.post(signerHost, data, headers, true);
- apir.whenCompleteAsync((signedData, err) -> {
- if (err != null) {
- // if signer fails, we just return
- completableFuture.completeExceptionally(err);
- return;
- }
- try {
- Gson gson = new Gson();
- SignerResponse signerResponse = gson.fromJson(signedData, SignerResponse.class);
- Header[] signerHeaders = new Header[3];
- if (signerResponse.getTorus_timestamp() == null || signerResponse.getTorus_nonce() == null || signerResponse.getTorus_signature() == null) {
- completableFuture.completeExceptionally(new Exception("Invalid signer response. Please retry!"));
- return;
- }
- signerHeaders[0] = new Header("torus-timestamp", signerResponse.getTorus_timestamp());
- signerHeaders[1] = new Header("torus-nonce", signerResponse.getTorus_nonce());
- signerHeaders[2] = new Header("torus-signature", signerResponse.getTorus_signature());
-
- CompletableFuture cf = APIUtils.post(endpoints[nodeNum], data, signerHeaders, false);
- cf.whenCompleteAsync((resp, keyAssignErr) -> {
- try {
- // we only retry if keyassign api fails..
- // All other cases, we just complete exceptionally
- if (keyAssignErr != null) {
- Utils.keyAssign(endpoints, torusNodePubs, nodeNum + 1, finalInitialPoint, verifier, verifierId, signerHost, network).whenCompleteAsync((res2, err2) -> {
- if (err2 != null) {
- completableFuture.completeExceptionally(err2);
- return;
- }
- completableFuture.complete(res2);
- });
- return;
- }
- JsonRPCResponse jsonRPCResponse = gson.fromJson(resp, JsonRPCResponse.class);
- String result = jsonRPCResponse.getResult().toString();
- if (result != null && !result.equals("")) {
- completableFuture.complete(new KeyLookupResult(result, null));
- } else {
- Utils.keyAssign(endpoints, torusNodePubs, nodeNum + 1, finalInitialPoint, verifier, verifierId, signerHost, network).whenCompleteAsync((res2, err2) -> {
- if (err2 != null) {
- completableFuture.completeExceptionally(err2);
- return;
- }
- completableFuture.complete(res2);
- });
- }
- } catch (Exception ex) {
- completableFuture.completeExceptionally(ex);
- }
- });
- } catch (Exception e) {
- completableFuture.completeExceptionally(e);
- }
- });
- return completableFuture;
-
- }
-
- public static boolean isEmpty(final CharSequence cs) {
- return cs == null || cs.length() == 0;
- }
-
- public static String padLeft(String inputString, Character padChar, int length) {
- if (inputString.length() >= length) return inputString;
- StringBuilder sb = new StringBuilder();
- while (sb.length() < length - inputString.length()) {
- sb.append(padChar);
- }
- sb.append(inputString);
- return sb.toString();
- }
-
- public static String stripPaddingLeft(String inputString, Character padChar) {
- StringBuilder sb = new StringBuilder(inputString);
- while (sb.length() > 1 && sb.charAt(0) == padChar) {
- sb.deleteCharAt(0);
- }
- return sb.toString();
- }
-
- public static String convertToJsonObject(Object obj) {
- Gson gson = new Gson();
- return obj == null ? "" : gson.toJson(obj);
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/encryption/Encryption.java b/src/main/java/org/torusresearch/torusutils/helpers/encryption/Encryption.java
new file mode 100644
index 0000000..0f77888
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/helpers/encryption/Encryption.java
@@ -0,0 +1,82 @@
+package org.torusresearch.torusutils.helpers.encryption;
+
+import org.bouncycastle.crypto.digests.SHA256Digest;
+import org.bouncycastle.crypto.macs.HMac;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.encoders.Hex;
+import org.jetbrains.annotations.NotNull;
+import org.torusresearch.torusutils.helpers.KeyUtils;
+import org.torusresearch.torusutils.helpers.hashing.SHA512;
+import org.torusresearch.torusutils.types.common.ecies.Ecies;
+
+import java.io.ByteArrayOutputStream;
+import java.security.KeyPair;
+import java.security.Provider;
+import java.security.SecureRandom;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyAgreement;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+public class Encryption {
+ static final protected Provider provider = new BouncyCastleProvider();
+
+ public static byte[] ecdh (@NotNull byte[] dataPrv, @NotNull byte[] dataPub) throws Exception
+ {
+ KeyAgreement ka = KeyAgreement.getInstance("ECDH", provider);
+ ka.init(KeyUtils.deserializePrivateKey(dataPrv));
+ ka.doPhase(KeyUtils.deserializePublicKey(dataPub), true);
+ return ka.generateSecret();
+ }
+
+ public static Ecies encrypt(@NotNull byte[] publicKey, @NotNull String plaintext) throws Exception {
+ KeyPair ephemeral = KeyUtils.generateKeyPair();
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", provider);
+
+ SecureRandom random = new SecureRandom();
+ byte[] iv = new byte[16];
+ random.nextBytes(iv);
+
+ byte[] shared = ecdh(KeyUtils.serializePrivateKey(ephemeral.getPrivate()), publicKey);
+ byte[] hash = SHA512.digest(shared);
+ byte[] aesKey = new byte[32];
+ System.arraycopy(hash, 0, aesKey, 0, 32);
+ byte[] macKey = new byte[32];
+ System.arraycopy(hash, 32, macKey, 0, 32);
+ cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(aesKey, "AES"), new IvParameterSpec(iv));
+
+ byte[] cipherText = cipher.doFinal(Hex.decode(plaintext));
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ outputStream.write(iv); // 16 bytes
+ outputStream.write(publicKey); // 65 bytes
+ outputStream.write(cipherText);
+
+ byte[] dataToMac = outputStream.toByteArray();
+
+ HMac hmac = new HMac(new SHA256Digest());
+ hmac.init(new KeyParameter(macKey));
+ byte[] finalMac = new byte[hmac.getMacSize()];
+ hmac.update(dataToMac, 0, dataToMac.length);
+ hmac.doFinal(finalMac, 0);
+ return new Ecies(Hex.toHexString(iv), Hex.toHexString(KeyUtils.serializePublicKey(ephemeral.getPublic(),false)),Hex.toHexString(cipherText), Hex.toHexString(finalMac));
+ }
+
+ public static byte[] decrypt(@NotNull String privateKeyHex, @NotNull Ecies ecies) throws Exception {
+ byte[] shared = ecdh(Hex.decode(privateKeyHex), Hex.decode(ecies.ephemPublicKey));
+ byte[] sha512hash = SHA512.digest(shared);
+ SecretKeySpec aesKey = new SecretKeySpec(Arrays.copyOf(sha512hash, 32), "AES");
+
+ byte[] iv = Hex.decode(ecies.iv);
+ IvParameterSpec ivSpec = new IvParameterSpec(iv);
+
+ byte[] cipherText = Hex.decode(ecies.ciphertext);
+
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", provider);
+ cipher.init(Cipher.DECRYPT_MODE, aesKey, ivSpec);
+ return cipher.doFinal(cipherText);
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/helpers/SHA512.java b/src/main/java/org/torusresearch/torusutils/helpers/hashing/SHA512.java
similarity index 57%
rename from src/main/java/org/torusresearch/torusutils/helpers/SHA512.java
rename to src/main/java/org/torusresearch/torusutils/helpers/hashing/SHA512.java
index 415afb9..d579b47 100644
--- a/src/main/java/org/torusresearch/torusutils/helpers/SHA512.java
+++ b/src/main/java/org/torusresearch/torusutils/helpers/hashing/SHA512.java
@@ -1,10 +1,12 @@
-package org.torusresearch.torusutils.helpers;
+package org.torusresearch.torusutils.helpers.hashing;
+
+import org.jetbrains.annotations.NotNull;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHA512 {
- public static byte[] digest(byte[] buf) throws NoSuchAlgorithmException {
+ public static byte[] digest(@NotNull byte[] buf) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-512");
digest.update(buf);
return digest.digest();
diff --git a/src/main/java/org/torusresearch/torusutils/types/DecryptedShare.java b/src/main/java/org/torusresearch/torusutils/types/DecryptedShare.java
deleted file mode 100644
index 6a805ab..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/DecryptedShare.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-import java.math.BigInteger;
-
-public class DecryptedShare {
- private final BigInteger index;
- private final BigInteger value;
-
- public DecryptedShare(BigInteger _index, BigInteger _value) {
- index = _index;
- value = _value;
- }
-
- public BigInteger getIndex() {
- return index;
- }
-
- public BigInteger getValue() {
- return value;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/FinalKeyData.java b/src/main/java/org/torusresearch/torusutils/types/FinalKeyData.java
new file mode 100644
index 0000000..26ad98b
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/FinalKeyData.java
@@ -0,0 +1,19 @@
+package org.torusresearch.torusutils.types;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class FinalKeyData extends FinalPubKeyData {
+ @Nullable
+ private final String privKey;
+
+ public FinalKeyData(@NotNull String walletAddress, @NotNull String X, @NotNull String Y, @Nullable String privKey) {
+ super(walletAddress,X,Y);
+ this.privKey = privKey;
+ }
+
+ @Nullable
+ public String getPrivKey() {
+ return privKey;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/FinalPubKeyData.java b/src/main/java/org/torusresearch/torusutils/types/FinalPubKeyData.java
new file mode 100644
index 0000000..e739c4b
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/FinalPubKeyData.java
@@ -0,0 +1,28 @@
+package org.torusresearch.torusutils.types;
+
+import org.jetbrains.annotations.NotNull;
+
+public class FinalPubKeyData {
+
+ private final String walletAddress;
+ private final String x;
+ private final String y;
+
+ public FinalPubKeyData(@NotNull String walletAddress, @NotNull String x, @NotNull String y) {
+ this.walletAddress = walletAddress;
+ this.x = x;
+ this.y = y;
+ }
+
+ public String getWalletAddress() {
+ return walletAddress;
+ }
+
+ public String getX() {
+ return x;
+ }
+
+ public String getY() {
+ return y;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/GetOrSetNonceError.java b/src/main/java/org/torusresearch/torusutils/types/GetOrSetNonceError.java
deleted file mode 100644
index 7b6994c..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/GetOrSetNonceError.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-public class GetOrSetNonceError extends Exception {
- public GetOrSetNonceError(Exception e) {
- super(e);
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/GetOrSetNonceResult.java b/src/main/java/org/torusresearch/torusutils/types/GetOrSetNonceResult.java
deleted file mode 100644
index 34310ea..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/GetOrSetNonceResult.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-
-import org.jetbrains.annotations.Nullable;
-
-public class GetOrSetNonceResult {
- private final TypeOfUser typeOfUser;
- @Nullable
- private String nonce;
- @Nullable
- private PubNonce pubNonce;
- private boolean upgraded;
-
- public GetOrSetNonceResult(TypeOfUser typeOfUser) {
- this.typeOfUser = typeOfUser;
- }
-
- @Nullable
- public String getNonce() {
- return nonce;
- }
-
- public void setNonce(@Nullable String nonce) {
- this.nonce = nonce;
- }
-
- @Nullable
- public PubNonce getPubNonce() {
- return pubNonce;
- }
-
- public void setPubNonce(@Nullable PubNonce pubNonce) {
- this.pubNonce = pubNonce;
- }
-
- public boolean isUpgraded() {
- return upgraded;
- }
-
- public void setUpgraded(boolean upgraded) {
- this.upgraded = upgraded;
- }
-
- public TypeOfUser getTypeOfUser() {
- return typeOfUser;
- }
-
-
- public static class PubNonce {
- private final String x;
- private final String y;
-
- public PubNonce(String x, String y) {
- this.x = x;
- this.y = y;
- }
-
- public String getX() {
- return x;
- }
-
- public String getY() {
- return y;
- }
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/Metadata.java b/src/main/java/org/torusresearch/torusutils/types/Metadata.java
new file mode 100644
index 0000000..43ff3c5
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/Metadata.java
@@ -0,0 +1,57 @@
+package org.torusresearch.torusutils.types;
+
+import org.jetbrains.annotations.NotNull;
+import org.torusresearch.torusutils.types.common.PubNonce;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
+
+import java.math.BigInteger;
+
+import io.reactivex.annotations.Nullable;
+
+public class Metadata {
+
+ @Nullable
+ private final PubNonce pubNonce;
+ private final BigInteger nonce;
+ @Nullable
+ private final Boolean upgraded;
+ private final TypeOfUser typeOfUser;
+
+ private final Integer serverTimeOffset;
+
+ public Metadata(@Nullable PubNonce pubNonce, @NotNull BigInteger nonce, @NotNull TypeOfUser typeOfUser, @Nullable Boolean upgraded, @NotNull Integer serverTimeOffset) {
+ this.pubNonce = pubNonce;
+ this.nonce = nonce;
+ this.typeOfUser = typeOfUser;
+ this.upgraded = upgraded;
+ this.serverTimeOffset = serverTimeOffset;
+ }
+
+ public Metadata(@Nullable PubNonce pubNonce, @NotNull BigInteger nonce, @NotNull TypeOfUser typeOfUser, @NotNull Boolean upgraded) {
+ this.pubNonce = pubNonce;
+ this.nonce = nonce;
+ this.typeOfUser = typeOfUser;
+ this.upgraded = upgraded;
+ this.serverTimeOffset = 0;
+ }
+
+ public PubNonce getPubNonce() {
+ return pubNonce;
+ }
+
+ public BigInteger getNonce() {
+ return nonce;
+ }
+
+ public boolean isUpgraded() {
+ return upgraded;
+ }
+
+ public TypeOfUser getTypeOfUser() {
+ return typeOfUser;
+ }
+
+ public Integer getServerTimeOffset() {
+ return serverTimeOffset;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/MetadataParams.java b/src/main/java/org/torusresearch/torusutils/types/MetadataParams.java
deleted file mode 100644
index b459d8f..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/MetadataParams.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-public class MetadataParams extends MetadataPubKey {
- private final MetadataSetData set_data;
- private final String signature;
-
- public MetadataParams(String pub_key_X, String pub_key_Y, MetadataSetData set_data, String signature) {
- super(pub_key_X, pub_key_Y);
- this.set_data = set_data;
- this.signature = signature;
- }
-
- public MetadataSetData getSet_data() {
- return set_data;
- }
-
- public String getSignature() {
- return signature;
- }
-
- public static class MetadataSetData {
- private final String data;
- // timestamp in hex
- private final String timestamp;
-
- public MetadataSetData(String data, String timestamp) {
- this.data = data;
- this.timestamp = timestamp;
- }
-
- public String getData() {
- return data;
- }
-
- public String getTimestamp() {
- return timestamp;
- }
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/MetadataPubKey.java b/src/main/java/org/torusresearch/torusutils/types/MetadataPubKey.java
deleted file mode 100644
index 10c05d6..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/MetadataPubKey.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-public class MetadataPubKey {
- private final String pub_key_X;
- private final String pub_key_Y;
-
- public MetadataPubKey(String pub_key_X, String pub_key_Y) {
- this.pub_key_X = pub_key_X;
- this.pub_key_Y = pub_key_Y;
- }
-
- public String getPub_key_X() {
- return pub_key_X;
- }
-
- public String getPub_key_Y() {
- return pub_key_Y;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/MetadataResponse.java b/src/main/java/org/torusresearch/torusutils/types/MetadataResponse.java
deleted file mode 100644
index 8179550..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/MetadataResponse.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-public class MetadataResponse {
- private final String message;
-
- public MetadataResponse(String message) {
- this.message = message;
- }
-
- public String getMessage() {
- return message;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/NodesData.java b/src/main/java/org/torusresearch/torusutils/types/NodesData.java
new file mode 100644
index 0000000..c2c9843
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/NodesData.java
@@ -0,0 +1,18 @@
+package org.torusresearch.torusutils.types;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+public class NodesData {
+
+ private final List nodeIndexes;
+
+ public NodesData(@NotNull List nodeIndexes) {
+ this.nodeIndexes = nodeIndexes;
+ }
+
+ public List getNodeIndexes() {
+ return nodeIndexes;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/OAuthKeyData.java b/src/main/java/org/torusresearch/torusutils/types/OAuthKeyData.java
new file mode 100644
index 0000000..edc6b5e
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/OAuthKeyData.java
@@ -0,0 +1,9 @@
+package org.torusresearch.torusutils.types;
+
+import org.jetbrains.annotations.NotNull;
+
+public class OAuthKeyData extends FinalKeyData {
+ public OAuthKeyData(@NotNull String walletAddress, @NotNull String X, @NotNull String Y, @NotNull String privKey) {
+ super(walletAddress, X, Y, privKey);
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/OAuthPubKeyData.java b/src/main/java/org/torusresearch/torusutils/types/OAuthPubKeyData.java
new file mode 100644
index 0000000..d139269
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/OAuthPubKeyData.java
@@ -0,0 +1,10 @@
+package org.torusresearch.torusutils.types;
+
+import org.jetbrains.annotations.NotNull;
+
+
+public class OAuthPubKeyData extends FinalPubKeyData {
+ public OAuthPubKeyData(@NotNull String walletAddress, @NotNull String x, @NotNull String y) {
+ super(walletAddress, x, y);
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/Point.java b/src/main/java/org/torusresearch/torusutils/types/Point.java
new file mode 100644
index 0000000..9380b64
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/Point.java
@@ -0,0 +1,55 @@
+package org.torusresearch.torusutils.types;
+
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.jce.ECNamedCurveTable;
+import org.bouncycastle.jce.spec.ECParameterSpec;
+import org.bouncycastle.util.encoders.Hex;
+import org.jetbrains.annotations.NotNull;
+import org.torusresearch.torusutils.helpers.Common;
+import org.torusresearch.torusutils.helpers.KeyUtils;
+
+import java.math.BigInteger;
+
+public class Point {
+ private final BigInteger x;
+ private final BigInteger y;
+ @SuppressWarnings("unused")
+ private final ECDomainParameters ecCurve;
+
+ public Point(@NotNull String x, @NotNull String y) {
+ this.x = new BigInteger(x, 16);
+ this.y = new BigInteger(y, 16);
+ ECParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
+ this.ecCurve = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN(), spec.getH(), spec.getSeed());
+ }
+
+ public Point(@NotNull BigInteger x, @NotNull BigInteger y) {
+ this.x = x;
+ this.y = y;
+ ECParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
+ this.ecCurve = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN(), spec.getH(), spec.getSeed());
+ }
+
+ public BigInteger getX() {
+ return x;
+ }
+
+ public BigInteger getY() {
+ return y;
+ }
+
+ @SuppressWarnings("unused")
+ public byte[] encode(@NotNull String enc) throws Exception {
+ String xPadded = Common.padLeft(this.x.toString(16),'0', 64);
+ String yPadded = Common.padLeft(this.y.toString(16),'0', 64);
+ switch (enc) {
+ case "arr":
+ return Hex.decode("04"+ xPadded + yPadded);
+ case "elliptic-compressed":
+ return KeyUtils.serializePublicKey(KeyUtils.deserializePublicKey(Hex.decode("04"+ xPadded + yPadded)), true);
+ default:
+ throw new IllegalArgumentException("Invalid encoding in Point");
+ }
+ }
+}
+
diff --git a/src/main/java/org/torusresearch/torusutils/types/Polynomial.java b/src/main/java/org/torusresearch/torusutils/types/Polynomial.java
new file mode 100644
index 0000000..524f234
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/Polynomial.java
@@ -0,0 +1,46 @@
+package org.torusresearch.torusutils.types;
+
+import static org.torusresearch.torusutils.helpers.KeyUtils.getOrderOfCurve;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.math.BigInteger;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class Polynomial {
+ private final BigInteger[] polynomial;
+
+ public Polynomial(@NotNull BigInteger[] polynomial) {
+ this.polynomial = polynomial;
+ }
+
+ @SuppressWarnings("unused")
+ public int getThreshold() {
+ return polynomial.length;
+ }
+
+ public BigInteger polyEval(@NotNull BigInteger x) {
+ BigInteger xi = x;
+ BigInteger sum = BigInteger.ZERO;
+ sum = sum.add(polynomial[0]);
+
+ for (int i = 1; i < polynomial.length; i++) {
+ BigInteger tmp = xi.multiply(polynomial[i]);
+ sum = sum.add(tmp).mod(getOrderOfCurve());
+ xi = xi.multiply(x).mod(getOrderOfCurve());
+ }
+
+ return sum;
+ }
+
+ public Map generateShares(@NotNull BigInteger[] shareIndexes) {
+ Map shares = new LinkedHashMap<>();
+ for (BigInteger shareIndex : shareIndexes) {
+ String hexString = String.format("%064x", shareIndex);
+ shares.put(hexString, new Share(shareIndex, polyEval(shareIndex)));
+ }
+ return shares;
+ }
+}
+
diff --git a/src/main/java/org/torusresearch/torusutils/types/RetrieveSharesResponse.java b/src/main/java/org/torusresearch/torusutils/types/RetrieveSharesResponse.java
deleted file mode 100644
index 89e730e..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/RetrieveSharesResponse.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-import java.math.BigInteger;
-
-public class RetrieveSharesResponse {
- private final String ethAddress;
- private final BigInteger privKey;
-
- private final BigInteger nonce;
-
- public RetrieveSharesResponse(String _ethAddress, BigInteger _privKey, BigInteger _nonce) {
- ethAddress = _ethAddress;
- privKey = _privKey;
- nonce = _nonce;
- }
-
- public String getEthAddress() {
- return ethAddress;
- }
-
- public BigInteger getPrivKey() {
- return privKey;
- }
-
- public BigInteger getNonce() {
- return nonce;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/SessionData.java b/src/main/java/org/torusresearch/torusutils/types/SessionData.java
new file mode 100644
index 0000000..4888622
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/SessionData.java
@@ -0,0 +1,24 @@
+package org.torusresearch.torusutils.types;
+
+import org.jetbrains.annotations.NotNull;
+import org.torusresearch.torusutils.types.common.SessionToken;
+
+import java.util.List;
+
+public class SessionData {
+
+ private final List sessionTokenData;
+ private final String sessionAuthKey;
+
+ public SessionData(@NotNull List sessionTokenData, @NotNull String sessionAuthKey) {
+ this.sessionTokenData = sessionTokenData;
+ this.sessionAuthKey = sessionAuthKey;
+ }
+
+ public List getSessionTokenData() {
+ return sessionTokenData;
+ }
+ public String getSessionAuthKey() {
+ return sessionAuthKey;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/Share.java b/src/main/java/org/torusresearch/torusutils/types/Share.java
new file mode 100644
index 0000000..112f68c
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/Share.java
@@ -0,0 +1,48 @@
+package org.torusresearch.torusutils.types;
+
+import org.jetbrains.annotations.NotNull;
+import org.torusresearch.torusutils.helpers.TorusUtilError;
+
+import java.math.BigInteger;
+
+public class Share {
+ private final BigInteger share;
+ private final BigInteger shareIndex;
+
+ @SuppressWarnings("unused")
+ public Share(@NotNull String shareIndex, @NotNull String share) throws Exception {
+ try {
+ this.shareIndex = new BigInteger(shareIndex, 16);
+ } catch (NumberFormatException e) {
+ throw new TorusUtilError("Invalid input");
+ }
+
+ try {
+ this.share = new BigInteger(share, 16);
+ } catch (NumberFormatException e) {
+ throw new TorusUtilError("Invalid input");
+ }
+ }
+
+ public Share(@NotNull BigInteger shareIndex, @NotNull BigInteger share) {
+ this.shareIndex = shareIndex;
+ this.share = share;
+ }
+
+ public BigInteger getShare() {
+ return share;
+ }
+
+ public BigInteger getShareIndex() {
+ return shareIndex;
+ }
+
+ // toString method for debugging purposes
+ @Override
+ public String toString() {
+ return "Share{" +
+ "share=" + share.toString(16) +
+ ", shareIndex=" + shareIndex.toString(16) +
+ '}';
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/SomeException.java b/src/main/java/org/torusresearch/torusutils/types/SomeException.java
deleted file mode 100644
index 70d6ed9..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/SomeException.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-import com.google.gson.Gson;
-
-public class SomeException extends Exception {
- public String[] errors;
-
- public String[] responses;
-
- public String predicate;
-
- public SomeException(String[] errors ,String[] responses, String predicate) {
- super("Unable to resolve enough promises.");
- this.errors = errors;
- this.responses = responses;
- this.predicate = predicate;
- }
-
- @Override
- public String toString() {
- Gson gson = new Gson();
- return gson.toJson(this.errors) + ", responses: " +
- gson.toJson(this.responses) + this.predicate;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/torusresearch/torusutils/types/TorusCtorOptions.java b/src/main/java/org/torusresearch/torusutils/types/TorusCtorOptions.java
deleted file mode 100644
index b419328..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/TorusCtorOptions.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-import java.math.BigInteger;
-
-public class TorusCtorOptions {
- private String metadataHost = "https://metadata.tor.us";
- private String allowHost = "https://signer.tor.us/api/allow";
- private boolean enableOneKey = false;
- private String signerHost = "https://signer.tor.us/api/sign";
- // in seconds
- private BigInteger serverTimeOffset = new BigInteger("0");
- private String origin;
- private String network = "mainnet";
-
- private boolean legacyNonce = false;
- private String clientId;
-
- public TorusCtorOptions(String origin, String clientid) {
- this.origin = origin;
- this.clientId = clientid;
- }
-
- public String getNetwork() {
- return network;
- }
-
- public void setNetwork(String network) {
- this.network = network;
- }
-
- public String getOrigin() {
- return origin;
- }
-
- public void setOrigin(String origin) {
- this.origin = origin;
- }
-
- public BigInteger getServerTimeOffset() {
- return serverTimeOffset;
- }
-
- public void setServerTimeOffset(BigInteger serverTimeOffset) {
- this.serverTimeOffset = serverTimeOffset;
- }
-
- public String getSignerHost() {
- return signerHost;
- }
-
- public void setSignerHost(String signerHost) {
- this.signerHost = signerHost;
- }
-
- public boolean isEnableOneKey() {
- return enableOneKey;
- }
-
- public void setEnableOneKey(boolean enableOneKey) {
- this.enableOneKey = enableOneKey;
- }
-
- public String getAllowHost() {
- return allowHost;
- }
-
- public void setAllowHost(String allowHost) {
- this.allowHost = allowHost;
- }
-
- public String getMetadataHost() {
- return metadataHost;
- }
-
- public void setMetadataHost(String _metadataHost) {
- this.metadataHost = _metadataHost;
- }
-
- public boolean isLegacyNonce() {
- return legacyNonce;
- }
-
- public void setLegacyNonce(boolean legacyNonce) {
- this.legacyNonce = legacyNonce;
- }
-
- public String getClientId() {
- return clientId;
- }
-
- public void setClientId(String clientId) {
- this.clientId = clientId;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/TorusException.java b/src/main/java/org/torusresearch/torusutils/types/TorusException.java
deleted file mode 100644
index 6daf4d2..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/TorusException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-public class TorusException extends Exception {
- public TorusException(String msg) {
- super(msg);
- }
-
- public TorusException(String msg, Throwable err) {
- super(msg, err);
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/TorusPublicKey.java b/src/main/java/org/torusresearch/torusutils/types/TorusPublicKey.java
deleted file mode 100644
index 0e07aa8..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/TorusPublicKey.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-import org.jetbrains.annotations.Nullable;
-import org.torusresearch.fetchnodedetails.types.TorusNodePub;
-
-import java.math.BigInteger;
-
-public class TorusPublicKey extends TorusNodePub {
- private final String address;
- private TypeOfUser typeOfUser;
- private BigInteger metadataNonce;
- @Nullable
- private GetOrSetNonceResult.PubNonce pubNonce;
- private boolean upgraded;
-
- public TorusPublicKey(String _X, String _Y, String _address) {
- super(_X, _Y);
- address = _address;
- }
-
- public TorusPublicKey(String _address) {
- super(null, null);
- address = _address;
- }
-
- public String getAddress() {
- return address;
- }
-
- public TypeOfUser getTypeOfUser() {
- return typeOfUser;
- }
-
- public void setTypeOfUser(TypeOfUser typeOfUser) {
- this.typeOfUser = typeOfUser;
- }
-
- public BigInteger getMetadataNonce() {
- return metadataNonce;
- }
-
- public void setMetadataNonce(BigInteger metadataNonce) {
- this.metadataNonce = metadataNonce;
- }
-
- public GetOrSetNonceResult.PubNonce getPubNonce() {
- return pubNonce;
- }
-
- public void setPubNonce(GetOrSetNonceResult.PubNonce pubNonce) {
- this.pubNonce = pubNonce;
- }
-
- public boolean getUpgraded() {
- return upgraded;
- }
-
- public void setUpgraded(boolean upgraded) {
- this.upgraded = upgraded;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/TorusUtilsExtraParams.java b/src/main/java/org/torusresearch/torusutils/types/TorusUtilsExtraParams.java
new file mode 100644
index 0000000..4893231
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/TorusUtilsExtraParams.java
@@ -0,0 +1,64 @@
+package org.torusresearch.torusutils.types;
+
+// TODO: This class is a bit of a mess for legacy reasons and should be cleaned up in future.
+
+import org.jetbrains.annotations.Nullable;
+
+public class TorusUtilsExtraParams {
+ @Nullable
+ public final String nonce; // farcaster
+ @Nullable
+ public final String message; // farcaster
+ @Nullable
+ public final String signature; // farcaster, passkey, webauthn
+ @Nullable
+ public final String clientDataJson; // passkey, webauthn
+ @Nullable
+ public final String authenticatorData; // passkey, webauthn
+ @Nullable
+ public final String publicKey; // passkey, webauthn
+ @Nullable
+ public final String challenge; // passkey, webauthn
+ @Nullable
+ public final String rpOrigin; // passkey, webauthn
+ @Nullable
+ public final String rpId; // passkey, webauthn
+ @Nullable
+ public Integer session_token_exp_second;
+ @Nullable
+ public final Integer timestamp; // signature
+
+ // Default constructor
+ public TorusUtilsExtraParams() {
+ this.nonce = null;
+ this.message = null;
+ this.signature = null;
+ this.clientDataJson = null;
+ this.authenticatorData = null;
+ this.publicKey = null;
+ this.challenge = null;
+ this.rpOrigin = null;
+ this.rpId = null;
+ this.session_token_exp_second = null;
+ this.timestamp = null;
+ }
+
+ @SuppressWarnings("unused")
+ public TorusUtilsExtraParams(
+ @Nullable Integer session_token_exp_second,
+ @Nullable String nonce, @Nullable String message, @Nullable String signature, @Nullable String clientDataJson, @Nullable String authenticatorData,
+ @Nullable String publicKey, @Nullable String challenge, @Nullable String rpOrigin, @Nullable String rpId, @Nullable Integer timestamp) {
+ this.nonce = nonce;
+ this.message = message;
+ this.signature = signature;
+ this.clientDataJson = clientDataJson;
+ this.authenticatorData = authenticatorData;
+ this.publicKey = publicKey;
+ this.challenge = challenge;
+ this.rpOrigin = rpOrigin;
+ this.rpId = rpId;
+ this.session_token_exp_second = session_token_exp_second;
+ this.timestamp = timestamp;
+ }
+}
+
diff --git a/src/main/java/org/torusresearch/torusutils/types/TypeOfUser.java b/src/main/java/org/torusresearch/torusutils/types/TypeOfUser.java
deleted file mode 100644
index ee1fde6..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/TypeOfUser.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-public enum TypeOfUser {
- v1,
- v2
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/VerifierArgs.java b/src/main/java/org/torusresearch/torusutils/types/VerifierArgs.java
deleted file mode 100644
index b67b0dd..0000000
--- a/src/main/java/org/torusresearch/torusutils/types/VerifierArgs.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.torusresearch.torusutils.types;
-
-public class VerifierArgs {
- private final String verifier;
- private final String verifierId;
-
- public VerifierArgs(String _verifier, String _verifierId) {
- verifier = _verifier;
- verifierId = _verifierId;
- }
-
- public String getVerifier() {
- return verifier;
- }
-
- public String getVerifierId() {
- return verifierId;
- }
-}
diff --git a/src/main/java/org/torusresearch/torusutils/types/VerifierParams.java b/src/main/java/org/torusresearch/torusutils/types/VerifierParams.java
index 7ddc125..44a8b81 100644
--- a/src/main/java/org/torusresearch/torusutils/types/VerifierParams.java
+++ b/src/main/java/org/torusresearch/torusutils/types/VerifierParams.java
@@ -1,13 +1,23 @@
package org.torusresearch.torusutils.types;
-public class VerifierParams {
- private final String verifierId;
+import org.jetbrains.annotations.NotNull;
- public VerifierParams(String _verifierId) {
- verifierId = _verifierId;
- }
+import io.reactivex.annotations.Nullable;
- public String getVerifierId() {
- return verifierId;
+public class VerifierParams {
+ public final String verifier_id;
+ @Nullable
+ public final String extended_verifier_id;
+ @Nullable
+ public final String[] sub_verifier_ids;
+ @Nullable
+ public final VerifyParams[] verify_params;
+
+ public VerifierParams(@NotNull String verifierId, @Nullable String extendedVerifierId, @Nullable String[] subVerifierIds, @Nullable VerifyParams[] verifyParams) {
+ this.verifier_id = verifierId;
+ this.extended_verifier_id = extendedVerifierId;
+ this.verify_params = verifyParams;
+ this.sub_verifier_ids = subVerifierIds;
}
}
+
diff --git a/src/main/java/org/torusresearch/torusutils/types/VerifyParams.java b/src/main/java/org/torusresearch/torusutils/types/VerifyParams.java
new file mode 100644
index 0000000..6e36394
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/VerifyParams.java
@@ -0,0 +1,16 @@
+package org.torusresearch.torusutils.types;
+
+
+import org.jetbrains.annotations.Nullable;
+
+public class VerifyParams {
+ @Nullable
+ public final String verifier_id;
+ @Nullable
+ public final String idtoken;
+
+ public VerifyParams(@Nullable String verifier_id, @Nullable String idtoken) {
+ this.verifier_id = verifier_id;
+ this.idtoken = idtoken;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/ImportedShare.java b/src/main/java/org/torusresearch/torusutils/types/common/ImportedShare.java
new file mode 100644
index 0000000..1269081
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/ImportedShare.java
@@ -0,0 +1,41 @@
+package org.torusresearch.torusutils.types.common;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.torusutils.types.Point;
+import org.torusresearch.torusutils.types.common.ecies.EciesHexOmitCipherText;
+
+public class ImportedShare {
+
+ public final String oauth_pub_key_x;
+ public final String oauth_pub_key_y;
+ public final Point final_user_point;
+ public final String signing_pub_key_x;
+ public final String signing_pub_key_y;
+ public final String encryptedShare;
+ public final EciesHexOmitCipherText encryptedShareMetadata;
+ @Nullable
+ public final String encryptedSeed;
+ public final int node_index;
+ @Nullable
+ public final TorusKeyType key_type;
+ public final String nonce_data;
+ public final String nonce_signature;
+
+ public ImportedShare(@NotNull String oauth_pub_key_x, @NotNull String oauth_pub_key_y, @NotNull Point final_user_point, @NotNull String signing_pub_key_x, @NotNull String signing_pub_key_y, @NotNull String encryptedShare,
+ @NotNull EciesHexOmitCipherText encryptedShareMetadata, @Nullable String encryptedSeed, int node_index, @Nullable TorusKeyType key_type,
+ @NotNull String nonce_data, @NotNull String nonce_signature) {
+ this.oauth_pub_key_x = oauth_pub_key_x;
+ this.oauth_pub_key_y = oauth_pub_key_y;
+ this.final_user_point = final_user_point;
+ this.signing_pub_key_x = signing_pub_key_x;
+ this.signing_pub_key_y = signing_pub_key_y;
+ this.encryptedShare = encryptedShare;
+ this.encryptedShareMetadata = encryptedShareMetadata;
+ this.encryptedSeed = encryptedSeed;
+ this.node_index = node_index;
+ this.key_type = key_type;
+ this.nonce_data = nonce_data;
+ this.nonce_signature = nonce_signature;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/KeyLookup/KeyLookupResult.java b/src/main/java/org/torusresearch/torusutils/types/common/KeyLookup/KeyLookupResult.java
new file mode 100644
index 0000000..bcc3d04
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/KeyLookup/KeyLookupResult.java
@@ -0,0 +1,29 @@
+package org.torusresearch.torusutils.types.common.KeyLookup;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.torusutils.apis.JsonRPCErrorInfo;
+import org.torusresearch.torusutils.apis.responses.GetOrSetNonceResult;
+
+import java.util.List;
+
+public class KeyLookupResult {
+ @Nullable
+ public final KeyResult keyResult;
+
+ public final List nodeIndexes;
+ public final Integer server_time_offset;
+ @Nullable
+ public final GetOrSetNonceResult nonceResult;
+
+ @Nullable
+ public final JsonRPCErrorInfo errorResult;
+
+ public KeyLookupResult(@Nullable KeyResult keyResult, @NotNull List nodeIndexes, @NotNull Integer server_time_offset, @Nullable GetOrSetNonceResult nonceResult, @Nullable JsonRPCErrorInfo errorResult) {
+ this.keyResult = keyResult;
+ this.nodeIndexes = nodeIndexes;
+ this.server_time_offset = server_time_offset;
+ this.nonceResult = nonceResult;
+ this.errorResult = errorResult;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/KeyLookup/KeyResult.java b/src/main/java/org/torusresearch/torusutils/types/common/KeyLookup/KeyResult.java
new file mode 100644
index 0000000..b926052
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/KeyLookup/KeyResult.java
@@ -0,0 +1,20 @@
+package org.torusresearch.torusutils.types.common.KeyLookup;
+
+import org.jetbrains.annotations.NotNull;
+import org.torusresearch.torusutils.apis.responses.VerifierLookupResponse.VerifierKey;
+
+public class KeyResult {
+ public VerifierKey[] keys;
+ public final Boolean is_new_key;
+
+ @SuppressWarnings("unused")
+ public KeyResult(@NotNull VerifierKey[] keys, @NotNull Boolean is_new_key) {
+ this.keys = keys;
+ this.is_new_key = is_new_key;
+ }
+
+ public KeyResult(@NotNull Boolean is_new_key) {
+ this.keys = new VerifierKey[]{};
+ this.is_new_key = is_new_key;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/PrivateKeyData.java b/src/main/java/org/torusresearch/torusutils/types/common/PrivateKeyData.java
new file mode 100644
index 0000000..c6c89e8
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/PrivateKeyData.java
@@ -0,0 +1,65 @@
+package org.torusresearch.torusutils.types.common;
+
+import org.jetbrains.annotations.NotNull;
+
+public class PrivateKeyData {
+ private final String oAuthKey;
+ private final String oAuthPubKey;
+ private final String nonce;
+ private final String signingKey;
+ private final String signingPubKey;
+ private final String finalKey;
+ private final String finalPubKey;
+
+ public PrivateKeyData(@NotNull String oAuthKey, @NotNull String oAuthPubKey, @NotNull String nonce, @NotNull String signingKey, @NotNull String signingPubKey, @NotNull String finalKey, @NotNull String finalPubKey) {
+ this.oAuthKey = oAuthKey;
+ this.oAuthPubKey = oAuthPubKey;
+ this.nonce = nonce;
+ this.signingKey = signingKey;
+ this.signingPubKey = signingPubKey;
+ this.finalKey = finalKey;
+ this.finalPubKey = finalPubKey;
+ }
+
+ public String getOAuthKey() {
+ return oAuthKey;
+ }
+
+ public String getOAuthPubKey() {
+ return oAuthPubKey;
+ }
+
+ public String getNonce() {
+ return nonce;
+ }
+
+ public String getSigningKey() {
+ return signingKey;
+ }
+
+ public String getSigningPubKey() {
+ return signingPubKey;
+ }
+
+ @SuppressWarnings("unused")
+ public String getFinalKey() {
+ return finalKey;
+ }
+
+ public String getFinalPubKey() {
+ return finalPubKey;
+ }
+
+ @Override
+ public String toString() {
+ return "PrivateKeyData{" +
+ "oAuthKey='" + oAuthKey + '\'' +
+ ", oAuthPubKey='" + oAuthPubKey + '\'' +
+ ", nonce='" + nonce + '\'' +
+ ", signingKey='" + signingKey + '\'' +
+ ", signingPubKey='" + signingPubKey + '\'' +
+ ", finalKey='" + finalKey + '\'' +
+ ", finalPubKey='" + finalPubKey + '\'' +
+ '}';
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/PubNonce.java b/src/main/java/org/torusresearch/torusutils/types/common/PubNonce.java
new file mode 100644
index 0000000..405380d
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/PubNonce.java
@@ -0,0 +1,13 @@
+package org.torusresearch.torusutils.types.common;
+
+import org.jetbrains.annotations.NotNull;
+
+public class PubNonce {
+ public final String x;
+ public final String y;
+
+ public PubNonce(@NotNull String x, @NotNull String y) {
+ this.x = x;
+ this.y = y;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/SessionToken.java b/src/main/java/org/torusresearch/torusutils/types/common/SessionToken.java
new file mode 100644
index 0000000..79bf686
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/SessionToken.java
@@ -0,0 +1,37 @@
+package org.torusresearch.torusutils.types.common;
+
+import org.jetbrains.annotations.NotNull;
+
+public class SessionToken {
+
+ private final String token;
+ private final String signature;
+ private final String node_pubx;
+ private final String node_puby;
+
+ public SessionToken(@NotNull String token, @NotNull String signature, @NotNull String node_pubx, @NotNull String node_puby) {
+ this.token = token;
+ this.signature = signature;
+ this.node_pubx = node_pubx;
+ this.node_puby = node_puby;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ @SuppressWarnings("unused")
+ public String getSignature() {
+ return signature;
+ }
+
+ @SuppressWarnings("unused")
+ public String getNode_pubx() {
+ return node_pubx;
+ }
+
+ @SuppressWarnings("unused")
+ public String getNode_puby() {
+ return node_puby;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/TorusKey.java b/src/main/java/org/torusresearch/torusutils/types/common/TorusKey.java
new file mode 100644
index 0000000..9c7c351
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/TorusKey.java
@@ -0,0 +1,46 @@
+package org.torusresearch.torusutils.types.common;
+
+import org.jetbrains.annotations.NotNull;
+import org.torusresearch.torusutils.types.FinalKeyData;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthKeyData;
+import org.torusresearch.torusutils.types.SessionData;
+import org.torusresearch.torusutils.types.Metadata;
+
+public class TorusKey {
+
+ private final FinalKeyData finalKeyData;
+ private final OAuthKeyData oAuthKeyData;
+ private final SessionData sessionData;
+
+ private final Metadata metadata;
+ private final NodesData nodesData;
+
+ public TorusKey(@NotNull FinalKeyData finalKeyData, @NotNull OAuthKeyData oAuthKeyData, @NotNull SessionData sessionData, @NotNull Metadata metadata, @NotNull NodesData nodesData) {
+ this.finalKeyData = finalKeyData;
+ this.oAuthKeyData = oAuthKeyData;
+ this.sessionData = sessionData;
+ this.metadata = metadata;
+ this.nodesData = nodesData;
+ }
+
+ public FinalKeyData getFinalKeyData() {
+ return finalKeyData;
+ }
+
+ public OAuthKeyData getoAuthKeyData() {
+ return oAuthKeyData;
+ }
+
+ public SessionData getSessionData() {
+ return sessionData;
+ }
+
+ public Metadata getMetadata() {
+ return metadata;
+ }
+
+ public NodesData getNodesData() {
+ return nodesData;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/TorusKeyType.java b/src/main/java/org/torusresearch/torusutils/types/common/TorusKeyType.java
new file mode 100644
index 0000000..c18c4a9
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/TorusKeyType.java
@@ -0,0 +1,7 @@
+package org.torusresearch.torusutils.types.common;
+
+public enum TorusKeyType {
+ secp256k1,
+ @SuppressWarnings("unused")
+ ed25519
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/TorusOptions.java b/src/main/java/org/torusresearch/torusutils/types/common/TorusOptions.java
new file mode 100644
index 0000000..919668b
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/TorusOptions.java
@@ -0,0 +1,35 @@
+package org.torusresearch.torusutils.types.common;
+
+import static org.torusresearch.fetchnodedetails.types.Utils.METADATA_MAP;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
+
+public class TorusOptions {
+ public final String legacyMetadataHost;
+ // in seconds
+ public final Integer serverTimeOffset;
+ public final Web3AuthNetwork network;
+ public final String clientId;
+
+ public boolean enableOneKey;
+
+ public final TorusKeyType keyType = TorusKeyType.secp256k1;
+
+ public TorusOptions(@NotNull String clientId, @NotNull Web3AuthNetwork network, @Nullable String legacyMetadataHost, @Nullable Integer serverTimeOffset, @NotNull Boolean enableOneKey) {
+ this.clientId = clientId;
+ this.network = network;
+ if (legacyMetadataHost == null) {
+ this.legacyMetadataHost = METADATA_MAP.get(network);
+ } else {
+ this.legacyMetadataHost = legacyMetadataHost;
+ }
+ if (serverTimeOffset != null ) {
+ this.serverTimeOffset = serverTimeOffset;
+ } else {
+ this.serverTimeOffset = 0;
+ }
+ this.enableOneKey = enableOneKey;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/TorusPublicKey.java b/src/main/java/org/torusresearch/torusutils/types/common/TorusPublicKey.java
new file mode 100644
index 0000000..8500fad
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/TorusPublicKey.java
@@ -0,0 +1,38 @@
+package org.torusresearch.torusutils.types.common;
+
+import org.jetbrains.annotations.NotNull;
+import org.torusresearch.torusutils.types.FinalPubKeyData;
+import org.torusresearch.torusutils.types.Metadata;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthPubKeyData;
+
+public class TorusPublicKey {
+
+ private final OAuthPubKeyData oAuthKeyData;
+ private final FinalPubKeyData finalKeyData;
+ private final Metadata metadata;
+ private final NodesData nodesData;
+
+ public TorusPublicKey(@NotNull OAuthPubKeyData oAuthKeyData, @NotNull FinalPubKeyData finalKeyData, @NotNull Metadata metadata, @NotNull NodesData nodesData) {
+ this.oAuthKeyData = oAuthKeyData;
+ this.finalKeyData = finalKeyData;
+ this.metadata = metadata;
+ this.nodesData = nodesData;
+ }
+
+ public OAuthPubKeyData getoAuthKeyData() {
+ return oAuthKeyData;
+ }
+
+ public FinalPubKeyData getFinalKeyData() {
+ return finalKeyData;
+ }
+
+ public Metadata getMetadata() {
+ return metadata;
+ }
+
+ public NodesData getNodesData() {
+ return nodesData;
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/TypeOfUser.java b/src/main/java/org/torusresearch/torusutils/types/common/TypeOfUser.java
new file mode 100644
index 0000000..485227a
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/TypeOfUser.java
@@ -0,0 +1,6 @@
+package org.torusresearch.torusutils.types.common;
+
+public enum TypeOfUser {
+ v1,
+ v2
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/ecies/Ecies.java b/src/main/java/org/torusresearch/torusutils/types/common/ecies/Ecies.java
new file mode 100644
index 0000000..da72b2e
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/ecies/Ecies.java
@@ -0,0 +1,22 @@
+package org.torusresearch.torusutils.types.common.ecies;
+
+import org.jetbrains.annotations.NotNull;
+
+public class Ecies extends EciesHexOmitCipherText {
+ public final String ciphertext;
+
+ @SuppressWarnings("unused")
+ public Ecies(@NotNull String iv, @NotNull String ephemPublicKey, @NotNull String ciphertext, @NotNull String mac, @NotNull String mode) {
+ super(iv, ephemPublicKey, mac, mode);
+ this.ciphertext = ciphertext;
+ }
+
+ public Ecies(@NotNull String iv, @NotNull String ephemPublicKey, @NotNull String ciphertext, @NotNull String mac) {
+ super(iv,ephemPublicKey,mac,"AES256");
+ this.ciphertext = ciphertext;
+ }
+
+ public EciesHexOmitCipherText omitCipherText() {
+ return new EciesHexOmitCipherText(iv, ephemPublicKey, mac, mode);
+ }
+}
diff --git a/src/main/java/org/torusresearch/torusutils/types/common/ecies/EciesHexOmitCipherText.java b/src/main/java/org/torusresearch/torusutils/types/common/ecies/EciesHexOmitCipherText.java
new file mode 100644
index 0000000..e433c6c
--- /dev/null
+++ b/src/main/java/org/torusresearch/torusutils/types/common/ecies/EciesHexOmitCipherText.java
@@ -0,0 +1,25 @@
+package org.torusresearch.torusutils.types.common.ecies;
+
+import org.jetbrains.annotations.NotNull;
+
+public class EciesHexOmitCipherText {
+ public final String iv;
+ public final String ephemPublicKey;
+ public final String mac;
+ public final String mode;
+
+ public EciesHexOmitCipherText(@NotNull String iv, @NotNull String ephemPublicKey, @NotNull String mac, @NotNull String mode) {
+ this.iv = iv;
+ this.ephemPublicKey = ephemPublicKey;
+ this.mac = mac;
+ this.mode = mode;
+ }
+
+ @SuppressWarnings("unused")
+ public EciesHexOmitCipherText(@NotNull String iv, @NotNull String ephemPublicKey, @NotNull String mac) {
+ this.iv = iv;
+ this.ephemPublicKey = ephemPublicKey;
+ this.mac = mac;
+ this.mode = "AES256";
+ }
+}
diff --git a/src/test/java/org/torusresearch/torusutilstest/AquaTest.java b/src/test/java/org/torusresearch/torusutilstest/AquaTest.java
index 7b9c8f2..c2aac66 100644
--- a/src/test/java/org/torusresearch/torusutilstest/AquaTest.java
+++ b/src/test/java/org/torusresearch/torusutilstest/AquaTest.java
@@ -1,26 +1,38 @@
package org.torusresearch.torusutilstest;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.auth0.jwt.algorithms.Algorithm;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.torusresearch.fetchnodedetails.FetchNodeDetails;
import org.torusresearch.fetchnodedetails.types.NodeDetails;
import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
import org.torusresearch.torusutils.TorusUtils;
-import org.torusresearch.torusutils.types.RetrieveSharesResponse;
-import org.torusresearch.torusutils.types.TorusCtorOptions;
-import org.torusresearch.torusutils.types.TorusException;
-import org.torusresearch.torusutils.types.TorusPublicKey;
-import org.torusresearch.torusutils.types.VerifierArgs;
+import org.torusresearch.torusutils.helpers.TorusUtilError;
+import org.torusresearch.torusutils.types.FinalKeyData;
+import org.torusresearch.torusutils.types.FinalPubKeyData;
+import org.torusresearch.torusutils.types.Metadata;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthKeyData;
+import org.torusresearch.torusutils.types.OAuthPubKeyData;
+import org.torusresearch.torusutils.types.SessionData;
+import org.torusresearch.torusutils.types.VerifierParams;
+import org.torusresearch.torusutils.types.VerifyParams;
+import org.torusresearch.torusutils.types.common.PubNonce;
+import org.torusresearch.torusutils.types.common.TorusKey;
+import org.torusresearch.torusutils.types.common.TorusOptions;
+import org.torusresearch.torusutils.types.common.TorusPublicKey;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
import org.torusresearch.torusutilstest.utils.JwtUtils;
import org.torusresearch.torusutilstest.utils.PemUtils;
-import org.torusresearch.torusutilstest.utils.VerifyParams;
import org.web3j.crypto.Hash;
import java.io.IOException;
@@ -31,8 +43,6 @@
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
-import java.util.HashMap;
-import java.util.concurrent.ExecutionException;
public class AquaTest {
@@ -46,14 +56,10 @@ public class AquaTest {
static String TORUS_TEST_EMAIL = "hello@tor.us";
- @BeforeAll
- static void setup() throws ExecutionException, InterruptedException, IOException, NoSuchAlgorithmException, InvalidKeySpecException {
- System.out.println("Setup Starting");
+ @BeforeEach
+ void setup() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, TorusUtilError {
fetchNodeDetails = new FetchNodeDetails(Web3AuthNetwork.AQUA);
- TorusCtorOptions opts = new TorusCtorOptions("Custom", "YOUR_CLIENT_ID");
- opts.setNetwork("aqua");
- opts.setSignerHost("https://signer-polygon.tor.us/api/sign");
- opts.setAllowHost("https://signer-polygon.tor.us/api/allow");
+ TorusOptions opts = new TorusOptions("YOUR_CLIENT_ID", Web3AuthNetwork.AQUA, null, 0, false);
torusUtils = new TorusUtils(opts);
ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromFile("src/test/java/org/torusresearch/torusutilstest/keys/key.pem", "EC");
ECPublicKey publicKey = (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(new ECPublicKeySpec(privateKey.getParams().getGenerator(),
@@ -63,56 +69,155 @@ static void setup() throws ExecutionException, InterruptedException, IOException
@DisplayName("Gets Public Address")
@Test
- public void shouldGetPublicAddress() throws ExecutionException, InterruptedException {
- VerifierArgs args = new VerifierArgs("tkey-google-aqua", TORUS_TEST_EMAIL);
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(args.getVerifier(), args.getVerifierId()).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), args).get();
- assertEquals("0xDfA967285AC699A70DA340F60d00DB19A272639d", publicAddress.getAddress());
+ public void shouldGetPublicAddress() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("tkey-google-aqua", TORUS_TEST_EMAIL).get();
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), "tkey-google-aqua", TORUS_TEST_EMAIL, null);
+ assertTrue(publicAddress.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0xDfA967285AC699A70DA340F60d00DB19A272639d", publicAddress.getFinalKeyData().getWalletAddress());
+ assertThat(publicAddress).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xDfA967285AC699A70DA340F60d00DB19A272639d",
+ "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d",
+ "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c"),
+ new FinalPubKeyData("0xDfA967285AC699A70DA340F60d00DB19A272639d",
+ "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d",
+ "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c"),
+ new Metadata(publicAddress.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v1, false, publicAddress.getMetadata().getServerTimeOffset()),
+ new NodesData(publicAddress.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("Fetch User Type and Public Address")
+ @Test
+ public void shouldFetchUserTypeAndPublicAddress() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("tkey-google-aqua", TORUS_TEST_EMAIL).get();
+ TorusPublicKey key = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), "tkey-google-aqua", TORUS_TEST_EMAIL, null);
+ assertEquals("0x79F06350eF34Aeed4BE68e26954D405D573f1438", key.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key.getMetadata().getTypeOfUser());
+ assertThat(key).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xDfA967285AC699A70DA340F60d00DB19A272639d",
+ "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d",
+ "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c"),
+ new FinalPubKeyData("0x79F06350eF34Aeed4BE68e26954D405D573f1438",
+ "99df45abc8e6ee03d2f94df33be79e939eadfbed20c6b88492782fdc3ef1dfd3",
+ "12bf3e54599a177fdb88f8b22419df7ddf1622e1d2344301edbe090890a72b16"),
+ new Metadata(key.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v2, false, key.getMetadata().getServerTimeOffset()),
+ new NodesData(key.getNodesData().getNodeIndexes())
+ ));
+
+ String v2Verifier = "tkey-google-aqua";
+ // 1/1 user
+ String v2TestEmail = "somev2user@gmail.com";
+ TorusPublicKey key2 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), v2Verifier, v2TestEmail, null);
+ assertEquals("0xBc32f315515AdE7010cabC5Fd68c966657A570BD", key2.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key2.getMetadata().getTypeOfUser());
+ assertThat(key2).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x4ea5260fF85678A2a326D08DF9C44d1f559a5828",
+ "0e6febe33a9d4eeb680cc6b63ff6237ad1971f27adcd7f104a3b1de18eda9337",
+ "a5a915561f3543688e71281a850b9ee10b9690f305d9e79028dfc8359192b82d"),
+ new FinalPubKeyData("0xBc32f315515AdE7010cabC5Fd68c966657A570BD",
+ "4897f120584ee18a72b9a6bb92c3ef6e45fc5fdff70beae7dc9325bd01332022",
+ "2066dbef2fcdded4573e3c04d1c04edd5d44662168e636ed9d0b0cbe2e67c968"),
+ new Metadata(new PubNonce("1601cf4dc4362b219260663d5ec5119699fbca185d08b7acb2e36cad914340d5",
+ "c2f7871f61ee71b4486ac9fb40ec759099800e737139dc5dfaaaed8c9d77c3c1"),
+ BigInteger.ZERO, TypeOfUser.v2,
+ false,
+ key2.getMetadata().getServerTimeOffset()),
+ new NodesData(key2.getNodesData().getNodeIndexes())
+ ));
+
+ // 2/n user
+ String v2nTestEmail = "caspertorus@gmail.com";
+ TorusPublicKey key3 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), v2Verifier, v2nTestEmail, null);
+ assertEquals("0x5469C5aCB0F30929226AfF4622918DA8E1424a8D", key3.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key3.getMetadata().getTypeOfUser());
+ assertThat(key3).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD",
+ "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281",
+ "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f"),
+ new FinalPubKeyData("0x5469C5aCB0F30929226AfF4622918DA8E1424a8D",
+ "c20fac685bb67169e92f1d5d8894d4eea18753c0ef3b7b1b2224233b2dfa3539",
+ "c4f080b5c8d5c55c8eaba4bec70f668f36db4126f358b491d631fefea7c19d21"),
+ new Metadata(key3.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v2, false, key3.getMetadata().getServerTimeOffset()),
+ new NodesData(key3.getNodesData().getNodeIndexes())
+ ));
}
@DisplayName("Key Assign test")
@Test
- public void shouldKeyAssign() throws ExecutionException, InterruptedException {
+ public void shouldKeyAssign() throws Exception {
String email = JwtUtils.getRandomEmail();
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("tkey-google-aqua", email).get();
TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(),
- nodeDetails.getTorusNodePub(), new VerifierArgs("tkey-google-aqua", email)).get();
- System.out.println(email + " -> " + publicAddress.getAddress());
- assertNotNull(publicAddress.getAddress());
- assertNotEquals(publicAddress.getAddress(), "");
+ "tkey-google-aqua", email, "");
+ assertNotNull(publicAddress.getFinalKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getFinalKeyData().getWalletAddress(), "");
+ assertNotNull(publicAddress.getoAuthKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getoAuthKeyData().getWalletAddress(), "");
+ assertFalse(publicAddress.getMetadata().isUpgraded());
}
@DisplayName("Login test")
@Test
- public void shouldLogin() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldLogin() throws Exception {
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(),
- nodeDetails.getTorusIndexes(), TORUS_TEST_VERIFIER, new HashMap() {{
- put("verifier_id", TORUS_TEST_EMAIL);
- }},
- JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs)).get();
- System.out.println(retrieveSharesResponse.getPrivKey());
- BigInteger requiredPrivateKey = new BigInteger("f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d", 16);
- assert (requiredPrivateKey.equals(retrieveSharesResponse.getPrivKey()));
- assertEquals("0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195", retrieveSharesResponse.getEthAddress());
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_VERIFIER, verifierParams,
+ JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs), null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assert ((torusKey.getFinalKeyData().getPrivKey() != null) && torusKey.getFinalKeyData().getPrivKey().equals("f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d"));
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195",
+ "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664",
+ "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f",
+ "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d"),
+ new OAuthKeyData("0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195",
+ "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664",
+ "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f",
+ "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(null, BigInteger.ZERO, TypeOfUser.v1, null, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
@DisplayName("Aggregate Login test")
@Test
- public void shouldAggregateLogin() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldAggregateLogin() throws Exception {
String idToken = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
- String hashedIdToken = Hash.sha3String(idToken).substring(2);
+ String hashedIdToken = Hash.sha3String(idToken).replace("0x","");
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, new String[]{TORUS_TEST_VERIFIER}, new VerifyParams[]{new VerifyParams(TORUS_TEST_EMAIL, idToken)});
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_AGGREGATE_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(),
- nodeDetails.getTorusIndexes(), TORUS_TEST_AGGREGATE_VERIFIER, new HashMap() {{
- put("verify_params", new VerifyParams[]{
- new VerifyParams(idToken, TORUS_TEST_EMAIL)
- });
- put("sub_verifier_ids", new String[]{TORUS_TEST_VERIFIER});
- put("verifier_id", TORUS_TEST_EMAIL);
- }},
- hashedIdToken).get();
- assertEquals("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D", retrieveSharesResponse.getEthAddress());
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_AGGREGATE_VERIFIER, verifierParams,
+ hashedIdToken, null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D", torusKey.getoAuthKeyData().getWalletAddress());
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D",
+ "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d",
+ "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10",
+ "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355"),
+ new OAuthKeyData("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D",
+ "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d",
+ "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10",
+ "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(null, BigInteger.ZERO, TypeOfUser.v1, null, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("RetrieveShares Some Nodes Down")
+ @Test
+ public void testRetrieveSharesSomeNodesDown() throws Exception {
+ String verifier = TORUS_TEST_VERIFIER;
+ String verifierId = TORUS_TEST_EMAIL;
+ VerifierParams verifierParams = new VerifierParams(verifierId, null, null, null);
+ String jwt = JwtUtils.generateIdToken(verifierId, algorithmRs);
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(verifier, verifierId).get();
+ String[] endpoints = nodeDetails.getTorusNodeEndpoints();
+ endpoints[endpoints.length - 1] = "https://ndjnfjbfrj/random";
+ TorusKey torusKey = torusUtils.retrieveShares(endpoints, verifier, verifierParams, jwt, null);
+ assertEquals("f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d", torusKey.getFinalKeyData().getPrivKey());
}
}
diff --git a/src/test/java/org/torusresearch/torusutilstest/CelesteTest.java b/src/test/java/org/torusresearch/torusutilstest/CelesteTest.java
index 8bddabc..13a9ab6 100644
--- a/src/test/java/org/torusresearch/torusutilstest/CelesteTest.java
+++ b/src/test/java/org/torusresearch/torusutilstest/CelesteTest.java
@@ -1,27 +1,38 @@
package org.torusresearch.torusutilstest;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.auth0.jwt.algorithms.Algorithm;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.torusresearch.fetchnodedetails.FetchNodeDetails;
import org.torusresearch.fetchnodedetails.types.NodeDetails;
import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
import org.torusresearch.torusutils.TorusUtils;
-import org.torusresearch.torusutils.types.RetrieveSharesResponse;
-import org.torusresearch.torusutils.types.TorusCtorOptions;
-import org.torusresearch.torusutils.types.TorusException;
-import org.torusresearch.torusutils.types.TorusPublicKey;
-import org.torusresearch.torusutils.types.TypeOfUser;
-import org.torusresearch.torusutils.types.VerifierArgs;
+import org.torusresearch.torusutils.helpers.TorusUtilError;
+import org.torusresearch.torusutils.types.FinalKeyData;
+import org.torusresearch.torusutils.types.FinalPubKeyData;
+import org.torusresearch.torusutils.types.Metadata;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthKeyData;
+import org.torusresearch.torusutils.types.OAuthPubKeyData;
+import org.torusresearch.torusutils.types.SessionData;
+import org.torusresearch.torusutils.types.VerifierParams;
+import org.torusresearch.torusutils.types.VerifyParams;
+import org.torusresearch.torusutils.types.common.PubNonce;
+import org.torusresearch.torusutils.types.common.TorusKey;
+import org.torusresearch.torusutils.types.common.TorusOptions;
+import org.torusresearch.torusutils.types.common.TorusPublicKey;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
import org.torusresearch.torusutilstest.utils.JwtUtils;
import org.torusresearch.torusutilstest.utils.PemUtils;
-import org.torusresearch.torusutilstest.utils.VerifyParams;
import org.web3j.crypto.Hash;
import java.io.IOException;
@@ -32,8 +43,6 @@
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
-import java.util.HashMap;
-import java.util.concurrent.ExecutionException;
public class CelesteTest {
@@ -47,89 +56,155 @@ public class CelesteTest {
static String TORUS_TEST_EMAIL = "hello@tor.us";
- @BeforeAll
- static void setup() throws ExecutionException, InterruptedException, IOException, NoSuchAlgorithmException, InvalidKeySpecException {
- System.out.println("Setup Startingg");
+ @BeforeEach
+ void setup() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, TorusUtilError {
fetchNodeDetails = new FetchNodeDetails(Web3AuthNetwork.CELESTE);
- TorusCtorOptions opts = new TorusCtorOptions("Custom", "YOUR_CLIENT_ID");
- opts.setNetwork("celeste");
- opts.setSignerHost("https://signer-polygon.tor.us/api/sign");
- opts.setAllowHost("https://signer-polygon.tor.us/api/allow");
+ TorusOptions opts = new TorusOptions("YOUR_CLIENT_ID", Web3AuthNetwork.CELESTE, null, 0, false);
torusUtils = new TorusUtils(opts);
ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromFile("src/test/java/org/torusresearch/torusutilstest/keys/key.pem", "EC");
- ECPublicKey publicKey = (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(new ECPublicKeySpec(privateKey.getParams().getGenerator(), privateKey.getParams()));
+ ECPublicKey publicKey = (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(new ECPublicKeySpec(privateKey.getParams().getGenerator(),
+ privateKey.getParams()));
algorithmRs = Algorithm.ECDSA256(publicKey, privateKey);
}
@DisplayName("Gets Public Address")
@Test
- public void shouldGetPublicAddress() throws ExecutionException, InterruptedException {
- VerifierArgs args = new VerifierArgs("tkey-google-celeste", TORUS_TEST_EMAIL);
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(args.getVerifier(), args.getVerifierId()).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), args).get();
- assertEquals("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", publicAddress.getAddress());
+ public void shouldGetPublicAddress() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("tkey-google-celeste", TORUS_TEST_EMAIL).get();
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), "tkey-google-celeste", TORUS_TEST_EMAIL, null);
+ assertTrue(publicAddress.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", publicAddress.getFinalKeyData().getWalletAddress());
+ assertThat(publicAddress).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113",
+ "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9",
+ "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb"),
+ new FinalPubKeyData("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113",
+ "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9",
+ "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb"),
+ new Metadata(publicAddress.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v1, false, publicAddress.getMetadata().getServerTimeOffset()),
+ new NodesData(publicAddress.getNodesData().getNodeIndexes())
+ ));
}
-
@DisplayName("Fetch User Type and Public Address")
@Test
- public void shouldFetchUserTypeAndPublicAddress() throws ExecutionException, InterruptedException {
- VerifierArgs args = new VerifierArgs("tkey-google-celeste", TORUS_TEST_EMAIL);
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(args.getVerifier(), args.getVerifierId()).get();
- TorusPublicKey key = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), args).get();
- assertEquals("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", key.getAddress());
- assertEquals(TypeOfUser.v1, key.getTypeOfUser());
+ public void shouldFetchUserTypeAndPublicAddress() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("tkey-google-celeste", TORUS_TEST_EMAIL).get();
+ TorusPublicKey key = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), "tkey-google-celeste", TORUS_TEST_EMAIL, null);
+ assertEquals("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", key.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v1, key.getMetadata().getTypeOfUser());
+ assertThat(key).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113",
+ "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9",
+ "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb"),
+ new FinalPubKeyData("0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113",
+ "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9",
+ "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb"),
+ new Metadata(key.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v1, false, key.getMetadata().getServerTimeOffset()),
+ new NodesData(key.getNodesData().getNodeIndexes())
+ ));
String v2Verifier = "tkey-google-celeste";
// 1/1 user
String v2TestEmail = "somev2user@gmail.com";
- TorusPublicKey key2 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs(v2Verifier, v2TestEmail)).get();
- assertEquals("0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2", key2.getAddress());
- assertEquals(TypeOfUser.v2, key2.getTypeOfUser());
+ TorusPublicKey key2 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), v2Verifier, v2TestEmail, null);
+ assertEquals("0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2", key2.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key2.getMetadata().getTypeOfUser());
+ assertThat(key2).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xda4afB35493094Dd2C05b186Ca0FABAD96491B21",
+ "cfa646a2949ebe559205c5c407d734d1b6927f2ea5fbeabfcbc31ab9a985a336",
+ "8f988eb8b59515293820aa38af172b153e8d25307db8d5f410407c20e062b6e6"),
+ new FinalPubKeyData("0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2",
+ "5962144e03b993b0e503eb4e6e0196427f9fc9472f0dfd1be2ca5d4939f91680",
+ "f6e81f01f483110badab18371237d15834f9ecf31c3588c165dae32ec446ac38"),
+ new Metadata(new PubNonce("2f630074151394ba1f715986a9215f4e36c9f22fc264ff880ef6d162c1300aa8",
+ "704cb63e5f7a291735c54e22242ef53673642ec1660da00f1abc2e7909da03d7"),
+ BigInteger.ZERO, TypeOfUser.v2,
+ false,
+ key2.getMetadata().getServerTimeOffset()),
+ new NodesData(key2.getNodesData().getNodeIndexes())
+ ));
// 2/n user
String v2nTestEmail = "caspertorus@gmail.com";
- TorusPublicKey key3 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs(v2Verifier, v2nTestEmail)).get();
- assertEquals("0x8108c29976C458e76f797AD55A3715Ce80a3fe78", key3.getAddress());
- assertEquals(TypeOfUser.v2, key3.getTypeOfUser());
+ TorusPublicKey key3 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), v2Verifier, v2nTestEmail, null);
+ assertEquals("0x8108c29976C458e76f797AD55A3715Ce80a3fe78", key3.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key3.getMetadata().getTypeOfUser());
+ assertThat(key3).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xc8c4748ec135196fb482C761da273C31Ec48B099",
+ "0cc857201e6c304dd893b243e323fe95982e5a99c0994cf902efa2432a672eb4",
+ "37a2f53c250b3e1186e38ece3dfcbcb23e325913038703531831b96d3e7b54cc"),
+ new FinalPubKeyData("0x8108c29976C458e76f797AD55A3715Ce80a3fe78",
+ "e95fe2d595ade03f56d9c9a147fbb67705041704f147576fa4a8afbe7dc69470",
+ "3e20e4b331466769c4dd78f4561bfb2849010b4005b09c2ed082380326724ebe"),
+ new Metadata(new PubNonce("f8ff2c44cc0abf512d35b35c3c5cbc0eda700d49bc13b72c5492b0cdb2ca3619",
+ "88fb3087cec269c8c39d25b04f15298d33712f13b0f9665821328dfc7a567afb"), BigInteger.ZERO,
+ TypeOfUser.v2, false, key3.getMetadata().getServerTimeOffset()),
+ new NodesData(key3.getNodesData().getNodeIndexes())
+ ));
}
@DisplayName("Key Assign test")
@Test
- public void shouldKeyAssign() throws ExecutionException, InterruptedException {
+ public void shouldKeyAssign() throws Exception {
String email = JwtUtils.getRandomEmail();
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("tkey-google-celeste", email).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs("tkey-google-celeste", email)).get();
- System.out.println(email + " -> " + publicAddress.getAddress());
- assertNotNull(publicAddress.getAddress());
- assertNotEquals(publicAddress.getAddress(), "");
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(),
+ "tkey-google-celeste", email, "");
+ assertNotNull(publicAddress.getFinalKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getFinalKeyData().getWalletAddress(), "");
+ assertNotNull(publicAddress.getoAuthKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getoAuthKeyData().getWalletAddress(), "");
+ assertFalse(publicAddress.getMetadata().isUpgraded());
}
@DisplayName("Login test")
@Test
- public void shouldLogin() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldLogin() throws Exception {
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_VERIFIER, new HashMap() {{
- put("verifier_id", TORUS_TEST_EMAIL);
- }}, JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs)).get();
- System.out.println(retrieveSharesResponse.getPrivKey());
- BigInteger requiredPrivateKey = new BigInteger("0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914", 16);
- assert (requiredPrivateKey.equals(retrieveSharesResponse.getPrivKey()));
- assertEquals("0x58420FB83971C4490D8c9B091f8bfC890D716617", retrieveSharesResponse.getEthAddress());
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_VERIFIER, verifierParams,
+ JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs), null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assert ((torusKey.getFinalKeyData().getWalletAddress() != null) && torusKey.getFinalKeyData().getWalletAddress().equals("0x58420FB83971C4490D8c9B091f8bfC890D716617"));
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x58420FB83971C4490D8c9B091f8bfC890D716617",
+ "73b82ce0f8201a962636d404fe7a683f37c2267a9528576e1dac9964940add74",
+ "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1",
+ "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914"),
+ new OAuthKeyData("0x58420FB83971C4490D8c9B091f8bfC890D716617",
+ "73b82ce0f8201a962636d404fe7a683f37c2267a9528576e1dac9964940add74",
+ "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1",
+ "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(null, BigInteger.ZERO, TypeOfUser.v1, null, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
@DisplayName("Aggregate Login test")
@Test
- public void shouldAggregateLogin() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldAggregateLogin() throws Exception {
String idToken = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
- String hashedIdToken = Hash.sha3String(idToken).substring(2);
+ String hashedIdToken = Hash.sha3String(idToken).replace("0x", "");
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, new String[]{TORUS_TEST_VERIFIER}, new VerifyParams[]{new VerifyParams(TORUS_TEST_EMAIL, idToken)});
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_AGGREGATE_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_AGGREGATE_VERIFIER, new HashMap() {{
- put("verify_params", new VerifyParams[]{new VerifyParams(idToken, TORUS_TEST_EMAIL)});
- put("sub_verifier_ids", new String[]{TORUS_TEST_VERIFIER});
- put("verifier_id", TORUS_TEST_EMAIL);
- }}, hashedIdToken).get();
- assertEquals("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564", retrieveSharesResponse.getEthAddress());
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_AGGREGATE_VERIFIER, verifierParams,
+ hashedIdToken, null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564", torusKey.getoAuthKeyData().getWalletAddress());
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564",
+ "df6eb11d52e76b388a44896e9442eda17096c2b67b0be957a4ba0b68a70111ca",
+ "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb",
+ "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e"),
+ new OAuthKeyData("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564",
+ "df6eb11d52e76b388a44896e9442eda17096c2b67b0be957a4ba0b68a70111ca",
+ "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb",
+ "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(null, BigInteger.ZERO, TypeOfUser.v1, null, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
}
-
diff --git a/src/test/java/org/torusresearch/torusutilstest/CyanTest.java b/src/test/java/org/torusresearch/torusutilstest/CyanTest.java
index a5e6a9b..d0aa716 100644
--- a/src/test/java/org/torusresearch/torusutilstest/CyanTest.java
+++ b/src/test/java/org/torusresearch/torusutilstest/CyanTest.java
@@ -1,27 +1,38 @@
package org.torusresearch.torusutilstest;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.auth0.jwt.algorithms.Algorithm;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.torusresearch.fetchnodedetails.FetchNodeDetails;
import org.torusresearch.fetchnodedetails.types.NodeDetails;
import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
import org.torusresearch.torusutils.TorusUtils;
-import org.torusresearch.torusutils.types.RetrieveSharesResponse;
-import org.torusresearch.torusutils.types.TorusCtorOptions;
-import org.torusresearch.torusutils.types.TorusException;
-import org.torusresearch.torusutils.types.TorusPublicKey;
-import org.torusresearch.torusutils.types.TypeOfUser;
-import org.torusresearch.torusutils.types.VerifierArgs;
+import org.torusresearch.torusutils.helpers.TorusUtilError;
+import org.torusresearch.torusutils.types.FinalKeyData;
+import org.torusresearch.torusutils.types.FinalPubKeyData;
+import org.torusresearch.torusutils.types.Metadata;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthKeyData;
+import org.torusresearch.torusutils.types.OAuthPubKeyData;
+import org.torusresearch.torusutils.types.SessionData;
+import org.torusresearch.torusutils.types.VerifierParams;
+import org.torusresearch.torusutils.types.VerifyParams;
+import org.torusresearch.torusutils.types.common.PubNonce;
+import org.torusresearch.torusutils.types.common.TorusKey;
+import org.torusresearch.torusutils.types.common.TorusOptions;
+import org.torusresearch.torusutils.types.common.TorusPublicKey;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
import org.torusresearch.torusutilstest.utils.JwtUtils;
import org.torusresearch.torusutilstest.utils.PemUtils;
-import org.torusresearch.torusutilstest.utils.VerifyParams;
import org.web3j.crypto.Hash;
import java.io.IOException;
@@ -32,8 +43,6 @@
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
-import java.util.HashMap;
-import java.util.concurrent.ExecutionException;
public class CyanTest {
@@ -47,14 +56,10 @@ public class CyanTest {
static String TORUS_TEST_EMAIL = "hello@tor.us";
- @BeforeAll
- static void setup() throws ExecutionException, InterruptedException, IOException, NoSuchAlgorithmException, InvalidKeySpecException {
- System.out.println("Setup Starting");
+ @BeforeEach
+ void setup() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, TorusUtilError {
fetchNodeDetails = new FetchNodeDetails(Web3AuthNetwork.CYAN);
- TorusCtorOptions opts = new TorusCtorOptions("Custom", "YOUR_CLIENT_ID");
- opts.setNetwork("cyan");
- opts.setSignerHost("https://signer-polygon.tor.us/api/sign");
- opts.setAllowHost("https://signer-polygon.tor.us/api/allow");
+ TorusOptions opts = new TorusOptions("YOUR_CLIENT_ID", Web3AuthNetwork.CYAN, null, 0, false);
torusUtils = new TorusUtils(opts);
ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromFile("src/test/java/org/torusresearch/torusutilstest/keys/key.pem", "EC");
ECPublicKey publicKey = (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(new ECPublicKeySpec(privateKey.getParams().getGenerator(), privateKey.getParams()));
@@ -63,71 +68,139 @@ static void setup() throws ExecutionException, InterruptedException, IOException
@DisplayName("Gets Public Address")
@Test
- public void shouldGetPublicAddress() throws ExecutionException, InterruptedException {
- VerifierArgs args = new VerifierArgs("tkey-google-cyan", TORUS_TEST_EMAIL);
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(args.getVerifier(), args.getVerifierId()).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), args).get();
- assertEquals("0xA3767911A84bE6907f26C572bc89426dDdDB2825", publicAddress.getAddress());
+ public void shouldGetPublicAddress() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("tkey-google-cyan", TORUS_TEST_EMAIL).get();
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), "tkey-google-cyan", TORUS_TEST_EMAIL, null);
+ assertEquals("0xA3767911A84bE6907f26C572bc89426dDdDB2825", publicAddress.getFinalKeyData().getWalletAddress());
+ assertTrue(publicAddress.getMetadata().getServerTimeOffset() < 20);
+ assertThat(publicAddress).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xA3767911A84bE6907f26C572bc89426dDdDB2825",
+ "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a",
+ "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1"),
+ new FinalPubKeyData("0xA3767911A84bE6907f26C572bc89426dDdDB2825",
+ "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a",
+ "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1"),
+ new Metadata(publicAddress.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v1, false, publicAddress.getMetadata().getServerTimeOffset()),
+ new NodesData(publicAddress.getNodesData().getNodeIndexes())
+ ));
}
@DisplayName("Fetch User Type and Public Address")
@Test
- public void shouldFetchUserTypeAndPublicAddress() throws ExecutionException, InterruptedException {
- VerifierArgs args = new VerifierArgs("tkey-google-cyan", TORUS_TEST_EMAIL);
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(args.getVerifier(), args.getVerifierId()).get();
- TorusPublicKey key = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), args).get();
- assertEquals("0x3507F0d192a44E436B8a6C32a37d57D022861b1a", key.getAddress());
- assertEquals(TypeOfUser.v2, key.getTypeOfUser());
+ public void shouldFetchUserTypeAndPublicAddress() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("tkey-google-cyan", TORUS_TEST_EMAIL).get();
+ TorusPublicKey key = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), "tkey-google-cyan", TORUS_TEST_EMAIL, null);
+ assertEquals("0x3507F0d192a44E436B8a6C32a37d57D022861b1a", key.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key.getMetadata().getTypeOfUser());
+ assertThat(key).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xA3767911A84bE6907f26C572bc89426dDdDB2825",
+ "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a",
+ "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1"),
+ new FinalPubKeyData("0x3507F0d192a44E436B8a6C32a37d57D022861b1a",
+ "8aaadab9530cb157d0b0dfb7b27d1a3aaca45274563c22c92c77ee2191779051",
+ "d57b89d9f62bb6609d8542c3057943805c8c72f6f27d39781b820f27d7210f12"),
+ new Metadata(key.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v2, false, key.getMetadata().getServerTimeOffset()),
+ new NodesData(key.getNodesData().getNodeIndexes())
+ ));
String v2Verifier = "tkey-google-cyan";
// 1/1 user
String v2TestEmail = "somev2user@gmail.com";
- TorusPublicKey key2 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs(v2Verifier, v2TestEmail)).get();
- assertEquals("0x8EA83Ace86EB414747F2b23f03C38A34E0217814", key2.getAddress());
- assertEquals(TypeOfUser.v2, key2.getTypeOfUser());
+ TorusPublicKey key2 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), v2Verifier, v2TestEmail, null);
+ assertThat(key2).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x29446f428293a4E6470AEaEDa6EAfA0F842EF54e",
+ "8b6f2048aba8c7833e3b02c5b6522bb18c484ad0025156e428f17fb8d8c34021",
+ "cd9ba153ff89d665f655d1be4c6912f3ff93996e6fe580d89e78bf1476fef2aa"),
+ new FinalPubKeyData("0x8EA83Ace86EB414747F2b23f03C38A34E0217814",
+ "cbe7b0f0332e5583c410fcacb6d4ff685bec053cfd943ac75f5e4aa3278a6fbb",
+ "b525c463f438c7a3c4b018c8c5d16c9ef33b9ac6f319140a22b48b17bdf532dd"),
+ new Metadata(new PubNonce("da0039dd481e140090bed9e777ce16c0c4a16f30f47e8b08b73ac77737dd2d4",
+ "7fecffd2910fa47dbdbc989f5c119a668fc922937175974953cbb51c49268265"
+ ), BigInteger.ZERO, TypeOfUser.v2, false, key2.getMetadata().getServerTimeOffset()),
+ new NodesData(key2.getNodesData().getNodeIndexes())
+ ));
+ assertEquals("0x8EA83Ace86EB414747F2b23f03C38A34E0217814", key2.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key2.getMetadata().getTypeOfUser());
// 2/n user
String v2nTestEmail = "caspertorus@gmail.com";
- TorusPublicKey key3 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs(v2Verifier, v2nTestEmail)).get();
- assertEquals("0xCC1f953f6972a9e3d685d260399D6B85E2117561", key3.getAddress());
- assertEquals(TypeOfUser.v2, key3.getTypeOfUser());
+ TorusPublicKey key3 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), v2Verifier, v2nTestEmail, null);
+ assertThat(key3).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xe8a19482cbe5FaC896A5860Ca4156fb999DDc73b",
+ "c491ba39155594896b27cf71a804ccf493289d918f40e6ba4d590f1c76139e9e",
+ "d4649ed9e46461e1af00399a4c65fabb1dc219b3f4af501a7d635c17f57ab553"),
+ new FinalPubKeyData("0xCC1f953f6972a9e3d685d260399D6B85E2117561",
+ "8d784434becaad9b23d9293d1f29c4429447315c4cac824cbf2eb21d3f7d79c8",
+ "fe46a0ef5efe33d16f6cfa678a597be930fbec5432cbb7f3580189c18bd7e157"),
+ new Metadata(new PubNonce("50e250cc6ac1d50d32d2b0f85f11c6625a917a115ced4ef24f4eac183e1525c7",
+ "8067a52d02b8214bf82e91b66ce5009f674f4c3998b103059c46c386d0c17f90"
+ ), BigInteger.ZERO, TypeOfUser.v2, false, key3.getMetadata().getServerTimeOffset()),
+ new NodesData(key3.getNodesData().getNodeIndexes())
+ ));
+ assertEquals("0xCC1f953f6972a9e3d685d260399D6B85E2117561", key3.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key3.getMetadata().getTypeOfUser());
}
@DisplayName("Key Assign test")
@Test
- public void shouldKeyAssign() throws ExecutionException, InterruptedException {
+ public void shouldKeyAssign() throws Exception {
String email = JwtUtils.getRandomEmail();
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("tkey-google-cyan", email).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs("tkey-google-cyan", email)).get();
- System.out.println(email + " -> " + publicAddress.getAddress());
- assertNotNull(publicAddress.getAddress());
- assertNotEquals(publicAddress.getAddress(), "");
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), "tkey-google-cyan", email, null);
+ assertNotNull(publicAddress.getFinalKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getFinalKeyData().getWalletAddress(), "");
+ assertNotNull(publicAddress.getoAuthKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getoAuthKeyData().getWalletAddress(), "");
+ assertFalse(publicAddress.getMetadata().isUpgraded());
}
@DisplayName("Login test")
@Test
- public void shouldLogin() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldLogin() throws Exception {
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_VERIFIER, new HashMap() {{
- put("verifier_id", TORUS_TEST_EMAIL);
- }}, JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs)).get();
- System.out.println(retrieveSharesResponse.getPrivKey());
- BigInteger requiredPrivateKey = new BigInteger("42385046760370370667571434468449261359414980205144543049037030193411736357576", 10);
- assert (requiredPrivateKey.equals(retrieveSharesResponse.getPrivKey()));
- assertEquals("0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9", retrieveSharesResponse.getEthAddress());
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_VERIFIER,
+ verifierParams, JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs), null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assert ((torusKey.getFinalKeyData().getPrivKey() != null) && torusKey.getFinalKeyData().getPrivKey().equals("5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8"));
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9",
+ "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1",
+ "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359",
+ "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8"),
+ new OAuthKeyData("0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9",
+ "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1",
+ "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359",
+ "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(null, BigInteger.ZERO, TypeOfUser.v1, null, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
@DisplayName("Aggregate Login test")
@Test
- public void shouldAggregateLogin() throws ExecutionException, InterruptedException {
+ public void shouldAggregateLogin() throws Exception {
String idToken = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
- String hashedIdToken = Hash.sha3String(idToken).substring(2);
+ String hashedIdToken = Hash.sha3String(idToken).replace("0x","");
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, new String[]{TORUS_TEST_VERIFIER}, new VerifyParams[]{new VerifyParams(TORUS_TEST_EMAIL, idToken)});
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_AGGREGATE_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_AGGREGATE_VERIFIER, new HashMap() {{
- put("verify_params", new VerifyParams[]{new VerifyParams(idToken, TORUS_TEST_EMAIL)});
- put("sub_verifier_ids", new String[]{TORUS_TEST_VERIFIER});
- put("verifier_id", TORUS_TEST_EMAIL);
- }}, hashedIdToken).get();
- assertEquals("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04", retrieveSharesResponse.getEthAddress());
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_AGGREGATE_VERIFIER,
+ verifierParams, hashedIdToken, null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04", torusKey.getoAuthKeyData().getWalletAddress());
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04",
+ "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223",
+ "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd",
+ "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf"),
+ new OAuthKeyData("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04",
+ "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223",
+ "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd",
+ "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(null, BigInteger.ZERO, TypeOfUser.v1, null, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
}
diff --git a/src/test/java/org/torusresearch/torusutilstest/MainnetTest.java b/src/test/java/org/torusresearch/torusutilstest/MainnetTest.java
index e31ae80..d098029 100644
--- a/src/test/java/org/torusresearch/torusutilstest/MainnetTest.java
+++ b/src/test/java/org/torusresearch/torusutilstest/MainnetTest.java
@@ -1,27 +1,37 @@
package org.torusresearch.torusutilstest;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.auth0.jwt.algorithms.Algorithm;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.torusresearch.fetchnodedetails.FetchNodeDetails;
import org.torusresearch.fetchnodedetails.types.NodeDetails;
import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
import org.torusresearch.torusutils.TorusUtils;
-import org.torusresearch.torusutils.types.RetrieveSharesResponse;
-import org.torusresearch.torusutils.types.TorusCtorOptions;
-import org.torusresearch.torusutils.types.TorusException;
-import org.torusresearch.torusutils.types.TorusPublicKey;
-import org.torusresearch.torusutils.types.TypeOfUser;
-import org.torusresearch.torusutils.types.VerifierArgs;
+import org.torusresearch.torusutils.helpers.TorusUtilError;
+import org.torusresearch.torusutils.types.FinalKeyData;
+import org.torusresearch.torusutils.types.FinalPubKeyData;
+import org.torusresearch.torusutils.types.Metadata;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthKeyData;
+import org.torusresearch.torusutils.types.OAuthPubKeyData;
+import org.torusresearch.torusutils.types.SessionData;
+import org.torusresearch.torusutils.types.VerifierParams;
+import org.torusresearch.torusutils.types.VerifyParams;
+import org.torusresearch.torusutils.types.common.TorusKey;
+import org.torusresearch.torusutils.types.common.TorusOptions;
+import org.torusresearch.torusutils.types.common.TorusPublicKey;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
import org.torusresearch.torusutilstest.utils.JwtUtils;
import org.torusresearch.torusutilstest.utils.PemUtils;
-import org.torusresearch.torusutilstest.utils.VerifyParams;
import org.web3j.crypto.Hash;
import java.io.IOException;
@@ -32,8 +42,6 @@
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
-import java.util.HashMap;
-import java.util.concurrent.ExecutionException;
public class MainnetTest {
@@ -47,12 +55,10 @@ public class MainnetTest {
static String TORUS_TEST_EMAIL = "hello@tor.us";
- @BeforeAll
- static void setup() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
- System.out.println("Setup Starting");
+ @BeforeEach
+ void setup() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, TorusUtilError {
fetchNodeDetails = new FetchNodeDetails(Web3AuthNetwork.MAINNET);
- TorusCtorOptions opts = new TorusCtorOptions("Custom", "YOUR_CLIENT_ID");
- opts.setNetwork("mainnet");
+ TorusOptions opts = new TorusOptions("YOUR_CLIENT_ID", Web3AuthNetwork.MAINNET, null, 0, false);
torusUtils = new TorusUtils(opts);
ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromFile("src/test/java/org/torusresearch/torusutilstest/keys/key.pem", "EC");
ECPublicKey publicKey = (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(new ECPublicKeySpec(privateKey.getParams().getGenerator(), privateKey.getParams()));
@@ -61,72 +67,136 @@ static void setup() throws IOException, NoSuchAlgorithmException, InvalidKeySpec
@DisplayName("Gets Public Address")
@Test
- public void shouldGetPublicAddress() throws ExecutionException, InterruptedException {
- VerifierArgs args = new VerifierArgs("google", TORUS_TEST_EMAIL);
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(args.getVerifier(), args.getVerifierId()).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), args).get();
- assertEquals("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", publicAddress.getAddress());
+ public void shouldGetPublicAddress() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("google", TORUS_TEST_EMAIL).get();
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), "google", TORUS_TEST_EMAIL, null);
+ assertEquals("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", publicAddress.getFinalKeyData().getWalletAddress());
+ assertTrue(publicAddress.getMetadata().getServerTimeOffset() < 20);
+ assertThat(publicAddress).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A",
+ "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4",
+ "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1"),
+ new FinalPubKeyData("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A",
+ "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4",
+ "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1"),
+ new Metadata(publicAddress.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v1, false, publicAddress.getMetadata().getServerTimeOffset()),
+ new NodesData(publicAddress.getNodesData().getNodeIndexes())
+ ));
}
-
@DisplayName("Fetch User Type and Public Address")
@Test
- public void shouldFetchUserTypeAndPublicAddress() throws ExecutionException, InterruptedException {
- VerifierArgs args = new VerifierArgs("google", TORUS_TEST_EMAIL);
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(args.getVerifier(), args.getVerifierId()).get();
- TorusPublicKey key = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), args).get();
- assertEquals("0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E", key.getAddress());//0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A
- assertEquals(TypeOfUser.v2, key.getTypeOfUser());
+ public void shouldFetchUserTypeAndPublicAddress() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("google", TORUS_TEST_EMAIL).get();
+ TorusPublicKey key = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), "google", TORUS_TEST_EMAIL, null);
+ assertEquals("0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E", key.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key.getMetadata().getTypeOfUser());
+ assertThat(key).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A",
+ "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4",
+ "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1"),
+ new FinalPubKeyData("0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E",
+ "072beda348a832aed06044a258cb6a8d428ec7c245c5da92db5da4f3ab433e55",
+ "54ace0d3df2504fa29f17d424a36a0f92703899fad0afee93d010f6d84b310e5"),
+ new Metadata(key.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v2, false, key.getMetadata().getServerTimeOffset()),
+ new NodesData(key.getNodesData().getNodeIndexes())
+ ));
String v2Verifier = "tkey-google";
// 1/1 user
String v2TestEmail = "somev2user@gmail.com";
- TorusPublicKey key2 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs(v2Verifier, v2TestEmail)).get();
- assertEquals("0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526", key2.getAddress());
- assertEquals(TypeOfUser.v2, key2.getTypeOfUser());
+ TorusPublicKey key2 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), v2Verifier, v2TestEmail, null);
+ assertEquals("0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526", key2.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key2.getMetadata().getTypeOfUser());
+ assertThat(key2).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xA9c6829e4899b6D630130ebf59D046CA868D7f83",
+ "5566cd940ea540ba1a3ba2ff0f5fd3d9a3a74350ac3baf47b811592ae6ea1c30",
+ "07a302e87e8d9eb5d143f570c248657288c13c09ecbe1e3a8720449daf9315b0"),
+ new FinalPubKeyData("0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526",
+ "bbfd26b1e61572c4e991a21b64f12b313cb6fce6b443be92d4d5fd8f311e8f33",
+ "df2c905356ec94faaa111a886be56ed6fa215b7facc1d1598486558355123c25"),
+ new Metadata(key2.getMetadata().getPubNonce(),
+ BigInteger.ZERO, TypeOfUser.v2, false, key2.getMetadata().getServerTimeOffset()),
+ new NodesData(key2.getNodesData().getNodeIndexes())
+ ));
// v1 user
String v2nTestEmail = "caspertorus@gmail.com";
- TorusPublicKey key3 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs(v2Verifier, v2nTestEmail)).get();
- assertEquals("0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD", key3.getAddress());
- assertEquals(TypeOfUser.v2, key3.getTypeOfUser());
+ TorusPublicKey key3 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), v2Verifier, v2nTestEmail, null);
+ assertEquals("0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD", key3.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key3.getMetadata().getTypeOfUser());
+ assertThat(key3).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53",
+ "c01282dd68d2341031a1cff06f70d821cad45140f425f1c25055a8aa64959df8",
+ "cb3937773bb819d60b780b6d4c2edcf27c0f7090ba1fc2ff42504a8138a8e2d7"),
+ new FinalPubKeyData("0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD",
+ "6779af3031d9e9eec6b4133b0ae13e367c83a614f92d2008e10c7f3b8e6723bc",
+ "80edc4502abdfb220dd6e2fcfa2dbb058125dc95873e4bfa6877f9c26da7fdff"),
+ new Metadata(key3.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v2, false, key3.getMetadata().getServerTimeOffset()),
+ new NodesData(key3.getNodesData().getNodeIndexes())
+ ));
}
@DisplayName("Key Assign test")
@Test
- public void shouldKeyAssign() throws ExecutionException, InterruptedException {
+ public void shouldKeyAssign() throws Exception {
String email = JwtUtils.getRandomEmail();
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("google", email).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs("google", email)).get();
- System.out.println(email + " -> " + publicAddress.getAddress());
- assertNotNull(publicAddress.getAddress());
- assertNotEquals(publicAddress.getAddress(), "");
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), "google", email, "");
+ assertNotNull(publicAddress.getFinalKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getFinalKeyData().getWalletAddress(), "");
+ assertNotNull(publicAddress.getoAuthKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getoAuthKeyData().getWalletAddress(), "");
+ assertFalse(publicAddress.getMetadata().isUpgraded());
}
@DisplayName("Login test")
@Test
- public void shouldLogin() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldLogin() throws Exception {
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_VERIFIER, new HashMap() {{
- put("verifier_id", TORUS_TEST_EMAIL);
- }}, JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs)).get();
- System.out.println(retrieveSharesResponse.getPrivKey());
- BigInteger requiredPrivateKey = new BigInteger("129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44", 16);
- assert (requiredPrivateKey.equals(retrieveSharesResponse.getPrivKey()));
- assertEquals("0x90A926b698047b4A87265ba1E9D8b512E8489067", retrieveSharesResponse.getEthAddress());
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_VERIFIER,
+ verifierParams, JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs), null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assert ((torusKey.getFinalKeyData().getPrivKey() != null) && torusKey.getFinalKeyData().getPrivKey().equals("0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44"));
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x90A926b698047b4A87265ba1E9D8b512E8489067",
+ "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f",
+ "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1",
+ "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44"),
+ new OAuthKeyData("0x90A926b698047b4A87265ba1E9D8b512E8489067",
+ "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f",
+ "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1",
+ "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(null, BigInteger.ZERO, TypeOfUser.v1, null, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
@DisplayName("Aggregate Login test")
@Test
- public void shouldAggregateLogin() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldAggregateLogin() throws Exception {
String idToken = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
- String hashedIdToken = Hash.sha3String(idToken).substring(2);
+ String hashedIdToken = Hash.sha3String(idToken).replace("0x","");
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, new String[]{TORUS_TEST_VERIFIER}, new VerifyParams[]{new VerifyParams(TORUS_TEST_EMAIL, idToken)});
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_AGGREGATE_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_AGGREGATE_VERIFIER, new HashMap() {{
- put("verify_params", new VerifyParams[]{new VerifyParams(idToken, TORUS_TEST_EMAIL)});
- put("sub_verifier_ids", new String[]{TORUS_TEST_VERIFIER});
- put("verifier_id", TORUS_TEST_EMAIL);
- }}, hashedIdToken).get();
- assertEquals("0x621a4d458cFd345dAE831D9E756F10cC40A50381", retrieveSharesResponse.getEthAddress());
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_AGGREGATE_VERIFIER,
+ verifierParams, hashedIdToken, null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0x621a4d458cFd345dAE831D9E756F10cC40A50381", torusKey.getoAuthKeyData().getWalletAddress());
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x621a4d458cFd345dAE831D9E756F10cC40A50381",
+ "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236",
+ "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e",
+ "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534"),
+ new OAuthKeyData("0x621a4d458cFd345dAE831D9E756F10cC40A50381",
+ "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236",
+ "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e",
+ "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(null, BigInteger.ZERO, TypeOfUser.v1, null, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
}
diff --git a/src/test/java/org/torusresearch/torusutilstest/OneKeyTest.java b/src/test/java/org/torusresearch/torusutilstest/OneKeyTest.java
index 109306a..05d7df7 100644
--- a/src/test/java/org/torusresearch/torusutilstest/OneKeyTest.java
+++ b/src/test/java/org/torusresearch/torusutilstest/OneKeyTest.java
@@ -1,27 +1,38 @@
package org.torusresearch.torusutilstest;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.auth0.jwt.algorithms.Algorithm;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.torusresearch.fetchnodedetails.FetchNodeDetails;
import org.torusresearch.fetchnodedetails.types.NodeDetails;
import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
import org.torusresearch.torusutils.TorusUtils;
-import org.torusresearch.torusutils.types.RetrieveSharesResponse;
-import org.torusresearch.torusutils.types.TorusCtorOptions;
-import org.torusresearch.torusutils.types.TorusException;
-import org.torusresearch.torusutils.types.TorusPublicKey;
-import org.torusresearch.torusutils.types.TypeOfUser;
-import org.torusresearch.torusutils.types.VerifierArgs;
+import org.torusresearch.torusutils.helpers.TorusUtilError;
+import org.torusresearch.torusutils.types.FinalKeyData;
+import org.torusresearch.torusutils.types.FinalPubKeyData;
+import org.torusresearch.torusutils.types.Metadata;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthKeyData;
+import org.torusresearch.torusutils.types.OAuthPubKeyData;
+import org.torusresearch.torusutils.types.SessionData;
+import org.torusresearch.torusutils.types.VerifierParams;
+import org.torusresearch.torusutils.types.VerifyParams;
+import org.torusresearch.torusutils.types.common.PubNonce;
+import org.torusresearch.torusutils.types.common.TorusKey;
+import org.torusresearch.torusutils.types.common.TorusOptions;
+import org.torusresearch.torusutils.types.common.TorusPublicKey;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
import org.torusresearch.torusutilstest.utils.JwtUtils;
import org.torusresearch.torusutilstest.utils.PemUtils;
-import org.torusresearch.torusutilstest.utils.VerifyParams;
import org.web3j.crypto.Hash;
import java.io.IOException;
@@ -32,8 +43,6 @@
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
-import java.util.HashMap;
-import java.util.concurrent.ExecutionException;
public class OneKeyTest {
@@ -47,79 +56,151 @@ public class OneKeyTest {
static String TORUS_TEST_EMAIL = "hello@tor.us";
- @BeforeAll
- static void setup() throws ExecutionException, InterruptedException, IOException, NoSuchAlgorithmException, InvalidKeySpecException {
- System.out.println("Setup Starting");
+ @BeforeEach
+ void setup() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, TorusUtilError {
fetchNodeDetails = new FetchNodeDetails(Web3AuthNetwork.TESTNET);
- TorusCtorOptions opts = new TorusCtorOptions("Custom", "YOUR_CLIENT_ID");
- opts.setNetwork("testnet");
- opts.setEnableOneKey(true);
+ TorusOptions opts = new TorusOptions("YOUR_CLIENT_ID", Web3AuthNetwork.TESTNET, null, 0, true);
torusUtils = new TorusUtils(opts);
ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromFile("src/test/java/org/torusresearch/torusutilstest/keys/key.pem", "EC");
ECPublicKey publicKey = (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(new ECPublicKeySpec(privateKey.getParams().getGenerator(), privateKey.getParams()));
algorithmRs = Algorithm.ECDSA256(publicKey, privateKey);
}
- @DisplayName("Gets Public Address")
+ @DisplayName("should still fetch v1 address correctly")
@Test
- public void shouldGetPublicAddress() throws ExecutionException, InterruptedException {
- VerifierArgs args = new VerifierArgs(TORUS_TEST_VERIFIER, "Jonathan.Nolan@hotmail.com");
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(args.getVerifier(), args.getVerifierId()).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), args, true).get();
- assertEquals(TypeOfUser.v2, publicAddress.getTypeOfUser());
- assertEquals("0x2876820fd9536BD5dd874189A85d71eE8bDf64c2", publicAddress.getAddress());
+ public void shouldStillFetchV1AddressCorrectly() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("google-lrc", "himanshu@tor.us").get();
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), "google-lrc", "himanshu@tor.us", null);
+ assertThat(publicAddress).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xf1e76fcDD28b5AA06De01de508fF21589aB9017E",
+ "b3f2b4d8b746353fe670e0c39ac9adb58056d4d7b718d06b623612d4ec49268b",
+ "ac9f79dff78add39cdba380dbbf517c20cf2c1e06b32842a90a84a31f6eb9a9a"),
+ new FinalPubKeyData("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1",
+ "12f6b90d66bda29807cf9ff14b2e537c25080154fc4fafed446306e8356ff425",
+ "e7c92e164b83e1b53e41e5d87d478bb07d7b19d105143e426e1ef08f7b37f224"),
+ new Metadata(null, new BigInteger("186a20d9b00315855ff5622a083aca6b2d34ef66ef6e0a4de670f5b2fde37e0d", 16), TypeOfUser.v1, false, publicAddress.getMetadata().getServerTimeOffset()),
+ new NodesData(publicAddress.getNodesData().getNodeIndexes())
+ ));
+ assertEquals("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1", publicAddress.getFinalKeyData().getWalletAddress());
+ assertTrue(publicAddress.getMetadata().getServerTimeOffset() < 20);
+ }
+
+ @DisplayName("Login test v1")
+ @Test
+ public void shouldLoginV1() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_VERIFIER,
+ verifierParams, JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs), null);
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x53010055542cCc0f2b6715a5c53838eC4aC96EF7",
+ "3fa78a0bfb9ec48810bf1ee332360def2600c4aef528ff8b1e49a0d304722c91",
+ "46aaca39fc00c0f88f63a79989697c70eeeeec6489300c493dd07a5608ded0d4",
+ "296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4"),
+ new OAuthKeyData("0xEfd7eDAebD0D99D1B7C8424b54835457dD005Dc4",
+ "18409385c38e9729eb6b7837dc8f234256233ffab1ed7eeb1c23b230333396b4",
+ "17d35ffc722d7a8dd88353815e9553cacf567c5f3b8d082adac9d653367ce47a",
+ "068ee4f97468ef1ae95d18554458d372e31968190ae38e377be59d8b3c9f7a25"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(new PubNonce(
+ "8e8c399d8ba00ff88e6c42eb40c10661f822868ba2ad8fe12a8830e996b1e25d",
+ "554b12253694bf9eb98485441bba7ba220b78cb78ee21664e96f934d10b1494d"
+ ), new BigInteger("22d160abe5320fe2be52a57c7aca8fe5d7e5eff104ff4d2b32767e3344e040bf", 16), TypeOfUser.v2, false, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
+ assertEquals("296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4", torusKey.getFinalKeyData().getPrivKey());
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
}
@DisplayName("Key Assign test")
@Test
- public void shouldKeyAssign() throws ExecutionException, InterruptedException {
+ public void shouldKeyAssign() throws Exception {
String email = JwtUtils.getRandomEmail();
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, email).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs(TORUS_TEST_VERIFIER, email), true).get();
- System.out.println(email + " -> " + publicAddress.getAddress());
- assertNotNull(publicAddress.getAddress());
- assertNotEquals(publicAddress.getAddress(), "");
- assertEquals(TypeOfUser.v2, publicAddress.getTypeOfUser());
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_VERIFIER, email, null);
+ assertNotNull(publicAddress.getFinalKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getFinalKeyData().getWalletAddress(), "");
+ assertNotNull(publicAddress.getoAuthKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getoAuthKeyData().getWalletAddress(), "");
+ assertEquals(publicAddress.getMetadata().getTypeOfUser(), TypeOfUser.v2);
+ assertFalse(publicAddress.getMetadata().isUpgraded());
}
- @DisplayName("Login test v1")
@Test
- public void shouldLoginV1() throws ExecutionException, InterruptedException, TorusException {
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_VERIFIER, new HashMap() {{
- put("verifier_id", TORUS_TEST_EMAIL);
- }}, JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs)).get();
- System.out.println(retrieveSharesResponse.getPrivKey().toString(16));
- BigInteger requiredPrivateKey = new BigInteger("296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4", 16);
- assert (requiredPrivateKey.equals(retrieveSharesResponse.getPrivKey()));
- assertEquals("0x53010055542cCc0f2b6715a5c53838eC4aC96EF7", retrieveSharesResponse.getEthAddress());
+ public void testShouldBeAbleToKeyAssignViaLogin() throws Exception {
+ String fakeEmail = JwtUtils.getRandomEmail();
+ String verifier = TORUS_TEST_VERIFIER;
+ String jwt = JwtUtils.generateIdToken(fakeEmail, algorithmRs);
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(verifier, fakeEmail).get();
+ VerifierParams verifierParams = new VerifierParams(fakeEmail, null, null, null);
+ TorusKey data = torusUtils.retrieveShares(
+ nodeDetails.getTorusNodeEndpoints(),
+ verifier,
+ verifierParams,
+ jwt, null
+ );
+ assertEquals(data.getMetadata().getTypeOfUser(), TypeOfUser.v2);
+ assertNotEquals(data.getMetadata().getNonce(), BigInteger.ZERO);
+ assertFalse(data.getMetadata().isUpgraded());
+ assertNotEquals("", data.getFinalKeyData().getWalletAddress());
+ assertNotEquals("", data.getoAuthKeyData().getWalletAddress());
}
@DisplayName("Login test v2")
@Test
- public void shouldLoginV2() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldLoginV2() throws Exception {
String email = "Jonathan.Nolan@hotmail.com";
+ VerifierParams verifierParams = new VerifierParams(email, null, null, null);
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, email).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_VERIFIER, new HashMap() {{
- put("verifier_id", email);
- }}, JwtUtils.generateIdToken(email, algorithmRs)).get();
- BigInteger requiredPrivateKey = new BigInteger("9ec5b0504e252e35218c7ce1e4660eac190a1505abfbec7102946f92ed750075", 16);
- System.out.println(retrieveSharesResponse.getPrivKey().toString(16) + " priv key " + retrieveSharesResponse.getEthAddress() + " nonce " + retrieveSharesResponse.getNonce().toString(16));
- assert (requiredPrivateKey.equals(retrieveSharesResponse.getPrivKey()));
- assertEquals("0x2876820fd9536BD5dd874189A85d71eE8bDf64c2", retrieveSharesResponse.getEthAddress());
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_VERIFIER,
+ verifierParams, JwtUtils.generateIdToken(email, algorithmRs), null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals(torusKey.getFinalKeyData().getPrivKey(), "9ec5b0504e252e35218c7ce1e4660eac190a1505abfbec7102946f92ed750075");
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x2876820fd9536BD5dd874189A85d71eE8bDf64c2",
+ "ad4c223520aac9bc3ec72399869601fd59f29363471131914e2ed2bc4ba46e54",
+ "802c6e40b22b49b5ef73fa49b194c2037267215fa01683aa86746907aab37ae1",
+ "9ec5b0504e252e35218c7ce1e4660eac190a1505abfbec7102946f92ed750075"),
+ new OAuthKeyData("0x54de3Df0CA76AAe3e171FB410F0626Ab759f3c24",
+ "49d69b8550bb0eba77595c73bf57f0463ff96adf6b50d44f9e1bcf2b3fb7976e",
+ "d63bac65bdfc7484a28d4362347bbd098095db190c14a4ce9dbaafe74803eccc",
+ "f4b7e0fb1e6f6fbac539c55e22aff2900947de652d2d6254a9cd8709f505f83a"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(new PubNonce(
+ "f494a5bf06a2f0550aafb6aabeb495bd6ea3ef92eaa736819b5b0ad6bfbf1aab",
+ "35df3d3a14f88cbba0cfd092a1e5a0e4e725ba52a8d45719614555542d701f18"
+ ), new BigInteger("aa0dcf552fb5be7a5c52b783c1b61c1aca7113872e172a5818994715c8a5497c", 16), TypeOfUser.v2, false, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
@DisplayName("Aggregate Login test")
@Test
- public void shouldAggregateLogin() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldAggregateLogin() throws Exception {
String idToken = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
- String hashedIdToken = Hash.sha3String(idToken).substring(2);
+ String hashedIdToken = Hash.sha3String(idToken).replace("0x","");
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, new String[]{TORUS_TEST_VERIFIER}, new VerifyParams[]{new VerifyParams(TORUS_TEST_EMAIL, idToken)});
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_AGGREGATE_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_AGGREGATE_VERIFIER, new HashMap() {{
- put("verify_params", new VerifyParams[]{new VerifyParams(idToken, TORUS_TEST_EMAIL)});
- put("sub_verifier_ids", new String[]{TORUS_TEST_VERIFIER});
- put("verifier_id", TORUS_TEST_EMAIL);
- }}, hashedIdToken).get();
- assertEquals("0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B", retrieveSharesResponse.getEthAddress());
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_AGGREGATE_VERIFIER,
+ verifierParams, hashedIdToken, null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B", torusKey.getFinalKeyData().getWalletAddress());
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B",
+ "78658b2671f1bd6a488baf2afb8ce6f8d8b9a1a70842130b3c8756a9d51d9723",
+ "2e5840f47d645afa4bfe93c3715e65974051080d7a1e474eef8d68752924f4fb",
+ "ad47959db4cb2e63e641bac285df1b944f54d1a1cecdaeea40042b60d53c35d2"),
+ new OAuthKeyData("0x5a165d2Ed4976BD104caDE1b2948a93B72FA91D2",
+ "aba2b085ae6390b3eb26802c3239bb7e3b9ed8ea6e1dcc28aeb67432571f20fc",
+ "f1a2163cba5620b7b40241a6112e7918e9445b0b9cfbbb9d77b2de6f61ed5c27",
+ "d9733fc1098151f3e3289673e7c69c4ed46cbbdbc13416560e14741524d2d51a"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(new PubNonce(
+ "376c0ac5e15686633061cf5833dd040365f91377686d7ab5338c5202bd963a2f",
+ "794d7edb6a5ec0307dd40789274b377f37f293b0410a6cbd303db309536099b7"
+ ), new BigInteger("d3d455dcab49dc700319244e9e187f443596f2acbce238cff1c215d8809fa1f9", 16), TypeOfUser.v2, false, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
}
diff --git a/src/test/java/org/torusresearch/torusutilstest/SapphireDevnetTest.java b/src/test/java/org/torusresearch/torusutilstest/SapphireDevnetTest.java
new file mode 100644
index 0000000..be09475
--- /dev/null
+++ b/src/test/java/org/torusresearch/torusutilstest/SapphireDevnetTest.java
@@ -0,0 +1,399 @@
+package org.torusresearch.torusutilstest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.interfaces.Header;
+
+import org.bouncycastle.util.encoders.Hex;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.torusresearch.fetchnodedetails.FetchNodeDetails;
+import org.torusresearch.fetchnodedetails.types.NodeDetails;
+import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
+import org.torusresearch.torusutils.TorusUtils;
+import org.torusresearch.torusutils.helpers.Common;
+import org.torusresearch.torusutils.helpers.KeyUtils;
+import org.torusresearch.torusutils.helpers.TorusUtilError;
+import org.torusresearch.torusutils.types.FinalKeyData;
+import org.torusresearch.torusutils.types.FinalPubKeyData;
+import org.torusresearch.torusutils.types.Metadata;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthKeyData;
+import org.torusresearch.torusutils.types.OAuthPubKeyData;
+import org.torusresearch.torusutils.types.SessionData;
+import org.torusresearch.torusutils.types.VerifierParams;
+import org.torusresearch.torusutils.types.VerifyParams;
+import org.torusresearch.torusutils.types.common.PubNonce;
+import org.torusresearch.torusutils.types.common.SessionToken;
+import org.torusresearch.torusutils.types.common.TorusKey;
+import org.torusresearch.torusutils.types.common.TorusOptions;
+import org.torusresearch.torusutils.types.common.TorusPublicKey;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
+import org.torusresearch.torusutilstest.utils.JwtUtils;
+import org.torusresearch.torusutilstest.utils.PemUtils;
+import org.web3j.crypto.Hash;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Base64;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+public class SapphireDevnetTest {
+
+ static FetchNodeDetails fetchNodeDetails;
+
+ static TorusUtils torusUtils;
+ static Algorithm algorithmRs;
+
+ static String TORUS_TEST_VERIFIER = "torus-test-health";
+ static String TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate";
+ static String TORUS_TEST_EMAIL = "devnettestuser@tor.us";
+ static String TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierid@example.com";
+ static String HashEnabledVerifier = "torus-test-verifierid-hash";
+
+ @BeforeEach
+ void setup() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, TorusUtilError {
+ fetchNodeDetails = new FetchNodeDetails(Web3AuthNetwork.SAPPHIRE_DEVNET);
+ TorusOptions opts = new TorusOptions("YOUR_CLIENT_ID", Web3AuthNetwork.SAPPHIRE_DEVNET, null, 0, true);
+ torusUtils = new TorusUtils(opts);
+ ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromFile("src/test/java/org/torusresearch/torusutilstest/keys/key.pem", "EC");
+ ECPublicKey publicKey = (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(new ECPublicKeySpec(privateKey.getParams().getGenerator(), privateKey.getParams()));
+ algorithmRs = Algorithm.ECDSA256(publicKey, privateKey);
+ }
+
+ @DisplayName("Gets Public Address")
+ @Test
+ public void shouldGetPublicAddress() throws Exception {
+ String verifier = TORUS_TEST_VERIFIER;
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(verifier, TORUS_TEST_EMAIL).get();
+ TorusPublicKey torusPublicKey = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), verifier, TORUS_TEST_EMAIL, null);
+ assertTrue(torusPublicKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", torusPublicKey.getoAuthKeyData().getWalletAddress());
+ assertEquals("0x462A8BF111A55C9354425F875F89B22678c0Bc44", torusPublicKey.getFinalKeyData().getWalletAddress());
+ assertThat(torusPublicKey).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x137B3607958562D03Eb3C6086392D1eFa01aA6aa",
+ "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b",
+ "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5"),
+ new FinalPubKeyData("0x462A8BF111A55C9354425F875F89B22678c0Bc44",
+ "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1",
+ "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507"),
+ new Metadata(new PubNonce("5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc",
+ "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed"),
+ BigInteger.ZERO, TypeOfUser.v2, false, torusPublicKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusPublicKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @Test
+ public void testShouldBeAbleToImportKeyForANewUser() throws Exception {
+ String fakeEmail = JwtUtils.getRandomEmail();
+ String jwt = JwtUtils.generateIdToken(fakeEmail, algorithmRs);
+ String key = Common.trimLeadingZeros(Hex.toHexString(KeyUtils.serializePrivateKey(KeyUtils.generateKeyPair().getPrivate())));
+ String privateKey = Common.padLeft(key, '0', 64);
+ VerifierParams verifierParams = new VerifierParams(fakeEmail, null, null, null);
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, fakeEmail).get();
+
+ TorusKey val = torusUtils.importPrivateKey(
+ nodeDetails.getTorusNodeSSSEndpoints(),
+ nodeDetails.getTorusIndexes(),
+ nodeDetails.getTorusNodePub(),
+ TORUS_TEST_VERIFIER,
+ verifierParams,
+ jwt,
+ privateKey,
+ null
+ );
+
+ assertEquals(val.getFinalKeyData().getPrivKey(), privateKey);
+
+ jwt = JwtUtils.generateIdToken(fakeEmail, algorithmRs);
+ TorusKey shareRetrieval = torusUtils.retrieveShares(
+ nodeDetails.getTorusNodeSSSEndpoints(),
+ TORUS_TEST_VERIFIER,
+ verifierParams,
+ jwt, null
+ );
+ assertEquals(shareRetrieval.getFinalKeyData().getPrivKey(), privateKey);
+
+ TorusPublicKey addressRetrieval = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(),
+ TORUS_TEST_VERIFIER, fakeEmail, null);
+ String publicAddress = KeyUtils.privateToPublic(new BigInteger(privateKey, 16));
+ String retrievedAddress = KeyUtils.getPublicKeyFromCoords(
+ addressRetrieval.getFinalKeyData().getX(),
+ addressRetrieval.getFinalKeyData().getY(), true
+ );
+ assertEquals(publicAddress, retrievedAddress);
+
+ }
+
+ @DisplayName("should be able to key assign")
+ @Test
+ public void shouldKeyAssign() throws Exception {
+ String email = JwtUtils.getRandomEmail();
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, email).get();
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeSSSEndpoints(), TORUS_TEST_VERIFIER, email, null);
+ assertNotNull(publicAddress.getFinalKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getFinalKeyData().getWalletAddress(), "");
+ }
+
+ @DisplayName("should fetch public address of a legacy v1 user")
+ @Test
+ public void testFetchPublicAddressOfLegacyV1User() throws Exception {
+ fetchNodeDetails = new FetchNodeDetails(Web3AuthNetwork.TESTNET);
+ TorusOptions opts = new TorusOptions("YOUR_CLIENT_ID", Web3AuthNetwork.TESTNET, null, 0, true);
+ torusUtils = new TorusUtils(opts);
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("google-lrc", "himanshu@tor.us").get();
+ TorusPublicKey publicKeyData = torusUtils.getPublicAddress(nodeDetails.getTorusNodeSSSEndpoints(), "google-lrc", "himanshu@tor.us", null);
+ assertEquals(TypeOfUser.v1, publicKeyData.getMetadata().getTypeOfUser());
+ assertThat(publicKeyData).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xf1e76fcDD28b5AA06De01de508fF21589aB9017E",
+ "b3f2b4d8b746353fe670e0c39ac9adb58056d4d7b718d06b623612d4ec49268b",
+ "ac9f79dff78add39cdba380dbbf517c20cf2c1e06b32842a90a84a31f6eb9a9a"),
+ new FinalPubKeyData("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1",
+ "12f6b90d66bda29807cf9ff14b2e537c25080154fc4fafed446306e8356ff425",
+ "e7c92e164b83e1b53e41e5d87d478bb07d7b19d105143e426e1ef08f7b37f224"),
+ new Metadata(null, new BigInteger("186a20d9b00315855ff5622a083aca6b2d34ef66ef6e0a4de670f5b2fde37e0d", 16),
+ TypeOfUser.v1, false, publicKeyData.getMetadata().getServerTimeOffset()),
+ new NodesData(publicKeyData.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should keep public address same")
+ @Test
+ public void shouldKeyPublicAddressSame() throws Exception {
+ String email = JwtUtils.getRandomEmail();
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, email).get();
+ TorusPublicKey result1 = torusUtils.getPublicAddress(nodeDetails.getTorusNodeSSSEndpoints(), TORUS_TEST_VERIFIER, email, null);
+ TorusPublicKey result2 = torusUtils.getPublicAddress(nodeDetails.getTorusNodeSSSEndpoints(), TORUS_TEST_VERIFIER, email, null);
+ assertThat(result1.getFinalKeyData()).isEqualToComparingFieldByFieldRecursively(result2.getFinalKeyData());
+ assertThat(result1.getoAuthKeyData()).isEqualToComparingFieldByFieldRecursively(result2.getoAuthKeyData());
+ }
+
+ @DisplayName("should be able to key assign to tssVerifierId")
+ @Test
+ public void testShouldBeAbleToKeyAssignToTssVerifierId() throws Exception {
+ String fakeEmail = JwtUtils.getRandomEmail();
+ int nonce = 0;
+ String tssTag = "default";
+ String tssVerifierID = fakeEmail + "\u0015" + tssTag + "\u0016" + nonce;
+ String verifier = TORUS_TEST_VERIFIER;
+
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(verifier, fakeEmail).get();
+ TorusPublicKey torusPublicKey = torusUtils.getPublicAddress(
+ nodeDetails.getTorusNodeSSSEndpoints(),
+ verifier,
+ fakeEmail,
+ tssVerifierID
+ );
+
+ assertNotNull(torusPublicKey.getFinalKeyData().getWalletAddress());
+ assertNotEquals("", torusPublicKey.getFinalKeyData().getWalletAddress());
+ assertNotNull(torusPublicKey.getoAuthKeyData().getWalletAddress());
+ assertNotEquals("", torusPublicKey.getoAuthKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, torusPublicKey.getMetadata().getTypeOfUser());
+ assertFalse(torusPublicKey.getMetadata().isUpgraded());
+ }
+
+ @DisplayName("should fetch pubic address of tssVerifierId")
+ @Test
+ public void shouldFetchPubicAddressOfTssVerifierId() throws Exception {
+ String email = TORUS_EXTENDED_VERIFIER_EMAIL;
+ int nonce = 0;
+ String tssTag = "default";
+ String tssVerifierId = email + "\u0015" + tssTag + "\u0016" + nonce;
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, email).get();
+ TorusPublicKey torusPublicKey = torusUtils.getPublicAddress(nodeDetails.getTorusNodeSSSEndpoints(), TORUS_TEST_VERIFIER, email, tssVerifierId);
+ assertThat(torusPublicKey).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30",
+ "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c",
+ "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e"),
+ new FinalPubKeyData("0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30",
+ "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c",
+ "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e"),
+ new Metadata(torusPublicKey.getMetadata().getPubNonce(),
+ new BigInteger("0"), TypeOfUser.v2, false, torusPublicKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusPublicKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should allow test tssVerifier to fetch shares")
+ @Test
+ public void testShouldAllowTestTssVerifierToFetchShares() throws Exception {
+ String email = JwtUtils.getRandomEmail();
+ int nonce = 0;
+ String tssTag = "default";
+ String tssVerifierID = email + "\u0015" + tssTag + "\u0016" + nonce;
+ String verifier = TORUS_TEST_VERIFIER;
+ String token = JwtUtils.generateIdToken(email, algorithmRs);
+
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(verifier, email).get();
+ VerifierParams verifierParams = new VerifierParams(email, tssVerifierID, null, null);
+ TorusKey torusKey = torusUtils.retrieveShares(
+ nodeDetails.getTorusNodeSSSEndpoints(),
+ verifier,
+ verifierParams,
+ token, null
+ );
+ assertNotNull(torusKey.getFinalKeyData().getPrivKey());
+ assertNotNull(torusKey.getoAuthKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, torusKey.getMetadata().getTypeOfUser());
+ assertEquals(BigInteger.ZERO, torusKey.getMetadata().getNonce());
+ assertTrue(torusKey.getMetadata().isUpgraded());
+ }
+
+
+ @DisplayName("should fetch public address when verifierID is hash enabled")
+ @Test
+ public void shouldFetchPubAddressWhenVerfierIdIsHashEnabled() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(HashEnabledVerifier, TORUS_TEST_EMAIL).get();
+ String[] torusNodeEndpoints = nodeDetails.getTorusNodeSSSEndpoints();
+ TorusPublicKey torusPublicKey = torusUtils.getPublicAddress(torusNodeEndpoints, HashEnabledVerifier, TORUS_TEST_EMAIL, null);
+ assertEquals("0x8a7e297e20804786767B1918a5CFa11683e5a3BB", torusPublicKey.getFinalKeyData().getWalletAddress());
+ assertThat(torusPublicKey).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xaEafa3Fc7349E897F8fCe981f55bbD249f12aC8C",
+ "72d9172d7edc623266d6c625db91505e6b64a5524e6d7c7c0184b1bbdea1e986",
+ "8c26d557a0a9cb22dc2a30d36bf67de93a0eb6d4ef503a849c7de2d14dcbdaaa"),
+ new FinalPubKeyData("0x8a7e297e20804786767B1918a5CFa11683e5a3BB",
+ "7927d5281aea24fd93f41696f79c91370ec0097ff65e83e95691fffbde6d733a",
+ "f22735f0e72ff225274cf499d50b240b7571063e0584471b2b4dab337ad5d8da"),
+ new Metadata(new PubNonce("5712d789f7ecf3435dd9bf1136c2daaa634f0222d64e289d2abe30a729a6a22b",
+ "2d2b4586fd5fd9d15c22f66b61bc475742754a8b96d1edb7b2590e4c4f97b3f0"),
+ new BigInteger("0"), TypeOfUser.v2, false, torusPublicKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusPublicKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("Should fetch user type and public address when verifierID is hash enabled")
+ @Test
+ public void testFetchUserTypeAndPublicAddressWhenVerfierIdIsHashEnabled() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(HashEnabledVerifier, TORUS_TEST_EMAIL).get();
+ String[] torusNodeEndpoints = nodeDetails.getTorusNodeSSSEndpoints();
+ TorusPublicKey torusPublicKey = torusUtils.getPublicAddress(torusNodeEndpoints, HashEnabledVerifier, TORUS_TEST_EMAIL, null);
+ assertTrue(torusPublicKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0x8a7e297e20804786767B1918a5CFa11683e5a3BB", torusPublicKey.getFinalKeyData().getWalletAddress());
+ assertThat(torusPublicKey).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xaEafa3Fc7349E897F8fCe981f55bbD249f12aC8C",
+ "72d9172d7edc623266d6c625db91505e6b64a5524e6d7c7c0184b1bbdea1e986",
+ "8c26d557a0a9cb22dc2a30d36bf67de93a0eb6d4ef503a849c7de2d14dcbdaaa"),
+ new FinalPubKeyData("0x8a7e297e20804786767B1918a5CFa11683e5a3BB",
+ "7927d5281aea24fd93f41696f79c91370ec0097ff65e83e95691fffbde6d733a",
+ "f22735f0e72ff225274cf499d50b240b7571063e0584471b2b4dab337ad5d8da"),
+ new Metadata(new PubNonce("5712d789f7ecf3435dd9bf1136c2daaa634f0222d64e289d2abe30a729a6a22b",
+ "2d2b4586fd5fd9d15c22f66b61bc475742754a8b96d1edb7b2590e4c4f97b3f0"),
+ new BigInteger("0"), TypeOfUser.v2, false, torusPublicKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusPublicKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should be able to login when verifierID is hash enabled")
+ @Test
+ public void testShouldBeAbleToLoginWhenVerifierIdIsHashEnabled() throws Exception {
+ String idToken = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(HashEnabledVerifier, TORUS_TEST_EMAIL).get();
+ String[] torusNodeEndpoints = nodeDetails.getTorusNodeSSSEndpoints();
+ TorusKey torusKey = torusUtils.retrieveShares(torusNodeEndpoints, HashEnabledVerifier,
+ verifierParams, idToken, null);
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x8a7e297e20804786767B1918a5CFa11683e5a3BB",
+ "7927d5281aea24fd93f41696f79c91370ec0097ff65e83e95691fffbde6d733a",
+ "f22735f0e72ff225274cf499d50b240b7571063e0584471b2b4dab337ad5d8da",
+ "f161f63a84f1c935525ec0bda74bc5a15de6a9a7be28fad237ef6162df335fe6"),
+ new OAuthKeyData("0xaEafa3Fc7349E897F8fCe981f55bbD249f12aC8C",
+ "72d9172d7edc623266d6c625db91505e6b64a5524e6d7c7c0184b1bbdea1e986",
+ "8c26d557a0a9cb22dc2a30d36bf67de93a0eb6d4ef503a849c7de2d14dcbdaaa",
+ "62e110d9d698979c1966d14b2759006cf13be7dfc86a63ff30812e2032163f2f"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(new PubNonce("5712d789f7ecf3435dd9bf1136c2daaa634f0222d64e289d2abe30a729a6a22b",
+ "2d2b4586fd5fd9d15c22f66b61bc475742754a8b96d1edb7b2590e4c4f97b3f0"),
+ new BigInteger("8e80e560ae59319938f7ef727ff2c5346caac1c7f5be96d3076e3342ad1d20b7", 16), TypeOfUser.v2,
+ false, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should be able to login")
+ @Test
+ public void shouldLogin() throws Exception {
+ String token = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_VERIFIER,
+ verifierParams, token, null);
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x462A8BF111A55C9354425F875F89B22678c0Bc44",
+ "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1",
+ "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507",
+ "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203"),
+ new OAuthKeyData("0x137B3607958562D03Eb3C6086392D1eFa01aA6aa",
+ "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b",
+ "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5",
+ "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(new PubNonce("5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc",
+ "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed"),
+ new BigInteger("b7d126751b68ecd09e371a23898e6819dee54708a5ead4f6fe83cdc79c0f1c4a", 16), TypeOfUser.v2,
+ false, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should be able to aggregate login")
+ @Test
+ public void shouldAggregateLogin() throws Exception {
+ String email = JwtUtils.getRandomEmail();
+ String idToken = JwtUtils.generateIdToken(email, algorithmRs);
+ String hashedIdToken = Hash.sha3String(idToken).replace("0x","");
+ VerifierParams verifierParams = new VerifierParams(email, null, new String[]{TORUS_TEST_VERIFIER}, new VerifyParams[]{new VerifyParams(email, idToken)});
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_AGGREGATE_VERIFIER, email).get();
+ String[] endpoints = nodeDetails.getTorusNodeSSSEndpoints();
+ TorusKey result = torusUtils.retrieveShares(endpoints, TORUS_TEST_AGGREGATE_VERIFIER,
+ verifierParams, hashedIdToken, null);
+ assertNotNull(result.getFinalKeyData().getWalletAddress());
+ assertNotNull(result.getoAuthKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, result.getMetadata().getTypeOfUser());
+ assertNotNull(result.getMetadata().getNonce());
+ }
+
+ @DisplayName("should be able to update the `sessionTime` of the token signature data")
+ @Test
+ public void shouldUpdateSessionTimeOfTokenSignatureData() throws Exception {
+ String idToken = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
+ String[] torusNodeEndpoints = nodeDetails.getTorusNodeEndpoints();
+
+ int customSessionTime = 3600;
+ torusUtils.setSessionTime(customSessionTime);
+
+ TorusKey torusKey = torusUtils.retrieveShares(torusNodeEndpoints, TORUS_TEST_VERIFIER,
+ verifierParams, idToken, null);
+
+
+ for (SessionToken sessionToken : torusKey.getSessionData().getSessionTokenData()) {
+ String decodedToken = new String(Base64.getDecoder().decode(sessionToken.getToken()), StandardCharsets.UTF_8);
+ Header jwt = JwtUtils.parseTokenHeader(decodedToken);
+ Date expiry = jwt.getHeaderClaim("exp").asDate();
+ Date now = new Date();
+ long diffInMillis = Math.abs(expiry.getTime() - now.getTime());
+ long diff = TimeUnit.SECONDS.convert(diffInMillis, TimeUnit.MILLISECONDS);
+ assert (diff > (customSessionTime - 30));
+ assert (customSessionTime <= diff);
+ }
+ }
+}
diff --git a/src/test/java/org/torusresearch/torusutilstest/SapphireMainnetTest.java b/src/test/java/org/torusresearch/torusutilstest/SapphireMainnetTest.java
new file mode 100644
index 0000000..93099ab
--- /dev/null
+++ b/src/test/java/org/torusresearch/torusutilstest/SapphireMainnetTest.java
@@ -0,0 +1,340 @@
+package org.torusresearch.torusutilstest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.interfaces.Header;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.torusresearch.fetchnodedetails.FetchNodeDetails;
+import org.torusresearch.fetchnodedetails.types.NodeDetails;
+import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
+import org.torusresearch.torusutils.TorusUtils;
+import org.torusresearch.torusutils.helpers.TorusUtilError;
+import org.torusresearch.torusutils.types.FinalKeyData;
+import org.torusresearch.torusutils.types.FinalPubKeyData;
+import org.torusresearch.torusutils.types.Metadata;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthKeyData;
+import org.torusresearch.torusutils.types.OAuthPubKeyData;
+import org.torusresearch.torusutils.types.SessionData;
+import org.torusresearch.torusutils.types.VerifierParams;
+import org.torusresearch.torusutils.types.VerifyParams;
+import org.torusresearch.torusutils.types.common.PubNonce;
+import org.torusresearch.torusutils.types.common.SessionToken;
+import org.torusresearch.torusutils.types.common.TorusKey;
+import org.torusresearch.torusutils.types.common.TorusOptions;
+import org.torusresearch.torusutils.types.common.TorusPublicKey;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
+import org.torusresearch.torusutilstest.utils.JwtUtils;
+import org.torusresearch.torusutilstest.utils.PemUtils;
+import org.web3j.crypto.Hash;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Base64;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+public class SapphireMainnetTest {
+
+ static FetchNodeDetails fetchNodeDetails;
+
+ static TorusUtils torusUtils;
+ static Algorithm algorithmRs;
+
+ static String TORUS_TEST_VERIFIER = "torus-test-health";
+ static String TORUS_TEST_AGGREGATE_VERIFIER = "torus-aggregate-sapphire-mainnet";
+
+ static String TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierid@example.com";
+ static String HashEnabledVerifier = "torus-test-verifierid-hash";
+
+ static String TORUS_TEST_EMAIL = "hello@tor.us";
+
+ @BeforeEach
+ void setup() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, TorusUtilError {
+ fetchNodeDetails = new FetchNodeDetails(Web3AuthNetwork.SAPPHIRE_MAINNET);
+ TorusOptions opts = new TorusOptions("YOUR_CLIENT_ID", Web3AuthNetwork.SAPPHIRE_MAINNET, null, 0, true);
+ torusUtils = new TorusUtils(opts);
+ ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromFile("src/test/java/org/torusresearch/torusutilstest/keys/key.pem", "EC");
+ ECPublicKey publicKey = (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(new ECPublicKeySpec(privateKey.getParams().getGenerator(), privateKey.getParams()));
+ algorithmRs = Algorithm.ECDSA256(publicKey, privateKey);
+ }
+
+ @DisplayName("Gets Public Address")
+ @Test
+ public void shouldGetPublicAddress() throws Exception {
+ String verifier = "tkey-google-sapphire-mainnet";
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(verifier, TORUS_TEST_EMAIL).get();
+ TorusPublicKey torusPublicKey = torusUtils.getPublicAddress(nodeDetails.getTorusNodeSSSEndpoints(), verifier, TORUS_TEST_EMAIL, null);
+ assertEquals("0x327b2742768B436d09153429E762FADB54413Ded", torusPublicKey.getFinalKeyData().getWalletAddress());
+ assertThat(torusPublicKey).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xb1a49C6E50a1fC961259a8c388EAf5953FA5152b",
+ "a9f5a463aefb16e90f4cbb9de4a5b6b7f6c6a3831cefa0f20cccb9e7c7b01c20",
+ "3376c6734da57ab3a67c7792eeea20707d16992dd2c827a59499f4c056b00d08"),
+ new FinalPubKeyData("0x327b2742768B436d09153429E762FADB54413Ded",
+ "1567e030ca76e520c180c50bc6baed07554ebc35c3132495451173e9310d8be5",
+ "123c0560757ffe6498bf2344165d0f295ea74eb8884683675e5f17ae7bb41cdb"),
+ new Metadata(new PubNonce("56e803db7710adbfe0ecca35bc6a3ad27e966df142e157e76e492773c88e8433",
+ "f4168594c1126ca731756dd480f992ee73b0834ba4b787dd892a9211165f50a3"),
+ new BigInteger("0", 16), TypeOfUser.v2, false, torusPublicKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusPublicKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should be able to key assign")
+ @Test
+ public void shouldKeyAssign() throws Exception {
+ String verifier = "tkey-google-sapphire-mainnet";
+ String verifierId = JwtUtils.getRandomEmail();
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(verifier, verifierId).get();
+ TorusPublicKey result = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), verifier, verifierId, null);
+ assertNotEquals("", result.getFinalKeyData().getWalletAddress());
+ assertNotNull(result.getFinalKeyData().getWalletAddress());
+ assertNotEquals("", result.getFinalKeyData().getWalletAddress());
+ assertNotNull(result.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, result.getMetadata().getTypeOfUser());
+ assertFalse(result.getMetadata().isUpgraded());
+ }
+
+ @DisplayName("should assign key to tss verifier id")
+ @Test
+ public void shouldAssignKeyToTssVerifierId() throws Exception {
+ String email = JwtUtils.getRandomEmail();
+ int nonce = 0;
+ String tssTag = "default";
+ String tssVerifierId = email + "\u0015" + tssTag + "\u0016" + nonce;
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, email).get();
+ TorusPublicKey result = torusUtils.getPublicAddress(nodeDetails.getTorusNodeSSSEndpoints(), TORUS_TEST_VERIFIER, email, tssVerifierId);
+ assertNotNull(result.getFinalKeyData().getWalletAddress());
+ assertNotNull(result.getoAuthKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, result.getMetadata().getTypeOfUser());
+ assertFalse(result.getMetadata().isUpgraded());
+ }
+
+ @DisplayName("should fetch pubic address of tssVerifierId")
+ @Test
+ public void shouldFetchPubicAddressOfTssVerifierId() throws Exception {
+ String email = TORUS_EXTENDED_VERIFIER_EMAIL;
+ int nonce = 0;
+ String tssTag = "default";
+ String tssVerifierId = email + "\u0015" + tssTag + "\u0016" + nonce;
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, email).get();
+ TorusPublicKey torusPublicKey = torusUtils.getPublicAddress(nodeDetails.getTorusNodeSSSEndpoints(), TORUS_TEST_VERIFIER, email, tssVerifierId);
+ assertThat(torusPublicKey).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A",
+ "a772c71ca6c650506f26a180456a6bdf462996781a10f1740f4e65314f360f29",
+ "776c2178ff4620c67197b2f26b1222503919ff26a7cbd0fdbc91a2c9764e56cb"),
+ new FinalPubKeyData("0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A",
+ "a772c71ca6c650506f26a180456a6bdf462996781a10f1740f4e65314f360f29",
+ "776c2178ff4620c67197b2f26b1222503919ff26a7cbd0fdbc91a2c9764e56cb"),
+ new Metadata(torusPublicKey.getMetadata().getPubNonce(),
+ new BigInteger("0"), TypeOfUser.v2, false, torusPublicKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusPublicKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should allow test tssVerifier to fetch shares")
+ @Test
+ public void testShouldAllowTestTssVerifierToFetchShares() throws Exception {
+ String email = JwtUtils.getRandomEmail();
+ int nonce = 0;
+ String tssTag = "default";
+ String tssVerifierID = email + "\u0015" + tssTag + "\u0016" + nonce;
+ String verifier = TORUS_TEST_VERIFIER;
+ String token = JwtUtils.generateIdToken(email, algorithmRs);
+
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(verifier, email).get();
+ VerifierParams verifierParams = new VerifierParams(email, tssVerifierID, null, null);
+ TorusKey torusKey = torusUtils.retrieveShares(
+ nodeDetails.getTorusNodeSSSEndpoints(),
+ verifier,
+ verifierParams,
+ token, null
+ );
+ assertNotNull(torusKey.getFinalKeyData().getPrivKey());
+ assertNotNull(torusKey.getoAuthKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, torusKey.getMetadata().getTypeOfUser());
+ assertEquals(BigInteger.ZERO, torusKey.getMetadata().getNonce());
+ assertTrue(torusKey.getMetadata().isUpgraded());
+ }
+
+ @DisplayName("should fetch public address when verifierID hash enabled")
+ @Test
+ public void shouldFetchPubAddressWhenVerfierIdHasEnabled() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(HashEnabledVerifier, TORUS_TEST_EMAIL).get();
+ String[] torusNodeEndpoints = nodeDetails.getTorusNodeSSSEndpoints();
+ TorusPublicKey torusPublicKey = torusUtils.getPublicAddress(torusNodeEndpoints, HashEnabledVerifier, TORUS_TEST_EMAIL, null);
+ assertTrue(torusPublicKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", torusPublicKey.getFinalKeyData().getWalletAddress());
+ assertThat(torusPublicKey).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC",
+ "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8",
+ "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c"),
+ new FinalPubKeyData("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB",
+ "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8",
+ "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90"),
+ new Metadata(new PubNonce("498ed301af25a3b7136f478fa58677c79a6d6fe965bc13002a6f459b896313bd",
+ "d6feb9a1e0d6d0627fbb1ce75682bc09ab4cf0e2da4f0f7fcac0ba9d07596c8f"),
+ new BigInteger("0", 16), TypeOfUser.v2, false, torusPublicKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusPublicKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should fetch user type and public address when verifierID hash enabled")
+ @Test
+ public void shouldFetchUserTypeAndPubAddressWhenVerfierIdHasEnabled() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(HashEnabledVerifier, TORUS_TEST_EMAIL).get();
+ String[] torusNodeEndpoints = nodeDetails.getTorusNodeSSSEndpoints();
+ TorusPublicKey torusPublicKey = torusUtils.getPublicAddress(torusNodeEndpoints, HashEnabledVerifier, TORUS_TEST_EMAIL, null);
+ assertTrue(torusPublicKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", torusPublicKey.getFinalKeyData().getWalletAddress());
+ assertThat(torusPublicKey).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC",
+ "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8",
+ "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c"),
+ new FinalPubKeyData("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB",
+ "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8",
+ "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90"),
+ new Metadata(new PubNonce("498ed301af25a3b7136f478fa58677c79a6d6fe965bc13002a6f459b896313bd",
+ "d6feb9a1e0d6d0627fbb1ce75682bc09ab4cf0e2da4f0f7fcac0ba9d07596c8f"),
+ new BigInteger("0", 16), TypeOfUser.v2, false,
+ torusPublicKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusPublicKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should be able to login when verifierID hash enabled")
+ @Test
+ public void testShouldBeAbleToLoginWhenVerifierIdHashEnabled() throws Exception {
+ String idToken = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(HashEnabledVerifier, TORUS_TEST_EMAIL).get();
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeSSSEndpoints(), HashEnabledVerifier,
+ verifierParams, idToken, null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assert ((torusKey.getFinalKeyData().getPrivKey() != null) && torusKey.getFinalKeyData().getPrivKey().equals("13941ecd812b08d8a33a20bc975f0cd1c3f82de25b20c0c863ba5f21580b65f6"));
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB",
+ "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8",
+ "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90",
+ "13941ecd812b08d8a33a20bc975f0cd1c3f82de25b20c0c863ba5f21580b65f6"),
+ new OAuthKeyData("0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC",
+ "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8",
+ "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c",
+ "d768b327cbde681e5850a7d14f1c724bba2b8f8ab7fe2b1c4f1ee6979fc25478"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(new PubNonce("498ed301af25a3b7136f478fa58677c79a6d6fe965bc13002a6f459b896313bd",
+ "d6feb9a1e0d6d0627fbb1ce75682bc09ab4cf0e2da4f0f7fcac0ba9d07596c8f"),
+ new BigInteger("3c2b6ba5b54ca0ba4ae978eb48429a84c47b7b3e526b35e7d46dd716887f52bf", 16), TypeOfUser.v2,
+ false, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should be able to login")
+ @Test
+ public void shouldBeAbleToLogin() throws Exception {
+ String token = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_VERIFIER,
+ verifierParams, token, null);
+ assert ((torusKey.getFinalKeyData().getPrivKey() != null) && torusKey.getFinalKeyData().getPrivKey().equals("dfb39b84e0c64b8c44605151bf8670ae6eda232056265434729b6a8a50fa3419"));
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x70520A7F04868ACad901683699Fa32765C9F6871",
+ "adff099b5d3b1e238b43fba1643cfa486e8d9e8de22c1e6731d06a5303f9025b",
+ "21060328e7889afd303acb63201b6493e3061057d1d81279931ab4a6cabf94d4",
+ "dfb39b84e0c64b8c44605151bf8670ae6eda232056265434729b6a8a50fa3419"),
+ new OAuthKeyData("0x925c97404F1aBdf4A8085B93edC7B9F0CEB3C673",
+ "5cd8625fc01c7f7863a58c914a8c43b2833b3d0d5059350bab4acf6f4766a33d",
+ "198a4989615c5c2c7fa4d49c076ea7765743d09816bb998acb9ff54f5db4a391",
+ "90a219ac78273e82e36eaa57c15f9070195e436644319d6b9aea422bb4d31906"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(new PubNonce("ab4d287c263ab1bb83c37646d0279764e50fe4b0c34de4da113657866ddcf318",
+ "ad35db2679dfad4b62d77cf753d7b98f73c902e5d101cc2c3c1209ece6d94382"),
+ new BigInteger("4f1181d8689f0d0960f1a6f9fe26e03e557bdfba11f4b6c8d7b1285e9c271b13", 16),
+ TypeOfUser.v2, false, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should be able to aggregate login")
+ @Test
+ public void shouldAggregateLogin() throws Exception {
+ String email = JwtUtils.getRandomEmail();
+ String idToken = JwtUtils.generateIdToken(email, algorithmRs);
+ String hashedIdToken = Hash.sha3String(idToken).replace("0x","");
+
+
+ VerifierParams verifierParams = new VerifierParams(email, null, new String[]{TORUS_TEST_VERIFIER}, new VerifyParams[]{new VerifyParams(email, idToken)});
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_AGGREGATE_VERIFIER, email).get();
+ String[] endpoints = nodeDetails.getTorusNodeSSSEndpoints();
+ TorusKey result = torusUtils.retrieveShares(endpoints, TORUS_TEST_AGGREGATE_VERIFIER,
+ verifierParams, hashedIdToken, null);
+ assertNotNull(result.getFinalKeyData().getWalletAddress());
+ assertNotNull(result.getoAuthKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, result.getMetadata().getTypeOfUser());
+ assertNotNull(result.getMetadata().getNonce());
+ }
+
+ @DisplayName("Should fetch user type and public address when verifierID hash enabled")
+ @Test
+ public void testFetchUserTypeAndPublicAddressWhenVerfierIdHasEnabled() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(HashEnabledVerifier, TORUS_TEST_EMAIL).get();
+ String[] torusNodeEndpoints = nodeDetails.getTorusNodeSSSEndpoints();
+ TorusPublicKey torusPublicKey = torusUtils.getPublicAddress(torusNodeEndpoints, HashEnabledVerifier, TORUS_TEST_EMAIL, null);
+ assertEquals("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", torusPublicKey.getFinalKeyData().getWalletAddress());
+ assertThat(torusPublicKey).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC",
+ "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8",
+ "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c"),
+ new FinalPubKeyData("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB",
+ "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8",
+ "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90"),
+ new Metadata(new PubNonce("498ed301af25a3b7136f478fa58677c79a6d6fe965bc13002a6f459b896313bd",
+ "d6feb9a1e0d6d0627fbb1ce75682bc09ab4cf0e2da4f0f7fcac0ba9d07596c8f"),
+ new BigInteger("0", 16), TypeOfUser.v2, false, torusPublicKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusPublicKey.getNodesData().getNodeIndexes())
+ ));
+ }
+
+ @DisplayName("should be able to update the `sessionTime` of the token signature data")
+ @Test
+ public void shouldUpdateSessionTimeOfTokenSignatureData() throws Exception {
+ String idToken = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
+ String[] torusNodeEndpoints = nodeDetails.getTorusNodeEndpoints();
+
+ int customSessionTime = 3600;
+ torusUtils.setSessionTime(customSessionTime);
+ TorusKey torusKey = torusUtils.retrieveShares(torusNodeEndpoints, TORUS_TEST_VERIFIER,
+ verifierParams, idToken, null);
+
+ for (SessionToken sessionToken : torusKey.getSessionData().getSessionTokenData()) {
+ String decodedToken = new String(Base64.getDecoder().decode(sessionToken.getToken()), StandardCharsets.UTF_8);
+ Header jwt = JwtUtils.parseTokenHeader(decodedToken);
+ Date expiry = jwt.getHeaderClaim("exp").asDate();
+ Date now = new Date();
+ long diffInMillis = Math.abs(expiry.getTime() - now.getTime());
+ long diff = TimeUnit.SECONDS.convert(diffInMillis, TimeUnit.MILLISECONDS);
+ assert (diff > (customSessionTime - 30));
+ assert (customSessionTime <= diff);
+ }
+ }
+}
diff --git a/src/test/java/org/torusresearch/torusutilstest/TorusUtilsTest.java b/src/test/java/org/torusresearch/torusutilstest/TorusUtilsTest.java
index e41b7b3..2c047f4 100644
--- a/src/test/java/org/torusresearch/torusutilstest/TorusUtilsTest.java
+++ b/src/test/java/org/torusresearch/torusutilstest/TorusUtilsTest.java
@@ -1,27 +1,38 @@
package org.torusresearch.torusutilstest;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.auth0.jwt.algorithms.Algorithm;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.torusresearch.fetchnodedetails.FetchNodeDetails;
import org.torusresearch.fetchnodedetails.types.NodeDetails;
import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork;
import org.torusresearch.torusutils.TorusUtils;
-import org.torusresearch.torusutils.types.RetrieveSharesResponse;
-import org.torusresearch.torusutils.types.TorusCtorOptions;
-import org.torusresearch.torusutils.types.TorusException;
-import org.torusresearch.torusutils.types.TorusPublicKey;
-import org.torusresearch.torusutils.types.TypeOfUser;
-import org.torusresearch.torusutils.types.VerifierArgs;
+import org.torusresearch.torusutils.helpers.TorusUtilError;
+import org.torusresearch.torusutils.types.FinalKeyData;
+import org.torusresearch.torusutils.types.FinalPubKeyData;
+import org.torusresearch.torusutils.types.Metadata;
+import org.torusresearch.torusutils.types.NodesData;
+import org.torusresearch.torusutils.types.OAuthKeyData;
+import org.torusresearch.torusutils.types.OAuthPubKeyData;
+import org.torusresearch.torusutils.types.SessionData;
+import org.torusresearch.torusutils.types.VerifierParams;
+import org.torusresearch.torusutils.types.VerifyParams;
+import org.torusresearch.torusutils.types.common.PubNonce;
+import org.torusresearch.torusutils.types.common.TorusKey;
+import org.torusresearch.torusutils.types.common.TorusOptions;
+import org.torusresearch.torusutils.types.common.TorusPublicKey;
+import org.torusresearch.torusutils.types.common.TypeOfUser;
import org.torusresearch.torusutilstest.utils.JwtUtils;
import org.torusresearch.torusutilstest.utils.PemUtils;
-import org.torusresearch.torusutilstest.utils.VerifyParams;
import org.web3j.crypto.Hash;
import java.io.IOException;
@@ -32,8 +43,6 @@
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
-import java.util.HashMap;
-import java.util.concurrent.ExecutionException;
public class TorusUtilsTest {
@@ -45,14 +54,12 @@ public class TorusUtilsTest {
static String TORUS_TEST_VERIFIER = "torus-test-health";
static String TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate";
- static String TORUS_TEST_EMAIL = "hello@tor.us";
+ static String TORUS_TEST_EMAIL = "archit1@tor.us";
- @BeforeAll
- static void setup() throws ExecutionException, InterruptedException, IOException, NoSuchAlgorithmException, InvalidKeySpecException {
- System.out.println("Setup Starting");
+ @BeforeEach
+ void setup() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, TorusUtilError {
fetchNodeDetails = new FetchNodeDetails(Web3AuthNetwork.TESTNET);
- TorusCtorOptions opts = new TorusCtorOptions("Custom", "YOUR_CLIENT_ID");
- opts.setNetwork("testnet");
+ TorusOptions opts = new TorusOptions("YOUR_CLIENT_ID", Web3AuthNetwork.TESTNET, null, 0, false);
torusUtils = new TorusUtils(opts);
ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromFile("src/test/java/org/torusresearch/torusutilstest/keys/key.pem", "EC");
ECPublicKey publicKey = (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(new ECPublicKeySpec(privateKey.getParams().getGenerator(), privateKey.getParams()));
@@ -61,72 +68,141 @@ static void setup() throws ExecutionException, InterruptedException, IOException
@DisplayName("Gets Public Address")
@Test
- public void shouldGetPublicAddress() throws ExecutionException, InterruptedException {
- VerifierArgs args = new VerifierArgs("google-lrc", TORUS_TEST_EMAIL);
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(args.getVerifier(), args.getVerifierId()).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), args).get();
- assertEquals("0x872eEfa7495599A6983d396fE8dcf542457CF33f", publicAddress.getAddress());
+ public void shouldGetPublicAddress() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("google-lrc", TORUS_TEST_EMAIL).get();
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), "google-lrc", TORUS_TEST_EMAIL, null);
+ assertThat(publicAddress).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x9bcBAde70546c0796c00323CD1b97fa0a425A506",
+ "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5",
+ "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438"),
+ new FinalPubKeyData("0x9bcBAde70546c0796c00323CD1b97fa0a425A506",
+ "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5",
+ "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438"),
+ new Metadata(publicAddress.getMetadata().getPubNonce(), BigInteger.ZERO, TypeOfUser.v1, false, publicAddress.getMetadata().getServerTimeOffset()),
+ new NodesData(publicAddress.getNodesData().getNodeIndexes())
+ ));
+ assertTrue(publicAddress.getMetadata().getServerTimeOffset() < 20);
}
-
@DisplayName("Fetch User Type and Public Address")
@Test
- public void shouldFetchUserTypeAndPublicAddress() throws ExecutionException, InterruptedException {
- VerifierArgs args = new VerifierArgs("google-lrc", TORUS_TEST_EMAIL);
- NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(args.getVerifier(), args.getVerifierId()).get();
- TorusPublicKey key = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), args).get();
- assertEquals("0x872eEfa7495599A6983d396fE8dcf542457CF33f", key.getAddress());
- assertEquals(TypeOfUser.v1, key.getTypeOfUser());
+ public void shouldFetchUserTypeAndPublicAddress() throws Exception {
+ NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("google-lrc", TORUS_TEST_EMAIL).get();
+ TorusPublicKey key = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), "google-lrc", TORUS_TEST_EMAIL, null);
+ assertThat(key).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x9bcBAde70546c0796c00323CD1b97fa0a425A506",
+ "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5",
+ "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438"),
+ new FinalPubKeyData("0xf5804f608C233b9cdA5952E46EB86C9037fd6842",
+ "ed737569a557b50722a8b5c0e4e5ca30cef1ede2f5674a0616b78246bb93dfd0",
+ "d9e8e6c54c12c4da38c2f0d1047fcf6089036127738f4ef72a83431339586ca9"),
+ new Metadata(new PubNonce("f3f7caefd6540d923c9993113f34226371bd6714a5be6882dedc95a6a929a8",
+ "f28620603601ce54fa0d70fd691fb72ff52f5bf164bf1a91617922eaad8cc7a5"),
+ BigInteger.ZERO, TypeOfUser.v2, false, key.getMetadata().getServerTimeOffset()),
+ new NodesData(key.getNodesData().getNodeIndexes())
+ ));
+ assertEquals("0xf5804f608C233b9cdA5952E46EB86C9037fd6842", key.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key.getMetadata().getTypeOfUser());
String v2Verifier = "tkey-google-lrc";
// 1/1 user
String v2TestEmail = "somev2user@gmail.com";
- TorusPublicKey key2 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs(v2Verifier, v2TestEmail)).get();
- assertEquals("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", key2.getAddress());
- assertEquals(TypeOfUser.v2, key2.getTypeOfUser());
+ TorusPublicKey key2 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), v2Verifier, v2TestEmail, null);
+ assertThat(key2).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0x376597141d8d219553378313d18590F373B09795",
+ "86cd2db15b7a9937fa8ab7d0bf8e7f4113b64d1f4b2397aad35d6d4749d2fb6c",
+ "86ef47a3724144331c31a3a322d85b6fc1a5d113b41eaa0052053b6e3c74a3e2"),
+ new FinalPubKeyData("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D",
+ "c350e338dde24df986915992fea6e0aef3560c245ca144ee7fe1498784c4ef4e",
+ "a605e52b65d3635f89654519dfa7e31f7b45f206ef4189866ad0c2240d40f97f"),
+ new Metadata(new PubNonce("ad121b67fa550da814bbbd54ec7070705d058c941e04c03e07967b07b2f90345",
+ "bfe2395b177a72ebb836aaf24cedff2f14cd9ed49047990f5cdb99e4981b5753"),
+ BigInteger.ZERO, TypeOfUser.v2, false, key2.getMetadata().getServerTimeOffset()),
+ new NodesData(key2.getNodesData().getNodeIndexes())
+ ));
+ assertEquals("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", key2.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key2.getMetadata().getTypeOfUser());
// 2/n user
String v2nTestEmail = "caspertorus@gmail.com";
- TorusPublicKey key3 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs(v2Verifier, v2nTestEmail)).get();
- assertEquals("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", key3.getAddress());
- assertEquals(TypeOfUser.v2, key3.getTypeOfUser());
+ TorusPublicKey key3 = torusUtils.getUserTypeAndAddress(nodeDetails.getTorusNodeEndpoints(), v2Verifier, v2nTestEmail, null);
+ assertThat(key3).isEqualToComparingFieldByFieldRecursively(new TorusPublicKey(
+ new OAuthPubKeyData("0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544",
+ "d25cc473fbb448d20b5551f3c9aa121e1924b3d197353347187c47ad13ecd5d8",
+ "3394000f43160a925e6c3017dde1354ecb2b61739571c6584f58edd6b923b0f5"),
+ new FinalPubKeyData("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456",
+ "d3e222f6b23f0436b7c86e9cc4164eb5ea8448e4c0e7539c8b4f7fd00e8ec5c7",
+ "1c47f5faccec6cf57c36919f6f0941fe3d8d65033cf2cc78f209304386044222"),
+ new Metadata(new PubNonce("4f86b0e69992d1551f1b16ceb0909453dbe17b9422b030ee6c5471c2e16b65d0",
+ "640384f3d39debb04c4e9fe5a5ec6a1b494b0ad66d00ac9be6f166f21d116ca4"),
+ BigInteger.ZERO, TypeOfUser.v2, true, key3.getMetadata().getServerTimeOffset()),
+ new NodesData(key3.getNodesData().getNodeIndexes())
+ ));
+ assertEquals("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", key3.getFinalKeyData().getWalletAddress());
+ assertEquals(TypeOfUser.v2, key3.getMetadata().getTypeOfUser());
}
@DisplayName("Key Assign test")
@Test
- public void shouldKeyAssign() throws ExecutionException, InterruptedException {
+ public void shouldKeyAssign() throws Exception {
String email = JwtUtils.getRandomEmail();
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails("google-lrc", email).get();
- TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusNodePub(), new VerifierArgs("google-lrc", email)).get();
- System.out.println(email + " -> " + publicAddress.getAddress());
- assertNotNull(publicAddress.getAddress());
- assertNotEquals(publicAddress.getAddress(), "");
+ TorusPublicKey publicAddress = torusUtils.getPublicAddress(nodeDetails.getTorusNodeEndpoints(), "google-lrc", email, "");
+ assertNotNull(publicAddress.getFinalKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getFinalKeyData().getWalletAddress(), "");
+ assertNotNull(publicAddress.getoAuthKeyData().getWalletAddress());
+ assertNotEquals(publicAddress.getoAuthKeyData().getWalletAddress(), "");
+ assertEquals(publicAddress.getMetadata().getTypeOfUser(), TypeOfUser.v2);
+ assertFalse(publicAddress.getMetadata().isUpgraded());
}
@DisplayName("Login test")
@Test
- public void shouldLogin() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldLogin() throws Exception {
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_VERIFIER, new HashMap() {{
- put("verifier_id", TORUS_TEST_EMAIL);
- }}, JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs)).get();
- System.out.println(retrieveSharesResponse.getPrivKey());
- BigInteger requiredPrivateKey = new BigInteger("68ee4f97468ef1ae95d18554458d372e31968190ae38e377be59d8b3c9f7a25", 16);
- assert (requiredPrivateKey.equals(retrieveSharesResponse.getPrivKey()));
- assertEquals("0xEfd7eDAebD0D99D1B7C8424b54835457dD005Dc4", retrieveSharesResponse.getEthAddress());
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, null, null);
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_VERIFIER,
+ verifierParams, JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs), null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assert ((torusKey.getFinalKeyData().getPrivKey() != null) && torusKey.getFinalKeyData().getPrivKey().equals("9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3"));
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6",
+ "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd",
+ "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9",
+ "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3"),
+ new OAuthKeyData("0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6",
+ "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd",
+ "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9",
+ "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(null, BigInteger.ZERO, TypeOfUser.v1, null, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
@DisplayName("Aggregate Login test")
@Test
- public void shouldAggregateLogin() throws ExecutionException, InterruptedException, TorusException {
+ public void shouldAggregateLogin() throws Exception {
String idToken = JwtUtils.generateIdToken(TORUS_TEST_EMAIL, algorithmRs);
- String hashedIdToken = Hash.sha3String(idToken).substring(2);
+ String hashedIdToken = Hash.sha3String(idToken).replace("0x","");
+ VerifierParams verifierParams = new VerifierParams(TORUS_TEST_EMAIL, null, new String[]{TORUS_TEST_VERIFIER}, new VerifyParams[]{new VerifyParams(TORUS_TEST_EMAIL, idToken)});
NodeDetails nodeDetails = fetchNodeDetails.getNodeDetails(TORUS_TEST_AGGREGATE_VERIFIER, TORUS_TEST_EMAIL).get();
- RetrieveSharesResponse retrieveSharesResponse = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), nodeDetails.getTorusIndexes(), TORUS_TEST_AGGREGATE_VERIFIER, new HashMap() {{
- put("verify_params", new VerifyParams[]{new VerifyParams(idToken, TORUS_TEST_EMAIL)});
- put("sub_verifier_ids", new String[]{TORUS_TEST_VERIFIER});
- put("verifier_id", TORUS_TEST_EMAIL);
- }}, hashedIdToken).get();
- assertEquals("0x5a165d2Ed4976BD104caDE1b2948a93B72FA91D2", retrieveSharesResponse.getEthAddress());
+ TorusKey torusKey = torusUtils.retrieveShares(nodeDetails.getTorusNodeEndpoints(), TORUS_TEST_AGGREGATE_VERIFIER,
+ verifierParams, hashedIdToken, null);
+ assertTrue(torusKey.getMetadata().getServerTimeOffset() < 20);
+ assertEquals("0x938a40E155d118BD31E439A9d92D67bd55317965", torusKey.getoAuthKeyData().getWalletAddress());
+ assertThat(torusKey).isEqualToComparingFieldByFieldRecursively(new TorusKey(
+ new FinalKeyData("0x938a40E155d118BD31E439A9d92D67bd55317965",
+ "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95",
+ "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6",
+ "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1"),
+ new OAuthKeyData("0x938a40E155d118BD31E439A9d92D67bd55317965",
+ "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95",
+ "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6",
+ "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1"),
+ new SessionData(torusKey.getSessionData().getSessionTokenData(), torusKey.getSessionData().getSessionAuthKey()),
+ new Metadata(null, BigInteger.ZERO, TypeOfUser.v1, null, torusKey.getMetadata().getServerTimeOffset()),
+ new NodesData(torusKey.getNodesData().getNodeIndexes())
+ ));
}
}
diff --git a/src/test/java/org/torusresearch/torusutilstest/helpers/AES256CBC.java b/src/test/java/org/torusresearch/torusutilstest/helpers/AES256CBC.java
deleted file mode 100644
index a17109e..0000000
--- a/src/test/java/org/torusresearch/torusutilstest/helpers/AES256CBC.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.torusresearch.torusutilstest.helpers;
-
-import org.junit.jupiter.api.Test;
-
-import java.nio.charset.StandardCharsets;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-public class AES256CBC {
-
- @Test
- public void testLeadingZeroes() {
- // This combination of private and public keys resuts in an SHA512 hash with a leading zero
- String privateKey = "dec95a4ffa406daedd079956f1e43fb91baefdad00990699642474eeb09a5a90";
- String publicKey = "a6262a5650a9666195098c2e15e8eb451a755eb59ea2d1b437d11d9113f4d356bd479f01d29850b77fa6357628d2ed0fa0d8230620472b91f21db1c2c6e7def";
-
- // Leading zeroes in IV
- String iv = "0023456789ABCDEF0123456789ABCDEF";
-
- byte[] payload = "Hello World".getBytes(StandardCharsets.UTF_8);
-
- try {
- org.torusresearch.torusutils.helpers.AES256CBC aes256cbc = new org.torusresearch.torusutils.helpers.AES256CBC(privateKey, publicKey, iv);
- String encrypted = aes256cbc.encrypt(payload);
- byte[] decrypted = aes256cbc.decrypt(encrypted);
-
- assertArrayEquals(payload, decrypted);
- } catch (Exception e) {
- assertFalse(true);
- }
- }
-
-
-}
diff --git a/src/test/java/org/torusresearch/torusutilstest/helpers/TestAES256CBC.java b/src/test/java/org/torusresearch/torusutilstest/helpers/TestAES256CBC.java
new file mode 100644
index 0000000..7b89686
--- /dev/null
+++ b/src/test/java/org/torusresearch/torusutilstest/helpers/TestAES256CBC.java
@@ -0,0 +1,38 @@
+package org.torusresearch.torusutilstest.helpers;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.bouncycastle.util.encoders.Hex;
+import org.junit.jupiter.api.Test;
+import org.torusresearch.torusutils.helpers.KeyUtils;
+import org.torusresearch.torusutils.helpers.MetadataUtils;
+import org.torusresearch.torusutils.helpers.encryption.Encryption;
+import org.torusresearch.torusutils.types.common.ecies.Ecies;
+
+import java.nio.charset.StandardCharsets;
+import java.security.KeyPair;
+
+public class TestAES256CBC {
+ @Test
+ public void testECDH() throws Exception {
+ KeyPair secret = KeyUtils.generateKeyPair();
+ KeyPair secret2 = KeyUtils.generateKeyPair();
+
+ byte[] shared = Encryption.ecdh(KeyUtils.serializePrivateKey(secret.getPrivate()), (KeyUtils.serializePublicKey(secret2.getPublic(), false)));
+ byte[] shared2 = Encryption.ecdh(KeyUtils.serializePrivateKey(secret2.getPrivate()), (KeyUtils.serializePublicKey(secret.getPublic(), false)));
+ assertArrayEquals(shared, shared2);
+}
+ @Test
+ public void testEncryption() throws Exception {
+ KeyPair keypair = KeyUtils.generateKeyPair();
+ String payload = "Hello World";
+ String hexEncoded = Hex.toHexString(payload.getBytes());
+ Ecies encrypted = Encryption.encrypt(KeyUtils.serializePublicKey(keypair.getPublic(), false), hexEncoded);
+ String decrypted = new String(Encryption.decrypt(Hex.toHexString(KeyUtils.serializePrivateKey(keypair.getPrivate())), encrypted), StandardCharsets.UTF_8);
+ String decryptedNodeData = MetadataUtils.decryptNodeData(encrypted.omitCipherText(), encrypted.ciphertext, Hex.toHexString(KeyUtils.serializePrivateKey(keypair.getPrivate())));
+
+ assertEquals(payload, decrypted);
+ assertEquals(hexEncoded, decryptedNodeData);
+ }
+}
diff --git a/src/test/java/org/torusresearch/torusutilstest/helpers/TestGenerateEthereumAddress.java b/src/test/java/org/torusresearch/torusutilstest/helpers/TestGenerateEthereumAddress.java
new file mode 100644
index 0000000..5de9e7e
--- /dev/null
+++ b/src/test/java/org/torusresearch/torusutilstest/helpers/TestGenerateEthereumAddress.java
@@ -0,0 +1,17 @@
+package org.torusresearch.torusutilstest.helpers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.torusresearch.torusutils.helpers.KeyUtils;
+
+public class TestGenerateEthereumAddress {
+ @Test
+ public void testGenerateAddressFromPublicKey() throws Exception {
+ String fullAddress = "04238569d5e12caf57d34fb5b2a0679c7775b5f61fd18cd69db9cc600a651749c3ec13a9367380b7a024a67f5e663f3afd40175c3223da63f6024b05d0bd9f292e";
+ String[] coords = KeyUtils.getPublicKeyCoords(fullAddress);
+ String etherAddress = KeyUtils.generateAddressFromPubKey(coords[0], coords[1]);
+ String finalAddress = "0x048975d4997D7578A3419851639c10318db430b6";
+ assertEquals(etherAddress, finalAddress);
+ }
+}
diff --git a/src/test/java/org/torusresearch/torusutilstest/helpers/TestKCombinations.java b/src/test/java/org/torusresearch/torusutilstest/helpers/TestKCombinations.java
new file mode 100644
index 0000000..f7a97df
--- /dev/null
+++ b/src/test/java/org/torusresearch/torusutilstest/helpers/TestKCombinations.java
@@ -0,0 +1,42 @@
+package org.torusresearch.torusutilstest.helpers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.torusresearch.torusutils.helpers.Common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestKCombinations {
+ @Test
+ public void testKCombinations() {
+ List set = new ArrayList<>();
+ List> allCombis = Common.kCombinations(set, 0);
+ assertEquals(allCombis.size(), 0);
+
+ set.add(0);
+ set.add(1);
+ set.add(2);
+ set.add(3);
+ set.add(4);
+ set.add(5);
+
+
+ allCombis = Common.kCombinations(set, 10);
+ assertEquals(allCombis.size(), 0);
+
+ allCombis = Common.kCombinations(set, 6);
+ assertEquals(allCombis.size(), 1);
+
+ allCombis = Common.kCombinations(set, 1);
+ assertEquals(allCombis.size(), 6);
+
+ allCombis = Common.kCombinations(set, 2);
+ assertEquals(allCombis.size(), 15);
+
+ set.remove(0);
+ allCombis = Common.kCombinations(set, 3);
+ assertEquals(allCombis.size(), 10);
+ }
+}
diff --git a/src/test/java/org/torusresearch/torusutilstest/helpers/TestLagrangeInterpolation.java b/src/test/java/org/torusresearch/torusutilstest/helpers/TestLagrangeInterpolation.java
new file mode 100644
index 0000000..7bcdab8
--- /dev/null
+++ b/src/test/java/org/torusresearch/torusutilstest/helpers/TestLagrangeInterpolation.java
@@ -0,0 +1,40 @@
+package org.torusresearch.torusutilstest.helpers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.torusresearch.torusutils.helpers.Lagrange;
+import org.torusresearch.torusutils.types.Point;
+import org.torusresearch.torusutils.types.Polynomial;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+
+public class TestLagrangeInterpolation {
+ @Test
+ public void testLagrangeInterpolation() {
+ ArrayList points = new ArrayList<>();
+ points.add(new Point(BigInteger.ONE, new BigInteger(String.valueOf(2))));
+ points.add(new Point(new BigInteger(String.valueOf(2)), new BigInteger(String.valueOf(5))));
+ points.add(new Point(new BigInteger(String.valueOf(3)), new BigInteger(String.valueOf(10))));
+ Polynomial poly = Lagrange.lagrangeInterpolatePolynomial(points.toArray(new Point[0]));
+
+ ArrayList xValues = new ArrayList<>();
+ xValues.add(BigInteger.ONE);
+ xValues.add(new BigInteger(String.valueOf(2)));
+ xValues.add(new BigInteger(String.valueOf(3)));
+
+ ArrayList expectedYValues = new ArrayList<>();
+ expectedYValues.add(new BigInteger(String.valueOf(2)));
+ expectedYValues.add(new BigInteger(String.valueOf(5)));
+ expectedYValues.add(new BigInteger(String.valueOf(10)));
+
+ for (int i = 0; i < xValues.size(); i++) {
+ BigInteger x = xValues.get(i);
+ BigInteger expectedY = expectedYValues.get(i);
+
+ BigInteger y = poly.polyEval(x);
+ assertEquals(expectedY, y);
+ }
+ }
+}
diff --git a/src/test/java/org/torusresearch/torusutilstest/utils/JwtUtils.java b/src/test/java/org/torusresearch/torusutilstest/utils/JwtUtils.java
index 1531bf9..4f0b576 100644
--- a/src/test/java/org/torusresearch/torusutilstest/utils/JwtUtils.java
+++ b/src/test/java/org/torusresearch/torusutilstest/utils/JwtUtils.java
@@ -2,28 +2,44 @@
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.impl.JWTParser;
+import com.auth0.jwt.interfaces.Header;
+import com.auth0.jwt.interfaces.JWTPartsParser;
+
import net.andreinc.mockneat.MockNeat;
+import java.util.Calendar;
import java.util.Date;
public class JwtUtils {
public static String generateIdToken(String email, Algorithm alg) {
+
+ Date today = new Date();
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(today);
+ calendar.add(Calendar.MINUTE, 2);
+ Date modifiedDate = calendar.getTime();
+
return JWT.create()
- .withSubject("email|" + email.split("@")[0])
- .withAudience("torus-key-test")
- .withExpiresAt(new Date(System.currentTimeMillis() + 3600 * 1000))
- .withIssuedAt(new Date())
- .withIssuer("torus-key-test")
- .withClaim("email", email)
- .withClaim("nickname", email.split("@")[0])
+ .withClaim("admin", false)
.withClaim("name", email)
- .withClaim("picture", "")
+ .withClaim("email", email)
+ .withSubject("email|" + email.split("@")[0]) // sub
.withClaim("email_verified", true)
+ .withAudience("torus-key-test") // aud
+ .withExpiresAt(modifiedDate) // eat
+ .withIssuer("torus-key-test") // iss
+ .withIssuedAt(today) // iat
.sign(alg);
}
+ public static Header parseTokenHeader(String token) {
+ JWTPartsParser parts = new JWTParser();
+ return parts.parseHeader(token);
+ }
+
public static String getRandomEmail() {
MockNeat mock = MockNeat.threadLocal();
return mock.emails().val();
}
-}
+}
\ No newline at end of file
diff --git a/src/test/java/org/torusresearch/torusutilstest/utils/PemUtils.java b/src/test/java/org/torusresearch/torusutilstest/utils/PemUtils.java
index e40490e..42c12cc 100644
--- a/src/test/java/org/torusresearch/torusutilstest/utils/PemUtils.java
+++ b/src/test/java/org/torusresearch/torusutilstest/utils/PemUtils.java
@@ -28,42 +28,25 @@ private static byte[] parsePEMFile(File pemFile) throws IOException {
return content;
}
- private static PublicKey getPublicKey(byte[] keyBytes, String algorithm) {
+ @SuppressWarnings("unused")
+ private static PublicKey getPublicKey(byte[] keyBytes, String algorithm) throws NoSuchAlgorithmException, InvalidKeySpecException {
PublicKey publicKey = null;
- try {
- KeyFactory kf = KeyFactory.getInstance(algorithm);
- EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
- publicKey = kf.generatePublic(keySpec);
- } catch (NoSuchAlgorithmException e) {
- System.out.println("Could not reconstruct the public key, the given algorithm could not be found.");
- } catch (InvalidKeySpecException e) {
- System.out.println("Could not reconstruct the public key");
- }
-
+ KeyFactory kf = KeyFactory.getInstance(algorithm);
+ EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
+ publicKey = kf.generatePublic(keySpec);
return publicKey;
}
- private static PrivateKey getPrivateKey(byte[] keyBytes, String algorithm) {
+ private static PrivateKey getPrivateKey(byte[] keyBytes, String algorithm) throws NoSuchAlgorithmException, InvalidKeySpecException {
PrivateKey privateKey = null;
- try {
- KeyFactory kf = KeyFactory.getInstance(algorithm);
- EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
- privateKey = kf.generatePrivate(keySpec);
- } catch (NoSuchAlgorithmException e) {
- System.out.println("Could not reconstruct the private key, the given algorithm could not be found.");
- } catch (InvalidKeySpecException e) {
- System.out.println("Could not reconstruct the private key");
- }
+ KeyFactory kf = KeyFactory.getInstance(algorithm);
+ EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
+ privateKey = kf.generatePrivate(keySpec);
return privateKey;
}
- public static PublicKey readPublicKeyFromFile(String filepath, String algorithm) throws IOException {
- byte[] bytes = PemUtils.parsePEMFile(new File(filepath));
- return PemUtils.getPublicKey(bytes, algorithm);
- }
-
- public static PrivateKey readPrivateKeyFromFile(String filepath, String algorithm) throws IOException {
+ public static PrivateKey readPrivateKeyFromFile(String filepath, String algorithm) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
byte[] bytes = PemUtils.parsePEMFile(new File(filepath));
return PemUtils.getPrivateKey(bytes, algorithm);
}
diff --git a/src/test/java/org/torusresearch/torusutilstest/utils/VerifyParams.java b/src/test/java/org/torusresearch/torusutilstest/utils/VerifyParams.java
deleted file mode 100644
index 46f4868..0000000
--- a/src/test/java/org/torusresearch/torusutilstest/utils/VerifyParams.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.torusresearch.torusutilstest.utils;
-
-public class VerifyParams {
- private final String idtoken;
- private final String verifier_id;
-
- public VerifyParams(String idtoken, String verifier_id) {
- this.idtoken = idtoken;
- this.verifier_id = verifier_id;
- }
-
- public String getVerifier_id() {
- return verifier_id;
- }
-
- public String getIdtoken() {
- return idtoken;
- }
-}