0

I was wondering if there are already Providers in the Java Cryptography Architecture (JCA) for post-quantum signature schemes, especially XMSS^MT?

whme
  • 4,908
  • 5
  • 15
  • 28
  • See [this](https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html), [this](https://docs.oracle.com/javase/9/security/oracleproviders.htm#JSSEC-GUID-FE2D2E28-C991-4EF9-9DBE-2A4982726313), [this](https://docs.oracle.com/javase/10/security/oracle-providers.htm#JSSEC-GUID-FE2D2E28-C991-4EF9-9DBE-2A4982726313) and so on. You might next look for third-party providers. – President James K. Polk Nov 22 '18 at 16:37
  • this, this, this <- no xmss^mt,. no xmss^mt, no xmss^mt.. – whme Nov 22 '18 at 16:51
  • Sorry, maybe a third-party provider. Check Bouncycastle, and there is a German university that I recall has a post-quantum provider ... I'll see what I can find. – President James K. Polk Nov 22 '18 at 16:53
  • The german one is was thinking of is flexiprovider, but I don't see any evidencee of XMSS support. On the other hand, Bouncycastle has XMSS support so you should give it a try. – President James K. Polk Nov 22 '18 at 16:59
  • Thank you very much! I found BouncyCastlePQCProvider though I seem to be unable to implement it correctly in the JCA, are you experienced with this ? – whme Nov 22 '18 at 17:08
  • No, I might play around a bit to see if I can make some progress with it. – President James K. Polk Nov 22 '18 at 17:09
  • Thank you very much, in the meantime I will try to figure it out as well. – whme Nov 22 '18 at 17:11

1 Answers1

0

Here is an example taken almost verbatim from the Bouncycastle source code in org.bouncycastle.pqc.jcajce.provider.test.XMSSMTTest. This code was run on Java 8.

import org.bouncycastle.pqc.jcajce.interfaces.StateAwareSignature;
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
import org.bouncycastle.pqc.jcajce.spec.XMSSMTParameterSpec;
import org.bouncycastle.util.Strings;

import java.security.*;

public class Main {

    private static void fail(boolean condition, String msg) {
        if (condition) {
            throw new RuntimeException(msg);
        }
    }

    public static void main(String[] args) throws Exception {
        Security.addProvider(new BouncyCastlePQCProvider());
        byte[] msg = Strings.toByteArray("Cthulhu Fthagn --What a wonderful phrase!Cthulhu Fthagn --Say it and you're crazed!");
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("XMSSMT", "BCPQC");

        kpg.initialize(new XMSSMTParameterSpec(20, 10, XMSSMTParameterSpec.SHA256), new SecureRandom());

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SHA256withXMSSMT", "BCPQC");

        fail(!(sig instanceof StateAwareSignature), "wrong signature instance");

        StateAwareSignature xmssSig = (StateAwareSignature) sig;

        xmssSig.initSign(kp.getPrivate());

        fail(!xmssSig.isSigningCapable(), "signature object is not signing-capable");

        xmssSig.update(msg, 0, msg.length);

        byte[] s = sig.sign();

        PrivateKey nKey = xmssSig.getUpdatedPrivateKey();

        fail(kp.getPrivate().equals(nKey), "");
        fail(xmssSig.isSigningCapable(), "signature object is signing-capable");

        xmssSig.update(msg, 0, msg.length);

        try {
            sig.sign();
            fail(true, "no exception after key extraction");
        } catch (SignatureException e) {
            fail(!"signing key no longer usable".equals(e.getMessage()), "wrong exception");
        }

        try {
            xmssSig.getUpdatedPrivateKey();
            fail(true, "no exception after key extraction");
        } catch (IllegalStateException e) {
            fail(!"signature object not in a signing state".equals(e.getMessage()), "wrong exception");
        }

        xmssSig.initSign(nKey);

        xmssSig.update(msg, 0, msg.length);

        s = sig.sign();

        xmssSig.initVerify(kp.getPublic());

        xmssSig.update(msg, 0, msg.length);

        fail(!xmssSig.verify(s), "verification failure");
    }
}

There are other examples in that file as well. Source code is available here.

President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
  • Thank you very much James, when I try to implement the BouncyCastlePQCProvider to the JCA like described [here](https://docs.oracle.com/javase/9/security/howtoimplaprovider.htm#JSSEC-GUID-FB9C6DB2-DE9A-4EFE-89B4-C2C168C5982D) under Step 8, it does not get recognized. `keytool -genkeypair -alias -keyalg xmss` prompts: `no such algorithm exeption` which means the BCProvider does not get recognized (as it clearly does provide the xmss alg for keygen). As you did already help me a lot, might you have an idea for this as well ? ^^ – whme Nov 22 '18 at 20:41
  • @NicolasBrauer: is the provider configured in your JRE/lib/security/java.security or j9+ JRE/conf/security/java.security and is the jar findable (through j8 JRE/lib/ext is good)? (If the first part is true your code wouldn't need the Security.addProvider call. Remember BouncyCastlePQCProvider and BouncyCastleProvider are different.) – dave_thompson_085 Nov 22 '18 at 22:29
  • Those instructions are for building and signing *your own provider*. Leave those java.security files alone. Bouncycastle has already gotten their provider jar properly signed, just place the `bcprov-jdk15on-160.jar` file on your classpath and add the provider as in the example. – President James K. Polk Nov 22 '18 at 22:58
  • @dave_thompson_085 thank you but as of java9(or even 8 i dont know) `extensions mechanism are no longer supported; Use -classpath instead.` @JamesKPolk thank you very much this helps a lot, though i will not be able to add the provider as in the example as I don't intend using it to write java code but only to use jarsigner with it through command line interface. So how would I add it statically? (as the example is used to add it dynamically) – whme Nov 23 '18 at 08:53
  • @NicolasBrauer: j8 still has lib/ext; I didn't remember which higher version dropped it and I believe you it's 9. In classpath counts as 'findable'. If you don't config the provider in java.security, for keytool and jarsigner use `-providerClass classname` (specifying the full name of BouncyCastlePQCProvider). Meta: on Stack @ can only 'ping' one person (and did me) but that's okay because the _post author_ (here James) is _automatically_ pinged. – dave_thompson_085 Nov 23 '18 at 10:56
  • @dave_thompson_085 thank you very much ! Sadly `keytool -genkeypair -alias xmss -providerClass org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider -keyalg XMSS -sigalg SHA256withXMSS -dname CN=Jave -storetype JKS -keypass password -keystore mytest.jks -storepass password` raises `keytool error: java.lang.Exception: Provider "org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider" not found` so what did I do wrong ? – whme Nov 23 '18 at 11:12
  • 1
    On checking, keytool and jarsigner don't use the normal classpath, so you also need `-providerpath jarfile` to find the provider. However, it appears keytool only uses the init(int) overload and XMSSKeyPairGeneratorSpi rejects that; it wants AlgorithmParameterSpec specifically XMSSParameterSpec, or no init at all -- and if I try the latter, it does generates a keypair, but the resulting keys can't be encoded and thus can't be stored. Bleah. I think you'll have to code the generation. I haven't looked at the signature side yet. – dave_thompson_085 Nov 24 '18 at 23:48
  • @dave_thompson_085 you are awesome! thank you so much! I kinda noticed as well that the xmss and xmssmt keys can't get encoded thus not be stored in the KeyStore. Is there a way to talk via private message or mail or smthg in order to not 'abuse' the initial question posted? – whme Nov 25 '18 at 23:17