title: SHA3-512 to Generate Keys in Java
body: <p>Is it possible to use SHA3-512(a subset of keccak available in Java9) to generate keys in Java? </p>
  
  <p>I have searched through a lot of noise and documentation to try to figure this out.
  Currently it seems SHA3-512 is available as a hash for MessageDigest but not for generating keys. My code below tries to generate keys predictably(for wallet purposes like BIP32 but beyond currency to blockchain uses)</p>
  
  <p><a href="https://github.com/devssh/BlockchainFullNode/blob/d2978e598b4cdecdf4b3337713b2c3e839a6b181/src/main/java/app/model/Keyz.java#L111-L128" rel="nofollow noreferrer">https://github.com/devssh/BlockchainFullNode/blob/d2978e598b4cdecdf4b3337713b2c3e839a6b181/src/main/java/app/model/Keyz.java#L111-L128</a></p>
  
  <pre><code>    public static String GenerateSeed() throws Exception {
          SecureRandom random = new SecureRandom();
          byte[] seed = random.generateSeed(512);
          return Base64.getEncoder().encodeToString(seed);
      }
  
      public static Keyz GenerateKey(String seedString) {
          Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
          KeyPairGenerator keyGen1 = KeyPairGenerator.getInstance("ECDSA");
          ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256k1");
          SecureRandom random1 = SecureRandom.getInstance("SHA1PRNG");
          random1.setSeed(Base64.getDecoder().decode(seedString));
          keyGen1.initialize(ecSpec, random1);
          KeyPair keyPair1 = keyGen1.generateKeyPair();
          PublicKey pub1 = keyPair1.getPublic();
          PrivateKey priv1 = keyPair1.getPrivate();
          //Keyz is a simple model that stores the 3 fields below and overrides equals and hashcode on those fields
          return new Keyz("random", pub1, priv1);
      }
  </code></pre>
  
  <p>As you can see, it uses SHA1PRNG to predictably generate keypair deterministically(I am fine with the security concerns on this) so that the keys can be recreated deterministically.</p>
  
  <p>Here is a JUnit test to make sure the keys are deterministic(works for SHA1PRNG, needs to work in SHA3PRNG). Ideally what is needed is a SHA3-512 TRNG in the GenerateSeed and a SHA3PRNG in the GenerateKey. Since the keygenerator needs a SecureRandom I would be surprised if java.Security.SecureRandom is still on something as insecure as SHA1PRNG.</p>
  
  <p><a href="https://github.com/devssh/BlockchainFullNode/blob/d2978e598b4cdecdf4b3337713b2c3e839a6b181/test/main/java/app/model/KeyzTest.java#L16-L22" rel="nofollow noreferrer">https://github.com/devssh/BlockchainFullNode/blob/d2978e598b4cdecdf4b3337713b2c3e839a6b181/test/main/java/app/model/KeyzTest.java#L16-L22</a></p>
  
  <pre><code>    @Test
      public void shouldReturnDeterministicKeys() throws Exception {
          String seedString = GenerateSeed();
          Keyz random1 = GenerateKey(seedString);
          Keyz random2 = GenerateKey(seedString);
          //This assertion works as we override equals and hashcode
          assertEquals(random1, random2);
      }
  </code></pre>
  
  <p>Can someone please let me know if they figured a way to get this to work</p>