summaryrefslogtreecommitdiffstats
path: root/bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java
diff options
context:
space:
mode:
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java346
1 files changed, 346 insertions, 0 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java
new file mode 100644
index 0000000..c6ca7c2
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java
@@ -0,0 +1,346 @@
+package org.bouncycastle.pqc.jcajce.provider.mceliece;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactorySpi;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey;
+import org.bouncycastle.pqc.asn1.McElieceCCA2PublicKey;
+import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2PrivateKeySpec;
+import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2PublicKeySpec;
+
+/**
+ * This class is used to translate between McEliece CCA2 keys and key
+ * specifications.
+ *
+ * @see BCMcElieceCCA2PrivateKey
+ * @see McElieceCCA2PrivateKeySpec
+ * @see BCMcElieceCCA2PublicKey
+ * @see McElieceCCA2PublicKeySpec
+ */
+public class McElieceCCA2KeyFactorySpi
+ extends KeyFactorySpi
+{
+
+ /**
+ * The OID of the algorithm.
+ */
+ public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2";
+
+ /**
+ * Converts, if possible, a key specification into a
+ * {@link BCMcElieceCCA2PublicKey}. Currently, the following key
+ * specifications are supported: {@link McElieceCCA2PublicKeySpec},
+ * {@link X509EncodedKeySpec}.
+ *
+ * @param keySpec the key specification
+ * @return the McEliece CCA2 public key
+ * @throws InvalidKeySpecException if the key specification is not supported.
+ */
+ public PublicKey generatePublic(KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof McElieceCCA2PublicKeySpec)
+ {
+ return new BCMcElieceCCA2PublicKey(
+ (McElieceCCA2PublicKeySpec)keySpec);
+ }
+ else if (keySpec instanceof X509EncodedKeySpec)
+ {
+ // get the DER-encoded Key according to X.509 from the spec
+ byte[] encKey = ((X509EncodedKeySpec)keySpec).getEncoded();
+
+ // decode the SubjectPublicKeyInfo data structure to the pki object
+ SubjectPublicKeyInfo pki;
+ try
+ {
+ pki = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey));
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeySpecException(e.toString());
+ }
+
+
+ try
+ {
+ // --- Build and return the actual key.
+ ASN1Primitive innerType = pki.parsePublicKey();
+ ASN1Sequence publicKey = (ASN1Sequence)innerType;
+
+ // decode oidString (but we don't need it right now)
+ String oidString = ((ASN1ObjectIdentifier)publicKey.getObjectAt(0))
+ .toString();
+
+ // decode <n>
+ BigInteger bigN = ((ASN1Integer)publicKey.getObjectAt(1)).getValue();
+ int n = bigN.intValue();
+
+ // decode <t>
+ BigInteger bigT = ((ASN1Integer)publicKey.getObjectAt(2)).getValue();
+ int t = bigT.intValue();
+
+ // decode <matrixG>
+ byte[] matrixG = ((ASN1OctetString)publicKey.getObjectAt(3)).getOctets();
+
+ return new BCMcElieceCCA2PublicKey(new McElieceCCA2PublicKeySpec(
+ OID, n, t, matrixG));
+ }
+ catch (IOException cce)
+ {
+ throw new InvalidKeySpecException(
+ "Unable to decode X509EncodedKeySpec: "
+ + cce.getMessage());
+ }
+ }
+
+ throw new InvalidKeySpecException("Unsupported key specification: "
+ + keySpec.getClass() + ".");
+ }
+
+ /**
+ * Converts, if possible, a key specification into a
+ * {@link BCMcElieceCCA2PrivateKey}. Currently, the following key
+ * specifications are supported: {@link McElieceCCA2PrivateKeySpec},
+ * {@link PKCS8EncodedKeySpec}.
+ *
+ * @param keySpec the key specification
+ * @return the McEliece CCA2 private key
+ * @throws InvalidKeySpecException if the KeySpec is not supported.
+ */
+ public PrivateKey generatePrivate(KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof McElieceCCA2PrivateKeySpec)
+ {
+ return new BCMcElieceCCA2PrivateKey(
+ (McElieceCCA2PrivateKeySpec)keySpec);
+ }
+ else if (keySpec instanceof PKCS8EncodedKeySpec)
+ {
+ // get the DER-encoded Key according to PKCS#8 from the spec
+ byte[] encKey = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
+
+ // decode the PKCS#8 data structure to the pki object
+ PrivateKeyInfo pki;
+
+ try
+ {
+ pki = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey));
+ }
+ catch (IOException e)
+ {
+ throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec: " + e);
+ }
+
+ try
+ {
+ // get the inner type inside the BIT STRING
+ ASN1Primitive innerType = pki.parsePrivateKey().toASN1Primitive();
+
+ // build and return the actual key
+ ASN1Sequence privKey = (ASN1Sequence)innerType;
+
+ // decode oidString (but we don't need it right now)
+ String oidString = ((ASN1ObjectIdentifier)privKey.getObjectAt(0))
+ .toString();
+
+ // decode <n>
+ BigInteger bigN = ((ASN1Integer)privKey.getObjectAt(1)).getValue();
+ int n = bigN.intValue();
+
+ // decode <k>
+ BigInteger bigK = ((ASN1Integer)privKey.getObjectAt(2)).getValue();
+ int k = bigK.intValue();
+
+
+ // decode <fieldPoly>
+ byte[] encFieldPoly = ((ASN1OctetString)privKey.getObjectAt(3))
+ .getOctets();
+ // decode <goppaPoly>
+ byte[] encGoppaPoly = ((ASN1OctetString)privKey.getObjectAt(4))
+ .getOctets();
+ // decode <p>
+ byte[] encP = ((ASN1OctetString)privKey.getObjectAt(5)).getOctets();
+ // decode <h>
+ byte[] encH = ((ASN1OctetString)privKey.getObjectAt(6)).getOctets();
+ // decode <qInv>
+ ASN1Sequence qSeq = (ASN1Sequence)privKey.getObjectAt(7);
+ byte[][] encQInv = new byte[qSeq.size()][];
+ for (int i = 0; i < qSeq.size(); i++)
+ {
+ encQInv[i] = ((ASN1OctetString)qSeq.getObjectAt(i)).getOctets();
+ }
+
+ return new BCMcElieceCCA2PrivateKey(
+ new McElieceCCA2PrivateKeySpec(OID, n, k, encFieldPoly,
+ encGoppaPoly, encP, encH, encQInv));
+
+ }
+ catch (IOException cce)
+ {
+ throw new InvalidKeySpecException(
+ "Unable to decode PKCS8EncodedKeySpec.");
+ }
+ }
+
+ throw new InvalidKeySpecException("Unsupported key specification: "
+ + keySpec.getClass() + ".");
+ }
+
+ /**
+ * Converts, if possible, a given key into a key specification. Currently,
+ * the following key specifications are supported:
+ * <ul>
+ * <li>for McElieceCCA2PublicKey: {@link X509EncodedKeySpec},
+ * {@link McElieceCCA2PublicKeySpec}</li>
+ * <li>for McElieceCCA2PrivateKey: {@link PKCS8EncodedKeySpec},
+ * {@link McElieceCCA2PrivateKeySpec}</li>.
+ * </ul>
+ *
+ * @param key the key
+ * @param keySpec the key specification
+ * @return the specification of the McEliece CCA2 key
+ * @throws InvalidKeySpecException if the key type or the key specification is not
+ * supported.
+ * @see BCMcElieceCCA2PrivateKey
+ * @see McElieceCCA2PrivateKeySpec
+ * @see BCMcElieceCCA2PublicKey
+ * @see McElieceCCA2PublicKeySpec
+ */
+ public KeySpec getKeySpec(Key key, Class keySpec)
+ throws InvalidKeySpecException
+ {
+ if (key instanceof BCMcElieceCCA2PrivateKey)
+ {
+ if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec))
+ {
+ return new PKCS8EncodedKeySpec(key.getEncoded());
+ }
+ else if (McElieceCCA2PrivateKeySpec.class
+ .isAssignableFrom(keySpec))
+ {
+ BCMcElieceCCA2PrivateKey privKey = (BCMcElieceCCA2PrivateKey)key;
+ return new McElieceCCA2PrivateKeySpec(OID, privKey.getN(), privKey
+ .getK(), privKey.getField(), privKey.getGoppaPoly(),
+ privKey.getP(), privKey.getH(), privKey.getQInv());
+ }
+ }
+ else if (key instanceof BCMcElieceCCA2PublicKey)
+ {
+ if (X509EncodedKeySpec.class.isAssignableFrom(keySpec))
+ {
+ return new X509EncodedKeySpec(key.getEncoded());
+ }
+ else if (McElieceCCA2PublicKeySpec.class
+ .isAssignableFrom(keySpec))
+ {
+ BCMcElieceCCA2PublicKey pubKey = (BCMcElieceCCA2PublicKey)key;
+ return new McElieceCCA2PublicKeySpec(OID, pubKey.getN(), pubKey
+ .getT(), pubKey.getG());
+ }
+ }
+ else
+ {
+ throw new InvalidKeySpecException("Unsupported key type: "
+ + key.getClass() + ".");
+ }
+
+ throw new InvalidKeySpecException("Unknown key specification: "
+ + keySpec + ".");
+ }
+
+ /**
+ * Translates a key into a form known by the FlexiProvider. Currently, only
+ * the following "source" keys are supported: {@link BCMcElieceCCA2PrivateKey},
+ * {@link BCMcElieceCCA2PublicKey}.
+ *
+ * @param key the key
+ * @return a key of a known key type
+ * @throws InvalidKeyException if the key type is not supported.
+ */
+ public Key translateKey(Key key)
+ throws InvalidKeyException
+ {
+ if ((key instanceof BCMcElieceCCA2PrivateKey)
+ || (key instanceof BCMcElieceCCA2PublicKey))
+ {
+ return key;
+ }
+ throw new InvalidKeyException("Unsupported key type.");
+
+ }
+
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo pki)
+ throws InvalidKeySpecException
+ {
+ // get the inner type inside the BIT STRING
+ try
+ {
+ ASN1Primitive innerType = pki.parsePublicKey();
+ McElieceCCA2PublicKey key = McElieceCCA2PublicKey.getInstance((ASN1Sequence)innerType);
+ return new BCMcElieceCCA2PublicKey(key.getOID().getId(), key.getN(), key.getT(), key.getG());
+ }
+ catch (IOException cce)
+ {
+ throw new InvalidKeySpecException("Unable to decode X509EncodedKeySpec");
+ }
+ }
+
+
+ public PrivateKey generatePrivate(PrivateKeyInfo pki)
+ throws InvalidKeySpecException
+ {
+ // get the inner type inside the BIT STRING
+ try
+ {
+ ASN1Primitive innerType = pki.parsePrivateKey().toASN1Primitive();
+ McElieceCCA2PrivateKey key = McElieceCCA2PrivateKey.getInstance(innerType);
+ return new BCMcElieceCCA2PrivateKey(key.getOID().getId(), key.getN(), key.getK(), key.getField(), key.getGoppaPoly(), key.getP(), key.getH(), key.getQInv());
+ }
+ catch (IOException cce)
+ {
+ throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec");
+ }
+ }
+
+ protected PublicKey engineGeneratePublic(KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ protected KeySpec engineGetKeySpec(Key key, Class tClass)
+ throws InvalidKeySpecException
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ protected Key engineTranslateKey(Key key)
+ throws InvalidKeyException
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+}