diff --git a/src/main/java/org/cardanofoundation/signify/app/controlller/Controller.java b/src/main/java/org/cardanofoundation/signify/app/controlller/Controller.java index 71637ad..173e56a 100644 --- a/src/main/java/org/cardanofoundation/signify/app/controlller/Controller.java +++ b/src/main/java/org/cardanofoundation/signify/app/controlller/Controller.java @@ -11,6 +11,7 @@ import org.cardanofoundation.signify.cesr.args.RawArgs; import org.cardanofoundation.signify.cesr.args.RotateArgs; import org.cardanofoundation.signify.cesr.exceptions.LibsodiumException; +import org.cardanofoundation.signify.cesr.exceptions.extraction.UnexpectedCodeException; import org.cardanofoundation.signify.cesr.exceptions.material.InvalidValueException; import org.cardanofoundation.signify.cesr.exceptions.validation.ValidationException; import org.cardanofoundation.signify.cesr.util.CoreUtil; @@ -248,7 +249,10 @@ public Map rotate(String bran, List> aids) t if (aid.containsKey("salty")) { Map salty = Utils.toMap(aid.get("salty")); Cipher cipher = new Cipher(salty.get("sxlt").toString()); - String dnxt = ((Salter) decrypter.decrypt(null, cipher)).getQb64(); + DecryptResult result = decrypter.decrypt(null, cipher); + String dnxt = result.getSalter() + .map(Salter::getQb64) + .orElseThrow(() -> new UnexpectedCodeException("Expected DecryptedSalter but got DecryptedSigner")); // Now we have the AID salt, use it to verify against the current public keys Manager.SaltyCreator acreator = new Manager.SaltyCreator( @@ -293,7 +297,9 @@ public Map rotate(String bran, List> aids) t for (String prx : prxs) { Cipher cipher = new Cipher(prx); - Signer dsigner = (Signer) decrypter.decrypt(null, cipher, true); + DecryptResult result = decrypter.decrypt(null, cipher, true); + Signer dsigner = result.getSigner() + .orElseThrow(() -> new UnexpectedCodeException("Expected DecryptedSigner but got DecryptedSalter")); signers.add(dsigner); nprxs.add(encrypter.encrypt(dsigner.getQb64().getBytes()).getQb64()); } @@ -333,7 +339,10 @@ public Map rotate(String bran, List> aids) t public String recrypt(String enc, Decrypter decrypter, Encrypter encrypter) throws LibsodiumException { Cipher cipher = new Cipher(enc); - String dnxt = ((Salter) decrypter.decrypt(null, cipher)).getQb64(); + DecryptResult result = decrypter.decrypt(null, cipher); + String dnxt = result.getSalter() + .map(Salter::getQb64) + .orElseThrow(() -> new UnexpectedCodeException("Expected DecryptedSalter but got DecryptedSigner")); return encrypter.encrypt(dnxt.getBytes()).getQb64(); } diff --git a/src/main/java/org/cardanofoundation/signify/cesr/Cipher.java b/src/main/java/org/cardanofoundation/signify/cesr/Cipher.java index dece306..41c1e2f 100644 --- a/src/main/java/org/cardanofoundation/signify/cesr/Cipher.java +++ b/src/main/java/org/cardanofoundation/signify/cesr/Cipher.java @@ -16,7 +16,7 @@ public Cipher(byte[] qb64b) { super(qb64b); } - public Object decrypt(byte[] prikey, byte[] seed) throws LibsodiumException { + public DecryptResult decrypt(byte[] prikey, byte[] seed) throws LibsodiumException { Decrypter decrypter; if(prikey != null) { decrypter = new Decrypter(new String(prikey)); diff --git a/src/main/java/org/cardanofoundation/signify/cesr/DecryptResult.java b/src/main/java/org/cardanofoundation/signify/cesr/DecryptResult.java new file mode 100644 index 0000000..4358103 --- /dev/null +++ b/src/main/java/org/cardanofoundation/signify/cesr/DecryptResult.java @@ -0,0 +1,145 @@ +package org.cardanofoundation.signify.cesr; + +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * Sealed interface representing the result of a decryption operation. + * A decryption can produce either a Salter or a Signer. + * + *

This interface provides various helper methods to work with the result + * without explicit type checking or casting: + *

    + *
  • Type checking: {@link #isSalter()}, {@link #isSigner()}
  • + *
  • Safe extraction: {@link #getSalter()}, {@link #getSigner()}
  • + *
  • Visitor pattern: {@link #handle(Consumer, Consumer)}
  • + *
  • Functional mapping: {@link #map(Function, Function)}
  • + *
+ * + *

Example usage with pattern matching (Java 17+): + *

{@code
+ * DecryptResult result = decrypter.decrypt(cipher, salt);
+ *
+ * // Pattern matching with switch
+ * switch (result) {
+ *     case DecryptedSalter(var salter) -> System.out.println("Salter: " + salter.getQb64());
+ *     case DecryptedSigner(var signer) -> System.out.println("Signer: " + signer.getQb64());
+ * }
+ *
+ * // Or with traditional instanceof
+ * if (result instanceof DecryptedSalter(var salter)) {
+ *     // Use salter directly
+ * }
+ * }
+ * + *

Example usage with helper methods: + *

{@code
+ * // Using visitor pattern
+ * result.handle(
+ *     salter -> System.out.println("Got salter: " + salter),
+ *     signer -> System.out.println("Got signer: " + signer)
+ * );
+ *
+ * // Using map for transformation
+ * String qb64 = result.map(
+ *     salter -> salter.getQb64(),
+ *     signer -> signer.getQb64()
+ * );
+ *
+ * // Using safe extraction
+ * result.getSalter().ifPresent(salter -> {
+ *     // Work with salter
+ * });
+ * }
+ */ +public sealed interface DecryptResult permits DecryptResult.DecryptedSalter, DecryptResult.DecryptedSigner { + + /** + * Checks if this result contains a Salter. + * + * @return true if this is a DecryptedSalter, false otherwise + */ + default boolean isSalter() { + return this instanceof DecryptedSalter; + } + + /** + * Checks if this result contains a Signer. + * + * @return true if this is a DecryptedSigner, false otherwise + */ + default boolean isSigner() { + return this instanceof DecryptedSigner; + } + + /** + * Returns the Salter if this result contains one. + * + * @return Optional containing the Salter, or empty if this is a Signer + */ + default Optional getSalter() { + return this instanceof DecryptedSalter ds ? Optional.of(ds.salter()) : Optional.empty(); + } + + /** + * Returns the Signer if this result contains one. + * + * @return Optional containing the Signer, or empty if this is a Salter + */ + default Optional getSigner() { + return this instanceof DecryptedSigner ds ? Optional.of(ds.signer()) : Optional.empty(); + } + + /** + * Handles this result by invoking the appropriate consumer. + * This is a visitor pattern implementation. + * + * @param salterHandler Consumer to invoke if this is a Salter + * @param signerHandler Consumer to invoke if this is a Signer + */ + default void handle(Consumer salterHandler, Consumer signerHandler) { + switch (this) { + case DecryptedSalter(var salter) -> salterHandler.accept(salter); + case DecryptedSigner(var signer) -> signerHandler.accept(signer); + } + } + + /** + * Maps this result to a value of type T by applying the appropriate function. + * + * @param salterMapper Function to apply if this is a Salter + * @param signerMapper Function to apply if this is a Signer + * @param The type of the result + * @return The result of applying the appropriate mapper + */ + default T map(Function salterMapper, Function signerMapper) { + return switch (this) { + case DecryptedSalter(var salter) -> salterMapper.apply(salter); + case DecryptedSigner(var signer) -> signerMapper.apply(signer); + }; + } + + /** + * Record representing a decrypted Salter. + */ + record DecryptedSalter(Salter salter) implements DecryptResult { + public DecryptedSalter { + if (salter == null) { + throw new IllegalArgumentException("Salter cannot be null"); + } + } + } + + /** + * Record representing a decrypted Signer. + */ + record DecryptedSigner(Signer signer) implements DecryptResult { + public DecryptedSigner { + if (signer == null) { + throw new IllegalArgumentException("Signer cannot be null"); + } + } + } +} + diff --git a/src/main/java/org/cardanofoundation/signify/cesr/Decrypter.java b/src/main/java/org/cardanofoundation/signify/cesr/Decrypter.java index db79068..4b95cd1 100644 --- a/src/main/java/org/cardanofoundation/signify/cesr/Decrypter.java +++ b/src/main/java/org/cardanofoundation/signify/cesr/Decrypter.java @@ -35,7 +35,7 @@ private void setDecrypter() { } } - public Object decrypt(byte[] ser, Cipher cipher, Boolean transferable) throws LibsodiumException { + public DecryptResult decrypt(byte[] ser, Cipher cipher, Boolean transferable) throws LibsodiumException { if (ser == null && cipher == null) { throw new EmptyMaterialException("Neither ser nor matter are provided."); } @@ -47,11 +47,11 @@ public Object decrypt(byte[] ser, Cipher cipher, Boolean transferable) throws Li return decrypter.decrypt(cipher, this.getRaw(), transferable != null && transferable); } - public Object decrypt(byte[] ser, Cipher cipher) throws LibsodiumException { + public DecryptResult decrypt(byte[] ser, Cipher cipher) throws LibsodiumException { return decrypt(ser, cipher, false); } - private Object _x25519(Cipher cipher, byte[] priKey, Boolean transferable) throws LibsodiumException { + private DecryptResult _x25519(Cipher cipher, byte[] priKey, Boolean transferable) throws LibsodiumException { Key pubKey = lazySodium.cryptoScalarMultBase(Key.fromBytes(priKey)); byte[] plain = new byte[cipher.getRaw().length - CRYPTO_BOX_SEAL_BYTES]; boolean success = lazySodium.cryptoBoxSealOpen( @@ -65,9 +65,9 @@ private Object _x25519(Cipher cipher, byte[] priKey, Boolean transferable) throw throw new LibsodiumException("Decryption failed"); } if (cipher.getCode().equals(Codex.MatterCodex.X25519_Cipher_Salt.getValue())) { - return new Salter(plain); + return new DecryptResult.DecryptedSalter(new Salter(plain)); } else if (cipher.getCode().equals(Codex.MatterCodex.X25519_Cipher_Seed.getValue())) { - return new Signer(plain, transferable != null && transferable); + return new DecryptResult.DecryptedSigner(new Signer(plain, transferable != null && transferable)); } else { throw new UnexpectedCodeException("Unsupported cipher text code = " + cipher.getCode()); } @@ -75,6 +75,6 @@ private Object _x25519(Cipher cipher, byte[] priKey, Boolean transferable) throw @FunctionalInterface private interface DecrypterFunction { - Object decrypt(Cipher cipher, byte[] priKey, Boolean transferable) throws LibsodiumException; + DecryptResult decrypt(Cipher cipher, byte[] priKey, Boolean transferable) throws LibsodiumException; } } diff --git a/src/main/java/org/cardanofoundation/signify/cesr/Keeping.java b/src/main/java/org/cardanofoundation/signify/cesr/Keeping.java index 1056fc4..700e259 100644 --- a/src/main/java/org/cardanofoundation/signify/cesr/Keeping.java +++ b/src/main/java/org/cardanofoundation/signify/cesr/Keeping.java @@ -261,23 +261,14 @@ public SaltyKeeper( this.bran = null; this.sxlt = sxlt; Cipher ciph = new Cipher(this.sxlt); - Object decrypted = this.decrypter.decrypt(null, ciph, null); - - if (ciph.getCode().equals(MatterCodex.X25519_Cipher_Salt.getValue())) { - this.creator = new Manager.SaltyCreator( - ((Salter) decrypted).getQb64(), - tier, - this.stem - ); - } else if (ciph.getCode().equals(MatterCodex.X25519_Cipher_Seed.getValue())) { - this.creator = new Manager.SaltyCreator( - ((Signer) decrypted).getQb64(), - tier, - this.stem - ); - } else { - throw new UnexpectedCodeException("Unsupported cipher text code = " + ciph.getCode()); - } + DecryptResult decrypted = this.decrypter.decrypt(null, ciph, null); + + // Use map() to get qb64 from either Salter or Signer + String qb64 = decrypted.map( + Salter::getQb64, + Signer::getQb64 + ); + this.creator = new Manager.SaltyCreator(qb64, tier, this.stem); } this.signers = this.creator.create( @@ -508,11 +499,14 @@ public RandyKeeper( this.signers = new ArrayList<>(); for (String prx : this.prxs) { - this.signers.add((Signer) this.decrypter.decrypt( + DecryptResult result = this.decrypter.decrypt( new Cipher(prx).getQb64b(), null, this.transferable - )); + ); + Signer decryptedSigner = result.getSigner() + .orElseThrow(() -> new UnexpectedCodeException("Expected DecryptedSigner but got DecryptedSalter")); + this.signers.add(decryptedSigner); } } @@ -576,11 +570,13 @@ public KeeperResult rotate( List verfers = new ArrayList<>(); for (String ntx : this.nxts) { - Signer signer = (Signer) this.decrypter.decrypt( + DecryptResult result = this.decrypter.decrypt( null, new Cipher(ntx), this.transferable ); + Signer signer = result.getSigner() + .orElseThrow(() -> new UnexpectedCodeException("Expected DecryptedSigner but got DecryptedSalter")); verfers.add(signer.getVerfer().getQb64()); } @@ -610,11 +606,13 @@ public SignResult sign( ) throws LibsodiumException { List signers = new ArrayList<>(); for (String prx : this.prxs) { - Signer signer = (Signer) this.decrypter.decrypt( + DecryptResult result = this.decrypter.decrypt( new Cipher(prx).getQb64b(), null, this.transferable ); + Signer signer = result.getSigner() + .orElseThrow(() -> new UnexpectedCodeException("Expected DecryptedSigner but got DecryptedSalter")); signers.add(signer); } diff --git a/src/main/java/org/cardanofoundation/signify/core/Manager.java b/src/main/java/org/cardanofoundation/signify/core/Manager.java index b64c5ce..54e5357 100644 --- a/src/main/java/org/cardanofoundation/signify/core/Manager.java +++ b/src/main/java/org/cardanofoundation/signify/core/Manager.java @@ -111,7 +111,12 @@ public String getSalt() throws LibsodiumException { return this.salt; } else { String salt = this.ks.getGbls("salt"); - return ((Matter) this.decrypter.decrypt(salt.getBytes(), null)).getQb64(); + DecryptResult result = this.decrypter.decrypt(salt.getBytes(), null); + // Use map() to extract qb64 regardless of type + return result.map( + Salter::getQb64, + Signer::getQb64 + ); } } @@ -464,7 +469,11 @@ public ManagerRotateResult rotate(RotateArgs args) throws DigestException, Libso // If you provded a Salt for an AID but don't have encryption, pitch a fit throw new RuntimeException("Invalid configuration: AID salt with no encryption"); } - salt = ((Matter) this.decrypter.decrypt(salt.getBytes(), null)).getQb64(); + DecryptResult result = this.decrypter.decrypt(salt.getBytes(), null); + salt = result.map( + Salter::getQb64, + Signer::getQb64 + ); } else { salt = this.getSalt(); } @@ -1122,7 +1131,9 @@ public List> prisElements(Decrypter decrypter) throws List> entries = new ArrayList<>(); for (Map.Entry entry : pris.entrySet()) { Verfer verfer = new Verfer(entry.getKey()); - Signer signer = (Signer) decrypter.decrypt(entry.getValue(), null, verfer.isTransferable()); + DecryptResult result = decrypter.decrypt(entry.getValue(), null, verfer.isTransferable()); + Signer signer = result.getSigner() + .orElseThrow(() -> new RuntimeException("Expected DecryptedSigner but got DecryptedSalter")); entries.add(new AbstractMap.SimpleEntry<>(entry.getKey(), signer)); } return entries; @@ -1148,7 +1159,9 @@ public Signer getPris(String pubKey, Decrypter decrypter) throws LibsodiumExcept return null; } Verfer verfer = new Verfer(pubKey); - return (Signer) decrypter.decrypt(val, null, verfer.isTransferable()); + DecryptResult result = decrypter.decrypt(val, null, verfer.isTransferable()); + return result.getSigner() + .orElseThrow(() -> new RuntimeException("Expected DecryptedSigner but got DecryptedSalter")); } public boolean pinPths(String pubKey, PubPath val) { diff --git a/src/test/java/org/cardanofoundation/signify/cesr/DecrypterTest.java b/src/test/java/org/cardanofoundation/signify/cesr/DecrypterTest.java index cff8817..2991ec8 100644 --- a/src/test/java/org/cardanofoundation/signify/cesr/DecrypterTest.java +++ b/src/test/java/org/cardanofoundation/signify/cesr/DecrypterTest.java @@ -120,60 +120,122 @@ void shouldDecryptStuff() throws LibsodiumException, SodiumException { assertEquals("OLCFxqMz1z1UUS0TEJnvZP_zXHcuYdQsSGBWdOZeY5VQ", decrypter.getQb64()); assertArrayEquals(priKey, decrypter.getRaw()); - // Decrypt seed cipher using ser - Signer designer = (Signer) decrypter.decrypt( + // ===== APPROACH 1: Pattern Matching with Switch (Java 17+) ===== + // This is the cleanest approach - no casting needed! + DecryptResult result = decrypter.decrypt( seedcipher.getQb64b(), null, signer.getVerfer().isTransferable() ); - assertArrayEquals(designer.getQb64b(), seedQb64b); - assertEquals(Codex.MatterCodex.Ed25519_Seed.getValue(), designer.getCode()); - assertEquals(Codex.MatterCodex.Ed25519.getValue(), designer.getVerfer().getCode()); - assertTrue(signer.getVerfer().isTransferable()); - // Decrypt seed cipher using cipher - designer = (Signer) decrypter.decrypt( + switch (result) { + case DecryptResult.DecryptedSigner(var designer) -> { + // designer is automatically extracted and typed as Signer + assertArrayEquals(designer.getQb64b(), seedQb64b); + assertEquals(Codex.MatterCodex.Ed25519_Seed.getValue(), designer.getCode()); + assertEquals(Codex.MatterCodex.Ed25519.getValue(), designer.getVerfer().getCode()); + assertTrue(signer.getVerfer().isTransferable()); + } + case DecryptResult.DecryptedSalter(var salterResult) -> { + fail("Expected DecryptedSigner, got DecryptedSalter"); + } + } + + // ===== APPROACH 2: Pattern Matching with instanceof (Java 16+) ===== + result = decrypter.decrypt( null, seedcipher, signer.getVerfer().isTransferable() ); - assertArrayEquals(designer.getQb64b(), seedQb64b); - assertEquals(Codex.MatterCodex.Ed25519_Seed.getValue(), designer.getCode()); - assertEquals(Codex.MatterCodex.Ed25519.getValue(), designer.getVerfer().getCode()); - assertTrue(signer.getVerfer().isTransferable()); + + if (result instanceof DecryptResult.DecryptedSigner(var designer)) { + // designer is automatically extracted and typed as Signer + assertArrayEquals(designer.getQb64b(), seedQb64b); + assertEquals(Codex.MatterCodex.Ed25519_Seed.getValue(), designer.getCode()); + assertEquals(Codex.MatterCodex.Ed25519.getValue(), designer.getVerfer().getCode()); + assertTrue(signer.getVerfer().isTransferable()); + } else { + fail("Expected DecryptedSigner"); + } // Create cipher of salt Cipher saltcipher = encrypter.encrypt(saltQb64b); assertEquals(Codex.MatterCodex.X25519_Cipher_Salt.getValue(), saltcipher.getCode()); - // Decrypt salt cipher using ser - Salter desalter = (Salter) decrypter.decrypt(saltcipher.getQb64b(), null); - assertArrayEquals(desalter.getQb64b(), saltQb64b); - assertEquals(Codex.MatterCodex.Salt_128.getValue(), desalter.getCode()); + // ===== APPROACH 3: Using map() for functional transformation ===== + result = decrypter.decrypt(saltcipher.getQb64b(), null); + + String qb64Result = result.map( + s -> s.getQb64(), // If Salter + s -> s.getQb64() // If Signer + ); + assertEquals(saltQb64, qb64Result); + + // ===== APPROACH 4: Using handle() for visitor pattern ===== + result = decrypter.decrypt(null, saltcipher); + + result.handle( + desalter -> { + // Handle Salter case + assertArrayEquals(desalter.getQb64b(), saltQb64b); + assertEquals(Codex.MatterCodex.Salt_128.getValue(), desalter.getCode()); + }, + designer -> { + // Handle Signer case + fail("Expected Salter, got Signer"); + } + ); + + // ===== APPROACH 5: Using Optional-based extraction ===== + result = decrypter.decrypt(saltcipher.getQb64b(), null); + + result.getSalter().ifPresent(desalter -> { + assertArrayEquals(desalter.getQb64b(), saltQb64b); + assertEquals(Codex.MatterCodex.Salt_128.getValue(), desalter.getCode()); + }); - // Decrypt salt cipher using cipher - desalter = (Salter) decrypter.decrypt(null, saltcipher); + // Or with orElseThrow + Salter desalter = result.getSalter().orElseThrow(); assertArrayEquals(desalter.getQb64b(), saltQb64b); - assertEquals(Codex.MatterCodex.Salt_128.getValue(), desalter.getCode()); + + // ===== APPROACH 6: Type checking before extraction ===== + result = decrypter.decrypt(null, saltcipher); + + if (result.isSalter()) { + Salter s = result.getSalter().orElseThrow(); + assertArrayEquals(s.getQb64b(), saltQb64b); + assertEquals(Codex.MatterCodex.Salt_128.getValue(), s.getCode()); + } // Use previously stored fully qualified seed cipher with different nonce // get from seedCipher above String cipherSeed = "PM9jOGWNYfjM_oLXJNaQ8UlFSAV5ACjsUY7J16xfzrlpc9Ve3A5WYrZ4o_NHtP5lhp78Usspl9fyFdnCdItNd5JyqZ6dt8SXOt6TOqOCs-gy0obrwFkPPqBvVkEw"; - designer = (Signer) decrypter.decrypt( + result = decrypter.decrypt( cipherSeed.getBytes(), null, signer.getVerfer().isTransferable() ); - assertArrayEquals(designer.getQb64b(), seedQb64b); - assertEquals(Codex.MatterCodex.Ed25519_Seed.getValue(), designer.getCode()); - assertEquals(Codex.MatterCodex.Ed25519.getValue(), designer.getVerfer().getCode()); + + // Using pattern matching - cleanest approach + if (result instanceof DecryptResult.DecryptedSigner(var designer)) { + assertArrayEquals(designer.getQb64b(), seedQb64b); + assertEquals(Codex.MatterCodex.Ed25519_Seed.getValue(), designer.getCode()); + assertEquals(Codex.MatterCodex.Ed25519.getValue(), designer.getVerfer().getCode()); + } // Use previously stored fully qualified salt cipher with different nonce // get from saltCipher above String cipherSalt = "1AAHjlR2QR9J5Et67Wy-ZaVdTryN6T6ohg44r73GLRPnHw-5S3ABFkhWyIwLOI6TXUB_5CT13S8JvknxLxBaF8ANPK9FSOPD8tYu"; - desalter = (Salter) decrypter.decrypt(cipherSalt.getBytes(), null); - assertArrayEquals(desalter.getQb64b(), saltQb64b); - assertEquals(Codex.MatterCodex.Salt_128.getValue(), desalter.getCode()); + result = decrypter.decrypt(cipherSalt.getBytes(), null); + + // Using pattern matching with switch + switch (result) { + case DecryptResult.DecryptedSalter(var s) -> { + assertArrayEquals(s.getQb64b(), saltQb64b); + assertEquals(Codex.MatterCodex.Salt_128.getValue(), s.getCode()); + } + case DecryptResult.DecryptedSigner(var s) -> fail("Expected Salter"); + } // Create new decrypter but use seed parameter to init priKey decrypter = new Decrypter(RawArgs.builder().build(), cryptsigner.getQb64b()); @@ -182,7 +244,10 @@ void shouldDecryptStuff() throws LibsodiumException, SodiumException { assertArrayEquals(priKey, decrypter.getRaw()); // Decrypt cipherSalt - desalter = (Salter) decrypter.decrypt(saltcipher.getQb64b(), null); + result = decrypter.decrypt(saltcipher.getQb64b(), null); + + // Using getSalter() with orElseThrow - simple and clean + desalter = result.getSalter().orElseThrow(); assertArrayEquals(desalter.getQb64b(), saltQb64b); assertEquals(Codex.MatterCodex.Salt_128.getValue(), desalter.getCode()); } diff --git a/src/test/java/org/cardanofoundation/signify/core/ManagerTest.java b/src/test/java/org/cardanofoundation/signify/core/ManagerTest.java index 61b55ea..0d77272 100644 --- a/src/test/java/org/cardanofoundation/signify/core/ManagerTest.java +++ b/src/test/java/org/cardanofoundation/signify/core/ManagerTest.java @@ -220,7 +220,12 @@ void testManager_shouldManageKeyPairsForIdentifiers() throws DigestException, Li assertEquals(manager.getTier(), Salter.Tier.low.name()); Cipher saltCipher0 = new Cipher(manager.getKs().getGbls("salt")); - assertEquals(((Matter) saltCipher0.decrypt(null, seed0b)).getQb64(), salt); + DecryptResult result0 = saltCipher0.decrypt(null, seed0b); + String decryptedSalt = switch (result0) { + case DecryptResult.DecryptedSalter(Salter s) -> s.getQb64(); + case DecryptResult.DecryptedSigner(Signer sig) -> sig.getQb64(); + }; + assertEquals(decryptedSalt, salt); Manager.ManagerInceptArgs managerInceptArgs = Manager.ManagerInceptArgs.builder() .salt(salt) @@ -240,7 +245,12 @@ void testManager_shouldManageKeyPairsForIdentifiers() throws DigestException, Li Manager.PrePrm pp = manager.getKs().getPrms(spre); assertEquals(pp.pidx, 0); assertEquals(pp.algo, Manager.Algos.salty); - assertEquals(((Matter) manager.getDecrypter().decrypt(pp.salt.getBytes(), null)).getQb64(), salt); + DecryptResult result1 = manager.getDecrypter().decrypt(pp.salt.getBytes(), null); + String decryptedSalt1 = switch (result1) { + case DecryptResult.DecryptedSalter(Salter s) -> s.getQb64(); + case DecryptResult.DecryptedSigner(Signer sig) -> sig.getQb64(); + }; + assertEquals(decryptedSalt1, salt); assertEquals(pp.stem, ""); assertEquals(pp.tier, Salter.Tier.low.name()); @@ -360,7 +370,12 @@ void testManager_shouldManageKeyPairsForIdentifiers() throws DigestException, Li pp = manager.getKs().getPrms(spre); assertEquals(pp.pidx, 0); assertEquals(pp.algo, Manager.Algos.salty); - assertEquals(((Matter) manager.getDecrypter().decrypt(pp.salt.getBytes(), null)).getQb64(), salt); + DecryptResult result2 = manager.getDecrypter().decrypt(pp.salt.getBytes(), null); + String decryptedSalt2 = switch (result2) { + case DecryptResult.DecryptedSalter(Salter s) -> s.getQb64(); + case DecryptResult.DecryptedSigner(Signer sig) -> sig.getQb64(); + }; + assertEquals(decryptedSalt2, salt); assertEquals(pp.stem, ""); assertEquals(pp.tier, Salter.Tier.low.name()); @@ -518,7 +533,12 @@ void testManager_shouldManageKeyPairsForIdentifiers() throws DigestException, Li pp = manager.getKs().getPrms(spre); assertEquals(pp.pidx, 3); assertEquals(pp.algo, Manager.Algos.salty); - assertEquals(((Matter) manager.getDecrypter().decrypt(pp.salt.getBytes(), null)).getQb64(), salt); + DecryptResult result3 = manager.getDecrypter().decrypt(pp.salt.getBytes(), null); + String decryptedSalt3 = switch (result3) { + case DecryptResult.DecryptedSalter(Salter s) -> s.getQb64(); + case DecryptResult.DecryptedSigner(Signer sig) -> sig.getQb64(); + }; + assertEquals(decryptedSalt3, salt); assertEquals(pp.stem, stem); assertEquals(pp.tier, Salter.Tier.low.name());