package peergos.shared; import jsinterop.annotations.*; import peergos.shared.crypto.asymmetric.*; import peergos.shared.crypto.asymmetric.curve25519.*; import peergos.shared.crypto.hash.*; import peergos.shared.crypto.random.*; import peergos.shared.crypto.symmetric.*; import java.util.function.*; public class Crypto { private static Crypto INSTANCE; private static boolean isJava; @JsProperty public final SafeRandom random; public final LoginHasher hasher; public final Salsa20Poly1305 symmetricProvider; public final Ed25519 signer; public final Curve25519 boxer; public Crypto(SafeRandom random, LoginHasher hasher, Salsa20Poly1305 symmetricProvider, Ed25519 signer, Curve25519 boxer) { this.random = random; this.hasher = hasher; this.symmetricProvider = symmetricProvider; this.signer = signer; this.boxer = boxer; } private static synchronized Crypto init(Supplier<Crypto> instanceCreator, boolean isJava) { if (INSTANCE != null && Crypto.isJava ^ isJava) throw new IllegalStateException("Crypto is already initialized to a different type!"); if (INSTANCE != null) return INSTANCE; Crypto instance = instanceCreator.get(); INSTANCE = instance; Crypto.isJava = isJava; SymmetricKey.addProvider(SymmetricKey.Type.TweetNaCl, instance.symmetricProvider); PublicSigningKey.addProvider(PublicSigningKey.Type.Ed25519, instance.signer); SymmetricKey.setRng(SymmetricKey.Type.TweetNaCl, instance.random); PublicBoxingKey.addProvider(PublicBoxingKey.Type.Curve25519, instance.boxer); PublicBoxingKey.setRng(PublicBoxingKey.Type.Curve25519, instance.random); return instance; } @JsMethod public static Crypto initJS() { SafeRandom.Javascript random = new SafeRandom.Javascript(); Salsa20Poly1305.Javascript symmetricProvider = new Salsa20Poly1305.Javascript(); Ed25519.Javascript signer = new Ed25519.Javascript(); Curve25519.Javascript boxer = new Curve25519.Javascript(); return init(() -> new Crypto(random, new ScryptJS(), symmetricProvider, signer, boxer), false); } public static Crypto initJava() { SafeRandom.Java random = new SafeRandom.Java(); Salsa20Poly1305.Java symmetricProvider = new Salsa20Poly1305.Java(); Ed25519.Java signer = new Ed25519.Java(); Curve25519 boxer = new Curve25519.Java(); return init(() -> new Crypto(random, new ScryptJava(), symmetricProvider, signer, boxer), true); } }