summaryrefslogtreecommitdiffstats
path: root/bcprov/src/main/java/org/bouncycastle/pqc/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/pqc/crypto')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/DigestingMessageSigner.java117
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/MessageEncryptor.java30
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/MessageSigner.java32
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSDigestProvider.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyGenerationParameters.java26
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyPairGenerator.java476
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyParameters.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSLeaf.java376
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSParameters.java155
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSPrivateKeyParameters.java1041
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSPublicKeyParameters.java33
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSRootCalc.java596
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSRootSig.java666
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSSigner.java403
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSUtils.java145
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/Treehash.java525
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/GMSSRandom.java78
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/GMSSUtil.java151
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/WinternitzOTSVerify.java344
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/WinternitzOTSignature.java404
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/Conversions.java236
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyGenerationParameters.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyPairGenerator.java119
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyParameters.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Parameters.java51
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Primitives.java86
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PrivateKeyParameters.java172
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PublicKeyParameters.java97
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiCipher.java218
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiDigestCipher.java128
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyGenerationParameters.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java151
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyParameters.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiCipher.java319
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiDigestCipher.java128
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSCipher.java224
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSDigestCipher.java128
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceParameters.java181
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalCipher.java241
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalDigestCipher.java128
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePrivateKeyParameters.java197
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePublicKeyParameters.java96
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/IndexGenerator.java239
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyGenerationParameters.java463
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyPairGenerator.java113
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyParameters.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionParameters.java410
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionPrivateKeyParameters.java199
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionPublicKeyParameters.java131
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEngine.java495
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigner.java263
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSignerPrng.java64
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningKeyGenerationParameters.java407
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningKeyPairGenerator.java357
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningParameters.java269
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningPrivateKeyParameters.java388
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningPublicKeyParameters.java132
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/Layer.java322
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyGenerationParameters.java26
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyPairGenerator.java417
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyParameters.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowParameters.java111
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowPrivateKeyParameters.java117
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowPublicKeyParameters.java53
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowSigner.java301
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/ComputeInField.java490
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/GF2Field.java139
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/RainbowUtil.java230
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/AllTests.java47
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/BitStringTest.java88
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/EncryptionKeyTest.java51
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/GMSSSignerTest.java88
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McElieceFujisakiCipherTest.java102
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McElieceKobaraImaiCipherTest.java102
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McEliecePKCSCipherTest.java102
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McEliecePointchevalCipherTest.java102
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUEncryptTest.java298
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUEncryptionParametersTest.java48
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignatureKeyTest.java58
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignatureParametersTest.java64
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignerTest.java317
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSigningParametersTest.java65
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/RainbowSignerTest.java67
-rw-r--r--bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/RegressionTest.java33
85 files changed, 0 insertions, 16448 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/DigestingMessageSigner.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/DigestingMessageSigner.java
deleted file mode 100644
index 6b5b251..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/DigestingMessageSigner.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.bouncycastle.pqc.crypto;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.Signer;
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-
-
-/**
- * Implements the sign and verify functions for a Signature Scheme which can use a hash function.
- */
-public class DigestingMessageSigner
- implements Signer
-{
- private final Digest messDigest;
- private final MessageSigner messSigner;
- private boolean forSigning;
-
- public DigestingMessageSigner(MessageSigner messSigner, Digest messDigest)
- {
- this.messSigner = messSigner;
- this.messDigest = messDigest;
- }
-
- public void init(boolean forSigning,
- CipherParameters param)
- {
-
- this.forSigning = forSigning;
- AsymmetricKeyParameter k;
-
- if (param instanceof ParametersWithRandom)
- {
- k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters();
- }
- else
- {
- k = (AsymmetricKeyParameter)param;
- }
-
- if (forSigning && !k.isPrivate())
- {
- throw new IllegalArgumentException("Signing Requires Private Key.");
- }
-
- if (!forSigning && k.isPrivate())
- {
- throw new IllegalArgumentException("Verification Requires Public Key.");
- }
-
- reset();
-
- messSigner.init(forSigning, param);
- }
-
-
- /**
- * This function signs the message that has been updated, making use of the
- * private key.
- *
- * @return the signature of the message.
- */
- public byte[] generateSignature()
- {
- if (!forSigning)
- {
- throw new IllegalStateException("RainbowDigestSigner not initialised for signature generation.");
- }
-
- byte[] hash = new byte[messDigest.getDigestSize()];
- messDigest.doFinal(hash, 0);
-
- return messSigner.generateSignature(hash);
- }
-
- /**
- * This function verifies the signature of the message that has been
- * updated, with the aid of the public key.
- *
- * @param signature the signature of the message is given as a byte array.
- * @return true if the signature has been verified, false otherwise.
- */
- public boolean verify(byte[] signature)
- {
- if (forSigning)
- {
- throw new IllegalStateException("RainbowDigestSigner not initialised for verification");
- }
-
- byte[] hash = new byte[messDigest.getDigestSize()];
- messDigest.doFinal(hash, 0);
-
- return messSigner.verifySignature(hash, signature);
-
- }
-
- public void update(byte b)
- {
- messDigest.update(b);
- }
-
- public void update(byte[] in, int off, int len)
- {
- messDigest.update(in, off, len);
- }
-
- public void reset()
- {
- messDigest.reset();
- }
-
- public boolean verifySignature(byte[] signature)
- {
- return this.verify(signature);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/MessageEncryptor.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/MessageEncryptor.java
deleted file mode 100644
index 8d67c5c..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/MessageEncryptor.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.bouncycastle.pqc.crypto;
-
-
-import org.bouncycastle.crypto.CipherParameters;
-
-public interface MessageEncryptor
-{
-
- /**
- *
- * @param forEncrypting true if we are encrypting a signature, false
- * otherwise.
- * @param param key parameters for encryption or decryption.
- */
- public void init(boolean forEncrypting, CipherParameters param);
-
- /**
- *
- * @param message the message to be signed.
- * @throws Exception
- */
- public byte[] messageEncrypt(byte[] message) throws Exception;
-
- /**
- *
- * @param cipher the cipher text of the message
- * @throws Exception
- */
- public byte[] messageDecrypt(byte[] cipher) throws Exception;
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/MessageSigner.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/MessageSigner.java
deleted file mode 100644
index 50243f7..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/MessageSigner.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.bouncycastle.pqc.crypto;
-
-import org.bouncycastle.crypto.CipherParameters;
-
-public interface MessageSigner
-{
- /**
- * initialise the signer for signature generation or signature
- * verification.
- *
- * @param forSigning true if we are generating a signature, false
- * otherwise.
- * @param param key parameters for signature generation.
- */
- public void init(boolean forSigning, CipherParameters param);
-
- /**
- * sign the passed in message (usually the output of a hash function).
- *
- * @param message the message to be signed.
- * @return the signature of the message
- */
- public byte[] generateSignature(byte[] message);
-
- /**
- * verify the message message against the signature values r and s.
- *
- * @param message the message that was supposed to have been signed.
- * @param signature the signature of the message
- */
- public boolean verifySignature(byte[] message, byte[] signature);
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSDigestProvider.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSDigestProvider.java
deleted file mode 100644
index 4af1a8b..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSDigestProvider.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import org.bouncycastle.crypto.Digest;
-
-public interface GMSSDigestProvider
-{
- Digest get();
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyGenerationParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyGenerationParameters.java
deleted file mode 100644
index eace4d0..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyGenerationParameters.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.KeyGenerationParameters;
-
-public class GMSSKeyGenerationParameters
- extends KeyGenerationParameters
-{
-
- private GMSSParameters params;
-
- public GMSSKeyGenerationParameters(
- SecureRandom random,
- GMSSParameters params)
- {
- // XXX key size?
- super(random, 1);
- this.params = params;
- }
-
- public GMSSParameters getParameters()
- {
- return params;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyPairGenerator.java
deleted file mode 100644
index 013441e..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyPairGenerator.java
+++ /dev/null
@@ -1,476 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import java.security.SecureRandom;
-import java.util.Vector;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.KeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom;
-import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSVerify;
-import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSignature;
-
-
-/**
- * This class implements key pair generation of the generalized Merkle signature
- * scheme (GMSS).
- *
- * @see GMSSSigner
- */
-public class GMSSKeyPairGenerator
- implements AsymmetricCipherKeyPairGenerator
-{
- /**
- * The source of randomness for OTS private key generation
- */
- private GMSSRandom gmssRandom;
-
- /**
- * The hash function used for the construction of the authentication trees
- */
- private Digest messDigestTree;
-
- /**
- * An array of the seeds for the PRGN (for main tree, and all current
- * subtrees)
- */
- private byte[][] currentSeeds;
-
- /**
- * An array of seeds for the PRGN (for all subtrees after next)
- */
- private byte[][] nextNextSeeds;
-
- /**
- * An array of the RootSignatures
- */
- private byte[][] currentRootSigs;
-
- /**
- * Class of hash function to use
- */
- private GMSSDigestProvider digestProvider;
-
- /**
- * The length of the seed for the PRNG
- */
- private int mdLength;
-
- /**
- * the number of Layers
- */
- private int numLayer;
-
-
- /**
- * Flag indicating if the class already has been initialized
- */
- private boolean initialized = false;
-
- /**
- * Instance of GMSSParameterset
- */
- private GMSSParameters gmssPS;
-
- /**
- * An array of the heights of the authentication trees of each layer
- */
- private int[] heightOfTrees;
-
- /**
- * An array of the Winternitz parameter 'w' of each layer
- */
- private int[] otsIndex;
-
- /**
- * The parameter K needed for the authentication path computation
- */
- private int[] K;
-
- private GMSSKeyGenerationParameters gmssParams;
-
- /**
- * The GMSS OID.
- */
- public static final String OID = "1.3.6.1.4.1.8301.3.1.3.3";
-
- /**
- * The standard constructor tries to generate the GMSS algorithm identifier
- * with the corresponding OID.
- *
- * @param digestProvider provider for digest implementations.
- */
- public GMSSKeyPairGenerator(GMSSDigestProvider digestProvider)
- {
- this.digestProvider = digestProvider;
- messDigestTree = digestProvider.get();
-
- // set mdLength
- this.mdLength = messDigestTree.getDigestSize();
- // construct randomizer
- this.gmssRandom = new GMSSRandom(messDigestTree);
-
- }
-
- /**
- * Generates the GMSS key pair. The public key is an instance of
- * JDKGMSSPublicKey, the private key is an instance of JDKGMSSPrivateKey.
- *
- * @return Key pair containing a JDKGMSSPublicKey and a JDKGMSSPrivateKey
- */
- private AsymmetricCipherKeyPair genKeyPair()
- {
- if (!initialized)
- {
- initializeDefault();
- }
-
- // initialize authenticationPaths and treehash instances
- byte[][][] currentAuthPaths = new byte[numLayer][][];
- byte[][][] nextAuthPaths = new byte[numLayer - 1][][];
- Treehash[][] currentTreehash = new Treehash[numLayer][];
- Treehash[][] nextTreehash = new Treehash[numLayer - 1][];
-
- Vector[] currentStack = new Vector[numLayer];
- Vector[] nextStack = new Vector[numLayer - 1];
-
- Vector[][] currentRetain = new Vector[numLayer][];
- Vector[][] nextRetain = new Vector[numLayer - 1][];
-
- for (int i = 0; i < numLayer; i++)
- {
- currentAuthPaths[i] = new byte[heightOfTrees[i]][mdLength];
- currentTreehash[i] = new Treehash[heightOfTrees[i] - K[i]];
-
- if (i > 0)
- {
- nextAuthPaths[i - 1] = new byte[heightOfTrees[i]][mdLength];
- nextTreehash[i - 1] = new Treehash[heightOfTrees[i] - K[i]];
- }
-
- currentStack[i] = new Vector();
- if (i > 0)
- {
- nextStack[i - 1] = new Vector();
- }
- }
-
- // initialize roots
- byte[][] currentRoots = new byte[numLayer][mdLength];
- byte[][] nextRoots = new byte[numLayer - 1][mdLength];
- // initialize seeds
- byte[][] seeds = new byte[numLayer][mdLength];
- // initialize seeds[] by copying starting-seeds of first trees of each
- // layer
- for (int i = 0; i < numLayer; i++)
- {
- System.arraycopy(currentSeeds[i], 0, seeds[i], 0, mdLength);
- }
-
- // initialize rootSigs
- currentRootSigs = new byte[numLayer - 1][mdLength];
-
- // -------------------------
- // -------------------------
- // --- calculation of current authpaths and current rootsigs (AUTHPATHS,
- // SIG)------
- // from bottom up to the root
- for (int h = numLayer - 1; h >= 0; h--)
- {
- GMSSRootCalc tree = new GMSSRootCalc(this.heightOfTrees[h], this.K[h], digestProvider);
- try
- {
- // on lowest layer no lower root is available, so just call
- // the method with null as first parameter
- if (h == numLayer - 1)
- {
- tree = this.generateCurrentAuthpathAndRoot(null, currentStack[h], seeds[h], h);
- }
- else
- // otherwise call the method with the former computed root
- // value
- {
- tree = this.generateCurrentAuthpathAndRoot(currentRoots[h + 1], currentStack[h], seeds[h], h);
- }
-
- }
- catch (Exception e1)
- {
- e1.printStackTrace();
- }
-
- // set initial values needed for the private key construction
- for (int i = 0; i < heightOfTrees[h]; i++)
- {
- System.arraycopy(tree.getAuthPath()[i], 0, currentAuthPaths[h][i], 0, mdLength);
- }
- currentRetain[h] = tree.getRetain();
- currentTreehash[h] = tree.getTreehash();
- System.arraycopy(tree.getRoot(), 0, currentRoots[h], 0, mdLength);
- }
-
- // --- calculation of next authpaths and next roots (AUTHPATHS+, ROOTS+)
- // ------
- for (int h = numLayer - 2; h >= 0; h--)
- {
- GMSSRootCalc tree = this.generateNextAuthpathAndRoot(nextStack[h], seeds[h + 1], h + 1);
-
- // set initial values needed for the private key construction
- for (int i = 0; i < heightOfTrees[h + 1]; i++)
- {
- System.arraycopy(tree.getAuthPath()[i], 0, nextAuthPaths[h][i], 0, mdLength);
- }
- nextRetain[h] = tree.getRetain();
- nextTreehash[h] = tree.getTreehash();
- System.arraycopy(tree.getRoot(), 0, nextRoots[h], 0, mdLength);
-
- // create seed for the Merkle tree after next (nextNextSeeds)
- // SEEDs++
- System.arraycopy(seeds[h + 1], 0, this.nextNextSeeds[h], 0, mdLength);
- }
- // ------------
-
- // generate JDKGMSSPublicKey
- GMSSPublicKeyParameters publicKey = new GMSSPublicKeyParameters(currentRoots[0], gmssPS);
-
- // generate the JDKGMSSPrivateKey
- GMSSPrivateKeyParameters privateKey = new GMSSPrivateKeyParameters(currentSeeds, nextNextSeeds, currentAuthPaths,
- nextAuthPaths, currentTreehash, nextTreehash, currentStack, nextStack, currentRetain, nextRetain, nextRoots, currentRootSigs, gmssPS, digestProvider);
-
- // return the KeyPair
- return (new AsymmetricCipherKeyPair(publicKey, privateKey));
- }
-
- /**
- * calculates the authpath for tree in layer h which starts with seed[h]
- * additionally computes the rootSignature of underlaying root
- *
- * @param currentStack stack used for the treehash instance created by this method
- * @param lowerRoot stores the root of the lower tree
- * @param seed starting seeds
- * @param h actual layer
- */
- private GMSSRootCalc generateCurrentAuthpathAndRoot(byte[] lowerRoot, Vector currentStack, byte[] seed, int h)
- {
- byte[] help = new byte[mdLength];
-
- byte[] OTSseed = new byte[mdLength];
- OTSseed = gmssRandom.nextSeed(seed);
-
- WinternitzOTSignature ots;
-
- // data structure that constructs the whole tree and stores
- // the initial values for treehash, Auth and retain
- GMSSRootCalc treeToConstruct = new GMSSRootCalc(this.heightOfTrees[h], this.K[h], digestProvider);
-
- treeToConstruct.initialize(currentStack);
-
- // generate the first leaf
- if (h == numLayer - 1)
- {
- ots = new WinternitzOTSignature(OTSseed, digestProvider.get(), otsIndex[h]);
- help = ots.getPublicKey();
- }
- else
- {
- // for all layers except the lowest, generate the signature of the
- // underlying root
- // and reuse this signature to compute the first leaf of acual layer
- // more efficiently (by verifiing the signature)
- ots = new WinternitzOTSignature(OTSseed, digestProvider.get(), otsIndex[h]);
- currentRootSigs[h] = ots.getSignature(lowerRoot);
- WinternitzOTSVerify otsver = new WinternitzOTSVerify(digestProvider.get(), otsIndex[h]);
- help = otsver.Verify(lowerRoot, currentRootSigs[h]);
- }
- // update the tree with the first leaf
- treeToConstruct.update(help);
-
- int seedForTreehashIndex = 3;
- int count = 0;
-
- // update the tree 2^(H) - 1 times, from the second to the last leaf
- for (int i = 1; i < (1 << this.heightOfTrees[h]); i++)
- {
- // initialize the seeds for the leaf generation with index 3 * 2^h
- if (i == seedForTreehashIndex && count < this.heightOfTrees[h] - this.K[h])
- {
- treeToConstruct.initializeTreehashSeed(seed, count);
- seedForTreehashIndex *= 2;
- count++;
- }
-
- OTSseed = gmssRandom.nextSeed(seed);
- ots = new WinternitzOTSignature(OTSseed, digestProvider.get(), otsIndex[h]);
- treeToConstruct.update(ots.getPublicKey());
- }
-
- if (treeToConstruct.wasFinished())
- {
- return treeToConstruct;
- }
- System.err.println("Baum noch nicht fertig konstruiert!!!");
- return null;
- }
-
- /**
- * calculates the authpath and root for tree in layer h which starts with
- * seed[h]
- *
- * @param nextStack stack used for the treehash instance created by this method
- * @param seed starting seeds
- * @param h actual layer
- */
- private GMSSRootCalc generateNextAuthpathAndRoot(Vector nextStack, byte[] seed, int h)
- {
- byte[] OTSseed = new byte[numLayer];
- WinternitzOTSignature ots;
-
- // data structure that constructs the whole tree and stores
- // the initial values for treehash, Auth and retain
- GMSSRootCalc treeToConstruct = new GMSSRootCalc(this.heightOfTrees[h], this.K[h], this.digestProvider);
- treeToConstruct.initialize(nextStack);
-
- int seedForTreehashIndex = 3;
- int count = 0;
-
- // update the tree 2^(H) times, from the first to the last leaf
- for (int i = 0; i < (1 << this.heightOfTrees[h]); i++)
- {
- // initialize the seeds for the leaf generation with index 3 * 2^h
- if (i == seedForTreehashIndex && count < this.heightOfTrees[h] - this.K[h])
- {
- treeToConstruct.initializeTreehashSeed(seed, count);
- seedForTreehashIndex *= 2;
- count++;
- }
-
- OTSseed = gmssRandom.nextSeed(seed);
- ots = new WinternitzOTSignature(OTSseed, digestProvider.get(), otsIndex[h]);
- treeToConstruct.update(ots.getPublicKey());
- }
-
- if (treeToConstruct.wasFinished())
- {
- return treeToConstruct;
- }
- System.err.println("N�chster Baum noch nicht fertig konstruiert!!!");
- return null;
- }
-
- /**
- * This method initializes the GMSS KeyPairGenerator using an integer value
- * <code>keySize</code> as input. It provides a simple use of the GMSS for
- * testing demands.
- * <p>
- * A given <code>keysize</code> of less than 10 creates an amount 2^10
- * signatures. A keySize between 10 and 20 creates 2^20 signatures. Given an
- * integer greater than 20 the key pair generator creates 2^40 signatures.
- *
- * @param keySize Assigns the parameters used for the GMSS signatures. There are
- * 3 choices:<br>
- * 1. keysize &lt;= 10: creates 2^10 signatures using the
- * parameterset<br>
- * P = (2, (5, 5), (3, 3), (3, 3))<br>
- * 2. keysize &gt; 10 and &lt;= 20: creates 2^20 signatures using the
- * parameterset<br>
- * P = (2, (10, 10), (5, 4), (2, 2))<br>
- * 3. keysize &gt; 20: creates 2^40 signatures using the
- * parameterset<br>
- * P = (2, (10, 10, 10, 10), (9, 9, 9, 3), (2, 2, 2, 2))
- * @param secureRandom not used by GMSS, the SHA1PRNG of the SUN Provider is always
- * used
- */
- public void initialize(int keySize, SecureRandom secureRandom)
- {
-
- KeyGenerationParameters kgp;
- if (keySize <= 10)
- { // create 2^10 keys
- int[] defh = {10};
- int[] defw = {3};
- int[] defk = {2};
- // XXX sec random neede?
- kgp = new GMSSKeyGenerationParameters(secureRandom, new GMSSParameters(defh.length, defh, defw, defk));
- }
- else if (keySize <= 20)
- { // create 2^20 keys
- int[] defh = {10, 10};
- int[] defw = {5, 4};
- int[] defk = {2, 2};
- kgp = new GMSSKeyGenerationParameters(secureRandom, new GMSSParameters(defh.length, defh, defw, defk));
- }
- else
- { // create 2^40 keys, keygen lasts around 80 seconds
- int[] defh = {10, 10, 10, 10};
- int[] defw = {9, 9, 9, 3};
- int[] defk = {2, 2, 2, 2};
- kgp = new GMSSKeyGenerationParameters(secureRandom, new GMSSParameters(defh.length, defh, defw, defk));
- }
-
- // call the initializer with the chosen parameters
- this.initialize(kgp);
-
- }
-
-
- /**
- * Initalizes the key pair generator using a parameter set as input
- */
- public void initialize(KeyGenerationParameters param)
- {
-
- this.gmssParams = (GMSSKeyGenerationParameters)param;
-
- // generate GMSSParameterset
- this.gmssPS = new GMSSParameters(gmssParams.getParameters().getNumOfLayers(), gmssParams.getParameters().getHeightOfTrees(),
- gmssParams.getParameters().getWinternitzParameter(), gmssParams.getParameters().getK());
-
- this.numLayer = gmssPS.getNumOfLayers();
- this.heightOfTrees = gmssPS.getHeightOfTrees();
- this.otsIndex = gmssPS.getWinternitzParameter();
- this.K = gmssPS.getK();
-
- // seeds
- this.currentSeeds = new byte[numLayer][mdLength];
- this.nextNextSeeds = new byte[numLayer - 1][mdLength];
-
- // construct SecureRandom for initial seed generation
- SecureRandom secRan = new SecureRandom();
-
- // generation of initial seeds
- for (int i = 0; i < numLayer; i++)
- {
- secRan.nextBytes(currentSeeds[i]);
- gmssRandom.nextSeed(currentSeeds[i]);
- }
-
- this.initialized = true;
- }
-
- /**
- * This method is called by generateKeyPair() in case that no other
- * initialization method has been called by the user
- */
- private void initializeDefault()
- {
- int[] defh = {10, 10, 10, 10};
- int[] defw = {3, 3, 3, 3};
- int[] defk = {2, 2, 2, 2};
-
- KeyGenerationParameters kgp = new GMSSKeyGenerationParameters(new SecureRandom(), new GMSSParameters(defh.length, defh, defw, defk));
- this.initialize(kgp);
-
- }
-
- public void init(KeyGenerationParameters param)
- {
- this.initialize(param);
-
- }
-
- public AsymmetricCipherKeyPair generateKeyPair()
- {
- return genKeyPair();
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyParameters.java
deleted file mode 100644
index 53f6e43..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSKeyParameters.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-
-public class GMSSKeyParameters
- extends AsymmetricKeyParameter
-{
- private GMSSParameters params;
-
- public GMSSKeyParameters(
- boolean isPrivate,
- GMSSParameters params)
- {
- super(isPrivate);
- this.params = params;
- }
-
- public GMSSParameters getParameters()
- {
- return params;
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSLeaf.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSLeaf.java
deleted file mode 100644
index 6823ce3..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSLeaf.java
+++ /dev/null
@@ -1,376 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom;
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.encoders.Hex;
-
-
-/**
- * This class implements the distributed computation of the public key of the
- * Winternitz one-time signature scheme (OTSS). The class is used by the GMSS
- * classes for calculation of upcoming leafs.
- */
-public class GMSSLeaf
-{
-
- /**
- * The hash function used by the OTS and the PRNG
- */
- private Digest messDigestOTS;
-
- /**
- * The length of the message digest and private key
- */
- private int mdsize, keysize;
-
- /**
- * The source of randomness for OTS private key generation
- */
- private GMSSRandom gmssRandom;
-
- /**
- * Byte array for distributed computation of the upcoming leaf
- */
- private byte[] leaf;
-
- /**
- * Byte array for storing the concatenated hashes of private key parts
- */
- private byte[] concHashs;
-
- /**
- * indices for distributed computation
- */
- private int i, j;
-
- /**
- * storing 2^w
- */
- private int two_power_w;
-
- /**
- * Winternitz parameter w
- */
- private int w;
-
- /**
- * the amount of distributed computation steps when updateLeaf is called
- */
- private int steps;
-
- /**
- * the internal seed
- */
- private byte[] seed;
-
- /**
- * the OTS privateKey parts
- */
- byte[] privateKeyOTS;
-
- /**
- * This constructor regenerates a prior GMSSLeaf object
- *
- * @param digest an array of strings, containing the name of the used hash
- * function and PRNG and the name of the corresponding
- * provider
- * @param otsIndex status bytes
- * @param numLeafs status ints
- */
- public GMSSLeaf(Digest digest, byte[][] otsIndex, int[] numLeafs)
- {
- this.i = numLeafs[0];
- this.j = numLeafs[1];
- this.steps = numLeafs[2];
- this.w = numLeafs[3];
-
- messDigestOTS = digest;
-
- gmssRandom = new GMSSRandom(messDigestOTS);
-
- // calulate keysize for private key and the help array
- mdsize = messDigestOTS.getDigestSize();
- int mdsizeBit = mdsize << 3;
- int messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w);
- int checksumsize = getLog((messagesize << w) + 1);
- this.keysize = messagesize
- + (int)Math.ceil((double)checksumsize / (double)w);
- this.two_power_w = 1 << w;
-
- // calculate steps
- // ((2^w)-1)*keysize + keysize + 1 / (2^h -1)
-
- // initialize arrays
- this.privateKeyOTS = otsIndex[0];
- this.seed = otsIndex[1];
- this.concHashs = otsIndex[2];
- this.leaf = otsIndex[3];
- }
-
- /**
- * The constructor precomputes some needed variables for distributed leaf
- * calculation
- *
- * @param digest an array of strings, containing the digest of the used hash
- * function and PRNG and the digest of the corresponding
- * provider
- * @param w the winterniz parameter of that tree the leaf is computed
- * for
- * @param numLeafs the number of leafs of the tree from where the distributed
- * computation is called
- */
- GMSSLeaf(Digest digest, int w, int numLeafs)
- {
- this.w = w;
-
- messDigestOTS = digest;
-
- gmssRandom = new GMSSRandom(messDigestOTS);
-
- // calulate keysize for private key and the help array
- mdsize = messDigestOTS.getDigestSize();
- int mdsizeBit = mdsize << 3;
- int messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w);
- int checksumsize = getLog((messagesize << w) + 1);
- this.keysize = messagesize
- + (int)Math.ceil((double)checksumsize / (double)w);
- this.two_power_w = 1 << w;
-
- // calculate steps
- // ((2^w)-1)*keysize + keysize + 1 / (2^h -1)
- this.steps = (int)Math
- .ceil((double)(((1 << w) - 1) * keysize + 1 + keysize)
- / (double)(numLeafs));
-
- // initialize arrays
- this.seed = new byte[mdsize];
- this.leaf = new byte[mdsize];
- this.privateKeyOTS = new byte[mdsize];
- this.concHashs = new byte[mdsize * keysize];
- }
-
- public GMSSLeaf(Digest digest, int w, int numLeafs, byte[] seed0)
- {
- this.w = w;
-
- messDigestOTS = digest;
-
- gmssRandom = new GMSSRandom(messDigestOTS);
-
- // calulate keysize for private key and the help array
- mdsize = messDigestOTS.getDigestSize();
- int mdsizeBit = mdsize << 3;
- int messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w);
- int checksumsize = getLog((messagesize << w) + 1);
- this.keysize = messagesize
- + (int)Math.ceil((double)checksumsize / (double)w);
- this.two_power_w = 1 << w;
-
- // calculate steps
- // ((2^w)-1)*keysize + keysize + 1 / (2^h -1)
- this.steps = (int)Math
- .ceil((double)(((1 << w) - 1) * keysize + 1 + keysize)
- / (double)(numLeafs));
-
- // initialize arrays
- this.seed = new byte[mdsize];
- this.leaf = new byte[mdsize];
- this.privateKeyOTS = new byte[mdsize];
- this.concHashs = new byte[mdsize * keysize];
-
- initLeafCalc(seed0);
- }
-
- private GMSSLeaf(GMSSLeaf original)
- {
- this.messDigestOTS = original.messDigestOTS;
- this.mdsize = original.mdsize;
- this.keysize = original.keysize;
- this.gmssRandom = original.gmssRandom;
- this.leaf = Arrays.clone(original.leaf);
- this.concHashs = Arrays.clone(original.concHashs);
- this.i = original.i;
- this.j = original.j;
- this.two_power_w = original.two_power_w;
- this.w = original.w;
- this.steps = original.steps;
- this.seed = Arrays.clone(original.seed);
- this.privateKeyOTS = Arrays.clone(original.privateKeyOTS);
- }
-
- /**
- * initialize the distributed leaf calculation reset i,j and compute OTSseed
- * with seed0
- *
- * @param seed0 the starting seed
- */
- // TODO: this really looks like it should be either always called from a constructor or nextLeaf.
- void initLeafCalc(byte[] seed0)
- {
- this.i = 0;
- this.j = 0;
- byte[] dummy = new byte[mdsize];
- System.arraycopy(seed0, 0, dummy, 0, seed.length);
- this.seed = gmssRandom.nextSeed(dummy);
- }
-
- GMSSLeaf nextLeaf()
- {
- GMSSLeaf nextLeaf = new GMSSLeaf(this);
-
- nextLeaf.updateLeafCalc();
-
- return nextLeaf;
- }
-
- /**
- * Processes <code>steps</code> steps of distributed leaf calculation
- *
- * @return true if leaf is completed, else false
- */
- private void updateLeafCalc()
- {
- byte[] buf = new byte[messDigestOTS.getDigestSize()];
-
- // steps times do
- // TODO: this really needs to be looked at, the 10000 has been added as
- // prior to this the leaf value always ended up as zeros.
- for (int s = 0; s < steps + 10000; s++)
- {
- if (i == keysize && j == two_power_w - 1)
- { // [3] at last hash the
- // concatenation
- messDigestOTS.update(concHashs, 0, concHashs.length);
- leaf = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(leaf, 0);
- return;
- }
- else if (i == 0 || j == two_power_w - 1)
- { // [1] at the
- // beginning and
- // when [2] is
- // finished: get the
- // next private key
- // part
- i++;
- j = 0;
- // get next privKey part
- this.privateKeyOTS = gmssRandom.nextSeed(seed);
- }
- else
- { // [2] hash the privKey part
- messDigestOTS.update(privateKeyOTS, 0, privateKeyOTS.length);
- privateKeyOTS = buf;
- messDigestOTS.doFinal(privateKeyOTS, 0);
- j++;
- if (j == two_power_w - 1)
- { // after w hashes add to the
- // concatenated array
- System.arraycopy(privateKeyOTS, 0, concHashs, mdsize
- * (i - 1), mdsize);
- }
- }
- }
-
- throw new IllegalStateException("unable to updateLeaf in steps: " + steps + " " + i + " " + j);
- }
-
- /**
- * Returns the leaf value.
- *
- * @return the leaf value
- */
- public byte[] getLeaf()
- {
- return Arrays.clone(leaf);
- }
-
- /**
- * This method returns the least integer that is greater or equal to the
- * logarithm to the base 2 of an integer <code>intValue</code>.
- *
- * @param intValue an integer
- * @return The least integer greater or equal to the logarithm to the base 2
- * of <code>intValue</code>
- */
- private int getLog(int intValue)
- {
- int log = 1;
- int i = 2;
- while (i < intValue)
- {
- i <<= 1;
- log++;
- }
- return log;
- }
-
- /**
- * Returns the status byte array used by the GMSSPrivateKeyASN.1 class
- *
- * @return The status bytes
- */
- public byte[][] getStatByte()
- {
-
- byte[][] statByte = new byte[4][];
- statByte[0] = new byte[mdsize];
- statByte[1] = new byte[mdsize];
- statByte[2] = new byte[mdsize * keysize];
- statByte[3] = new byte[mdsize];
- statByte[0] = privateKeyOTS;
- statByte[1] = seed;
- statByte[2] = concHashs;
- statByte[3] = leaf;
-
- return statByte;
- }
-
- /**
- * Returns the status int array used by the GMSSPrivateKeyASN.1 class
- *
- * @return The status ints
- */
- public int[] getStatInt()
- {
-
- int[] statInt = new int[4];
- statInt[0] = i;
- statInt[1] = j;
- statInt[2] = steps;
- statInt[3] = w;
- return statInt;
- }
-
- /**
- * Returns a String representation of the main part of this element
- *
- * @return a String representation of the main part of this element
- */
- public String toString()
- {
- String out = "";
-
- for (int i = 0; i < 4; i++)
- {
- out = out + this.getStatInt()[i] + " ";
- }
- out = out + " " + this.mdsize + " " + this.keysize + " "
- + this.two_power_w + " ";
-
- byte[][] temp = this.getStatByte();
- for (int i = 0; i < 4; i++)
- {
- if (temp[i] != null)
- {
- out = out + new String(Hex.encode(temp[i])) + " ";
- }
- else
- {
- out = out + "null ";
- }
- }
- return out;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSParameters.java
deleted file mode 100644
index aa89f76..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSParameters.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import org.bouncycastle.util.Arrays;
-
-/**
- * This class provides a specification for the GMSS parameters that are used by
- * the GMSSKeyPairGenerator and GMSSSignature classes.
- *
- * @see org.bouncycastle.pqc.crypto.gmss.GMSSKeyPairGenerator
- */
-public class GMSSParameters
-{
- /**
- * The number of authentication tree layers.
- */
- private int numOfLayers;
-
- /**
- * The height of the authentication trees of each layer.
- */
- private int[] heightOfTrees;
-
- /**
- * The Winternitz Parameter 'w' of each layer.
- */
- private int[] winternitzParameter;
-
- /**
- * The parameter K needed for the authentication path computation
- */
- private int[] K;
-
- /**
- * The constructor for the parameters of the GMSSKeyPairGenerator.
- *
- * @param layers the number of authentication tree layers
- * @param heightOfTrees the height of the authentication trees
- * @param winternitzParameter the Winternitz Parameter 'w' of each layer
- * @param K parameter for authpath computation
- */
- public GMSSParameters(int layers, int[] heightOfTrees, int[] winternitzParameter, int[] K)
- throws IllegalArgumentException
- {
- init(layers, heightOfTrees, winternitzParameter, K);
- }
-
- private void init(int layers, int[] heightOfTrees,
- int[] winternitzParameter, int[] K)
- throws IllegalArgumentException
- {
- boolean valid = true;
- String errMsg = "";
- this.numOfLayers = layers;
- if ((numOfLayers != winternitzParameter.length)
- || (numOfLayers != heightOfTrees.length)
- || (numOfLayers != K.length))
- {
- valid = false;
- errMsg = "Unexpected parameterset format";
- }
- for (int i = 0; i < numOfLayers; i++)
- {
- if ((K[i] < 2) || ((heightOfTrees[i] - K[i]) % 2 != 0))
- {
- valid = false;
- errMsg = "Wrong parameter K (K >= 2 and H-K even required)!";
- }
-
- if ((heightOfTrees[i] < 4) || (winternitzParameter[i] < 2))
- {
- valid = false;
- errMsg = "Wrong parameter H or w (H > 3 and w > 1 required)!";
- }
- }
-
- if (valid)
- {
- this.heightOfTrees = Arrays.clone(heightOfTrees);
- this.winternitzParameter = Arrays.clone(winternitzParameter);
- this.K = Arrays.clone(K);
- }
- else
- {
- throw new IllegalArgumentException(errMsg);
- }
- }
-
- public GMSSParameters(int keySize)
- throws IllegalArgumentException
- {
- if (keySize <= 10)
- { // create 2^10 keys
- int[] defh = {10};
- int[] defw = {3};
- int[] defk = {2};
- this.init(defh.length, defh, defw, defk);
- }
- else if (keySize <= 20)
- { // create 2^20 keys
- int[] defh = {10, 10};
- int[] defw = {5, 4};
- int[] defk = {2, 2};
- this.init(defh.length, defh, defw, defk);
- }
- else
- { // create 2^40 keys, keygen lasts around 80 seconds
- int[] defh = {10, 10, 10, 10};
- int[] defw = {9, 9, 9, 3};
- int[] defk = {2, 2, 2, 2};
- this.init(defh.length, defh, defw, defk);
- }
- }
-
- /**
- * Returns the number of levels of the authentication trees.
- *
- * @return The number of levels of the authentication trees.
- */
- public int getNumOfLayers()
- {
- return numOfLayers;
- }
-
- /**
- * Returns the array of height (for each layer) of the authentication trees
- *
- * @return The array of height (for each layer) of the authentication trees
- */
- public int[] getHeightOfTrees()
- {
- return Arrays.clone(heightOfTrees);
- }
-
- /**
- * Returns the array of WinternitzParameter (for each layer) of the
- * authentication trees
- *
- * @return The array of WinternitzParameter (for each layer) of the
- * authentication trees
- */
- public int[] getWinternitzParameter()
- {
- return Arrays.clone(winternitzParameter);
- }
-
- /**
- * Returns the parameter K needed for authentication path computation
- *
- * @return The parameter K needed for authentication path computation
- */
- public int[] getK()
- {
- return Arrays.clone(K);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSPrivateKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSPrivateKeyParameters.java
deleted file mode 100644
index 83cf797..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSPrivateKeyParameters.java
+++ /dev/null
@@ -1,1041 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import java.util.Vector;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom;
-import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSignature;
-import org.bouncycastle.util.Arrays;
-
-
-/**
- * This class provides a specification for a GMSS private key.
- */
-public class GMSSPrivateKeyParameters
- extends GMSSKeyParameters
-{
- private int[] index;
-
- private byte[][] currentSeeds;
- private byte[][] nextNextSeeds;
-
- private byte[][][] currentAuthPaths;
- private byte[][][] nextAuthPaths;
-
- private Treehash[][] currentTreehash;
- private Treehash[][] nextTreehash;
-
- private Vector[] currentStack;
- private Vector[] nextStack;
-
- private Vector[][] currentRetain;
- private Vector[][] nextRetain;
-
- private byte[][][] keep;
-
- private GMSSLeaf[] nextNextLeaf;
- private GMSSLeaf[] upperLeaf;
- private GMSSLeaf[] upperTreehashLeaf;
-
- private int[] minTreehash;
-
- private GMSSParameters gmssPS;
-
- private byte[][] nextRoot;
- private GMSSRootCalc[] nextNextRoot;
-
- private byte[][] currentRootSig;
- private GMSSRootSig[] nextRootSig;
-
- private GMSSDigestProvider digestProvider;
-
- private boolean used = false;
-
- /**
- * An array of the heights of the authentication trees of each layer
- */
- private int[] heightOfTrees;
-
- /**
- * An array of the Winternitz parameter 'w' of each layer
- */
- private int[] otsIndex;
-
- /**
- * The parameter K needed for the authentication path computation
- */
- private int[] K;
-
- /**
- * the number of Layers
- */
- private int numLayer;
-
- /**
- * The hash function used to construct the authentication trees
- */
- private Digest messDigestTrees;
-
- /**
- * The message digest length
- */
- private int mdLength;
-
- /**
- * The PRNG used for private key generation
- */
- private GMSSRandom gmssRandom;
-
-
- /**
- * The number of leafs of one tree of each layer
- */
- private int[] numLeafs;
-
-
- /**
- * Generates a new GMSS private key
- *
- * @param currentSeed seed for the generation of private OTS keys for the
- * current subtrees
- * @param nextNextSeed seed for the generation of private OTS keys for the next
- * subtrees
- * @param currentAuthPath array of current authentication paths
- * @param nextAuthPath array of next authentication paths
- * @param currentTreehash array of current treehash instances
- * @param nextTreehash array of next treehash instances
- * @param currentStack array of current shared stacks
- * @param nextStack array of next shared stacks
- * @param currentRetain array of current retain stacks
- * @param nextRetain array of next retain stacks
- * @param nextRoot the roots of the next subtree
- * @param currentRootSig array of signatures of the roots of the current subtrees
- * @param gmssParameterset the GMSS Parameterset
- * @see org.bouncycastle.pqc.crypto.gmss.GMSSKeyPairGenerator
- */
-
- public GMSSPrivateKeyParameters(byte[][] currentSeed, byte[][] nextNextSeed,
- byte[][][] currentAuthPath, byte[][][] nextAuthPath,
- Treehash[][] currentTreehash, Treehash[][] nextTreehash,
- Vector[] currentStack, Vector[] nextStack,
- Vector[][] currentRetain, Vector[][] nextRetain, byte[][] nextRoot,
- byte[][] currentRootSig, GMSSParameters gmssParameterset,
- GMSSDigestProvider digestProvider)
- {
- this(null, currentSeed, nextNextSeed, currentAuthPath, nextAuthPath,
- null, currentTreehash, nextTreehash, currentStack, nextStack,
- currentRetain, nextRetain, null, null, null, null, nextRoot,
- null, currentRootSig, null, gmssParameterset, digestProvider);
- }
-
- /**
- * /**
- *
- * @param index tree indices
- * @param keep keep array for the authPath algorithm
- * @param currentTreehash treehash for authPath algorithm of current tree
- * @param nextTreehash treehash for authPath algorithm of next tree (TREE+)
- * @param currentStack shared stack for authPath algorithm of current tree
- * @param nextStack shared stack for authPath algorithm of next tree (TREE+)
- * @param currentRetain retain stack for authPath algorithm of current tree
- * @param nextRetain retain stack for authPath algorithm of next tree (TREE+)
- * @param nextNextLeaf array of upcoming leafs of the tree after next (LEAF++) of
- * each layer
- * @param upperLeaf needed for precomputation of upper nodes
- * @param upperTreehashLeaf needed for precomputation of upper treehash nodes
- * @param minTreehash index of next treehash instance to receive an update
- * @param nextRoot the roots of the next trees (ROOT+)
- * @param nextNextRoot the roots of the tree after next (ROOT++)
- * @param currentRootSig array of signatures of the roots of the current subtrees
- * (SIG)
- * @param nextRootSig array of signatures of the roots of the next subtree
- * (SIG+)
- * @param gmssParameterset the GMSS Parameterset
- */
- public GMSSPrivateKeyParameters(int[] index, byte[][] currentSeeds,
- byte[][] nextNextSeeds, byte[][][] currentAuthPaths,
- byte[][][] nextAuthPaths, byte[][][] keep,
- Treehash[][] currentTreehash, Treehash[][] nextTreehash,
- Vector[] currentStack, Vector[] nextStack,
- Vector[][] currentRetain, Vector[][] nextRetain,
- GMSSLeaf[] nextNextLeaf, GMSSLeaf[] upperLeaf,
- GMSSLeaf[] upperTreehashLeaf, int[] minTreehash, byte[][] nextRoot,
- GMSSRootCalc[] nextNextRoot, byte[][] currentRootSig,
- GMSSRootSig[] nextRootSig, GMSSParameters gmssParameterset,
- GMSSDigestProvider digestProvider)
- {
-
- super(true, gmssParameterset);
-
- // construct message digest
-
- this.messDigestTrees = digestProvider.get();
- this.mdLength = messDigestTrees.getDigestSize();
-
-
- // Parameter
- this.gmssPS = gmssParameterset;
- this.otsIndex = gmssParameterset.getWinternitzParameter();
- this.K = gmssParameterset.getK();
- this.heightOfTrees = gmssParameterset.getHeightOfTrees();
- // initialize numLayer
- this.numLayer = gmssPS.getNumOfLayers();
-
- // initialize index if null
- if (index == null)
- {
- this.index = new int[numLayer];
- for (int i = 0; i < numLayer; i++)
- {
- this.index[i] = 0;
- }
- }
- else
- {
- this.index = index;
- }
-
- this.currentSeeds = currentSeeds;
- this.nextNextSeeds = nextNextSeeds;
-
- this.currentAuthPaths = currentAuthPaths;
- this.nextAuthPaths = nextAuthPaths;
-
- // initialize keep if null
- if (keep == null)
- {
- this.keep = new byte[numLayer][][];
- for (int i = 0; i < numLayer; i++)
- {
- this.keep[i] = new byte[(int)Math.floor(heightOfTrees[i] / 2)][mdLength];
- }
- }
- else
- {
- this.keep = keep;
- }
-
- // initialize stack if null
- if (currentStack == null)
- {
- this.currentStack = new Vector[numLayer];
- for (int i = 0; i < numLayer; i++)
- {
- this.currentStack[i] = new Vector();
- }
- }
- else
- {
- this.currentStack = currentStack;
- }
-
- // initialize nextStack if null
- if (nextStack == null)
- {
- this.nextStack = new Vector[numLayer - 1];
- for (int i = 0; i < numLayer - 1; i++)
- {
- this.nextStack[i] = new Vector();
- }
- }
- else
- {
- this.nextStack = nextStack;
- }
-
- this.currentTreehash = currentTreehash;
- this.nextTreehash = nextTreehash;
-
- this.currentRetain = currentRetain;
- this.nextRetain = nextRetain;
-
- this.nextRoot = nextRoot;
-
- this.digestProvider = digestProvider;
-
- if (nextNextRoot == null)
- {
- this.nextNextRoot = new GMSSRootCalc[numLayer - 1];
- for (int i = 0; i < numLayer - 1; i++)
- {
- this.nextNextRoot[i] = new GMSSRootCalc(
- this.heightOfTrees[i + 1], this.K[i + 1], this.digestProvider);
- }
- }
- else
- {
- this.nextNextRoot = nextNextRoot;
- }
- this.currentRootSig = currentRootSig;
-
- // calculate numLeafs
- numLeafs = new int[numLayer];
- for (int i = 0; i < numLayer; i++)
- {
- numLeafs[i] = 1 << heightOfTrees[i];
- }
- // construct PRNG
- this.gmssRandom = new GMSSRandom(messDigestTrees);
-
- if (numLayer > 1)
- {
- // construct the nextNextLeaf (LEAFs++) array for upcoming leafs in
- // tree after next (TREE++)
- if (nextNextLeaf == null)
- {
- this.nextNextLeaf = new GMSSLeaf[numLayer - 2];
- for (int i = 0; i < numLayer - 2; i++)
- {
- this.nextNextLeaf[i] = new GMSSLeaf(digestProvider.get(), otsIndex[i + 1], numLeafs[i + 2], this.nextNextSeeds[i]);
- }
- }
- else
- {
- this.nextNextLeaf = nextNextLeaf;
- }
- }
- else
- {
- this.nextNextLeaf = new GMSSLeaf[0];
- }
-
- // construct the upperLeaf array for upcoming leafs in tree over the
- // actual
- if (upperLeaf == null)
- {
- this.upperLeaf = new GMSSLeaf[numLayer - 1];
- for (int i = 0; i < numLayer - 1; i++)
- {
- this.upperLeaf[i] = new GMSSLeaf(digestProvider.get(), otsIndex[i],
- numLeafs[i + 1], this.currentSeeds[i]);
- }
- }
- else
- {
- this.upperLeaf = upperLeaf;
- }
-
- // construct the leafs for upcoming leafs in treehashs in tree over the
- // actual
- if (upperTreehashLeaf == null)
- {
- this.upperTreehashLeaf = new GMSSLeaf[numLayer - 1];
- for (int i = 0; i < numLayer - 1; i++)
- {
- this.upperTreehashLeaf[i] = new GMSSLeaf(digestProvider.get(), otsIndex[i], numLeafs[i + 1]);
- }
- }
- else
- {
- this.upperTreehashLeaf = upperTreehashLeaf;
- }
-
- if (minTreehash == null)
- {
- this.minTreehash = new int[numLayer - 1];
- for (int i = 0; i < numLayer - 1; i++)
- {
- this.minTreehash[i] = -1;
- }
- }
- else
- {
- this.minTreehash = minTreehash;
- }
-
- // construct the nextRootSig (RootSig++)
- byte[] dummy = new byte[mdLength];
- byte[] OTSseed = new byte[mdLength];
- if (nextRootSig == null)
- {
- this.nextRootSig = new GMSSRootSig[numLayer - 1];
- for (int i = 0; i < numLayer - 1; i++)
- {
- System.arraycopy(currentSeeds[i], 0, dummy, 0, mdLength);
- gmssRandom.nextSeed(dummy);
- OTSseed = gmssRandom.nextSeed(dummy);
- this.nextRootSig[i] = new GMSSRootSig(digestProvider.get(), otsIndex[i],
- heightOfTrees[i + 1]);
- this.nextRootSig[i].initSign(OTSseed, nextRoot[i]);
- }
- }
- else
- {
- this.nextRootSig = nextRootSig;
- }
- }
-
- // we assume this only gets called from nextKey so used is never copied.
- private GMSSPrivateKeyParameters(GMSSPrivateKeyParameters original)
- {
- super(true, original.getParameters());
-
- this.index = Arrays.clone(original.index);
- this.currentSeeds = Arrays.clone(original.currentSeeds);
- this.nextNextSeeds = Arrays.clone(original.nextNextSeeds);
- this.currentAuthPaths = Arrays.clone(original.currentAuthPaths);
- this.nextAuthPaths = Arrays.clone(original.nextAuthPaths);
- this.currentTreehash = original.currentTreehash;
- this.nextTreehash = original.nextTreehash;
- this.currentStack = original.currentStack;
- this.nextStack = original.nextStack;
- this.currentRetain = original.currentRetain;
- this.nextRetain = original.nextRetain;
- this.keep = Arrays.clone(original.keep);
- this.nextNextLeaf = original.nextNextLeaf;
- this.upperLeaf = original.upperLeaf;
- this.upperTreehashLeaf = original.upperTreehashLeaf;
- this.minTreehash = original.minTreehash;
- this.gmssPS = original.gmssPS;
- this.nextRoot = Arrays.clone(original.nextRoot);
- this.nextNextRoot = original.nextNextRoot;
- this.currentRootSig = original.currentRootSig;
- this.nextRootSig = original.nextRootSig;
- this.digestProvider = original.digestProvider;
- this.heightOfTrees = original.heightOfTrees;
- this.otsIndex = original.otsIndex;
- this.K = original.K;
- this.numLayer = original.numLayer;
- this.messDigestTrees = original.messDigestTrees;
- this.mdLength = original.mdLength;
- this.gmssRandom = original.gmssRandom;
- this.numLeafs = original.numLeafs;
- }
-
- public boolean isUsed()
- {
- return this.used;
- }
-
- public void markUsed()
- {
- this.used = true;
- }
-
- public GMSSPrivateKeyParameters nextKey()
- {
- GMSSPrivateKeyParameters nKey = new GMSSPrivateKeyParameters(this);
-
- nKey.nextKey(gmssPS.getNumOfLayers() - 1);
-
- return nKey;
- }
-
- /**
- * This method updates the GMSS private key for the next signature
- *
- * @param layer the layer where the next key is processed
- */
- private void nextKey(int layer)
- {
- // only for lowest layer ( other layers indices are raised in nextTree()
- // method )
- if (layer == numLayer - 1)
- {
- index[layer]++;
- } // else System.out.println(" --- nextKey on layer " + layer + "
- // index is now : " + index[layer]);
-
- // if tree of this layer is depleted
- if (index[layer] == numLeafs[layer])
- {
- if (numLayer != 1)
- {
- nextTree(layer);
- index[layer] = 0;
- }
- }
- else
- {
- updateKey(layer);
- }
- }
-
- /**
- * Switch to next subtree if the current one is depleted
- *
- * @param layer the layer where the next tree is processed
- */
- private void nextTree(int layer)
- {
- // System.out.println("NextTree method called on layer " + layer);
- // dont create next tree for the top layer
- if (layer > 0)
- {
- // raise index for upper layer
- index[layer - 1]++;
-
- // test if it is already the last tree
- boolean lastTree = true;
- int z = layer;
- do
- {
- z--;
- if (index[z] < numLeafs[z])
- {
- lastTree = false;
- }
- }
- while (lastTree && (z > 0));
-
- // only construct next subtree if last one is not already in use
- if (!lastTree)
- {
- gmssRandom.nextSeed(currentSeeds[layer]);
-
- // last step of distributed signature calculation
- nextRootSig[layer - 1].updateSign();
-
- // last step of distributed leaf calculation for nextNextLeaf
- if (layer > 1)
- {
- nextNextLeaf[layer - 1 - 1] = nextNextLeaf[layer - 1 - 1].nextLeaf();
- }
-
- // last step of distributed leaf calculation for upper leaf
- upperLeaf[layer - 1] = upperLeaf[layer - 1].nextLeaf();
-
- // last step of distributed leaf calculation for all treehashs
-
- if (minTreehash[layer - 1] >= 0)
- {
- upperTreehashLeaf[layer - 1] = upperTreehashLeaf[layer - 1].nextLeaf();
- byte[] leaf = this.upperTreehashLeaf[layer - 1].getLeaf();
- // if update is required use the precomputed leaf to update
- // treehash
- try
- {
- currentTreehash[layer - 1][minTreehash[layer - 1]]
- .update(this.gmssRandom, leaf);
- // System.out.println("UUUpdated TH " +
- // minTreehash[layer - 1]);
- if (currentTreehash[layer - 1][minTreehash[layer - 1]]
- .wasFinished())
- {
- // System.out.println("FFFinished TH " +
- // minTreehash[layer - 1]);
- }
- }
- catch (Exception e)
- {
- System.out.println(e);
- }
- }
-
- // last step of nextNextAuthRoot calculation
- this.updateNextNextAuthRoot(layer);
-
- // ******************************************************** /
-
- // NOW: advance to next tree on layer 'layer'
-
- // NextRootSig --> currentRootSigs
- this.currentRootSig[layer - 1] = nextRootSig[layer - 1]
- .getSig();
-
- // -----------------------
-
- // nextTreehash --> currentTreehash
- // nextNextTreehash --> nextTreehash
- for (int i = 0; i < heightOfTrees[layer] - K[layer]; i++)
- {
- this.currentTreehash[layer][i] = this.nextTreehash[layer - 1][i];
- this.nextTreehash[layer - 1][i] = this.nextNextRoot[layer - 1]
- .getTreehash()[i];
- }
-
- // NextAuthPath --> currentAuthPath
- // nextNextAuthPath --> nextAuthPath
- for (int i = 0; i < heightOfTrees[layer]; i++)
- {
- System.arraycopy(nextAuthPaths[layer - 1][i], 0,
- currentAuthPaths[layer][i], 0, mdLength);
- System.arraycopy(nextNextRoot[layer - 1].getAuthPath()[i],
- 0, nextAuthPaths[layer - 1][i], 0, mdLength);
- }
-
- // nextRetain --> currentRetain
- // nextNextRetain --> nextRetain
- for (int i = 0; i < K[layer] - 1; i++)
- {
- this.currentRetain[layer][i] = this.nextRetain[layer - 1][i];
- this.nextRetain[layer - 1][i] = this.nextNextRoot[layer - 1]
- .getRetain()[i];
- }
-
- // nextStack --> currentStack
- this.currentStack[layer] = this.nextStack[layer - 1];
- // nextNextStack --> nextStack
- this.nextStack[layer - 1] = this.nextNextRoot[layer - 1]
- .getStack();
-
- // nextNextRoot --> nextRoot
- this.nextRoot[layer - 1] = this.nextNextRoot[layer - 1]
- .getRoot();
- // -----------------------
-
- // -----------------
- byte[] OTSseed = new byte[mdLength];
- byte[] dummy = new byte[mdLength];
- // gmssRandom.setSeed(currentSeeds[layer]);
- System
- .arraycopy(currentSeeds[layer - 1], 0, dummy, 0,
- mdLength);
- OTSseed = gmssRandom.nextSeed(dummy); // only need OTSSeed
- OTSseed = gmssRandom.nextSeed(dummy);
- OTSseed = gmssRandom.nextSeed(dummy);
- // nextWinSig[layer-1]=new
- // GMSSWinSig(OTSseed,algNames,otsIndex[layer-1],heightOfTrees[layer],nextRoot[layer-1]);
- nextRootSig[layer - 1].initSign(OTSseed, nextRoot[layer - 1]);
-
- // nextKey for upper layer
- nextKey(layer - 1);
- }
- }
- }
-
- /**
- * This method computes the authpath (AUTH) for the current tree,
- * Additionally the root signature for the next tree (SIG+), the authpath
- * (AUTH++) and root (ROOT++) for the tree after next in layer
- * <code>layer</code>, and the LEAF++^1 for the next next tree in the
- * layer above are updated This method is used by nextKey()
- *
- * @param layer
- */
- private void updateKey(int layer)
- {
- // ----------current tree processing of actual layer---------
- // compute upcoming authpath for current Tree (AUTH)
- computeAuthPaths(layer);
-
- // -----------distributed calculations part------------
- // not for highest tree layer
- if (layer > 0)
- {
-
- // compute (partial) next leaf on TREE++ (not on layer 1 and 0)
- if (layer > 1)
- {
- nextNextLeaf[layer - 1 - 1] = nextNextLeaf[layer - 1 - 1].nextLeaf();
- }
-
- // compute (partial) next leaf on tree above (not on layer 0)
- upperLeaf[layer - 1] = upperLeaf[layer - 1].nextLeaf();
-
- // compute (partial) next leaf for all treehashs on tree above (not
- // on layer 0)
-
- int t = (int)Math
- .floor((double)(this.getNumLeafs(layer) * 2)
- / (double)(this.heightOfTrees[layer - 1] - this.K[layer - 1]));
-
- if (index[layer] % t == 1)
- {
- // System.out.println(" layer: " + layer + " index: " +
- // index[layer] + " t : " + t);
-
- // take precomputed node for treehash update
- // ------------------------------------------------
- if (index[layer] > 1 && minTreehash[layer - 1] >= 0)
- {
- byte[] leaf = this.upperTreehashLeaf[layer - 1].getLeaf();
- // if update is required use the precomputed leaf to update
- // treehash
- try
- {
- currentTreehash[layer - 1][minTreehash[layer - 1]]
- .update(this.gmssRandom, leaf);
- // System.out.println("Updated TH " + minTreehash[layer
- // - 1]);
- if (currentTreehash[layer - 1][minTreehash[layer - 1]]
- .wasFinished())
- {
- // System.out.println("Finished TH " +
- // minTreehash[layer - 1]);
- }
- }
- catch (Exception e)
- {
- System.out.println(e);
- }
- // ------------------------------------------------
- }
-
- // initialize next leaf precomputation
- // ------------------------------------------------
-
- // get lowest index of treehashs
- this.minTreehash[layer - 1] = getMinTreehashIndex(layer - 1);
-
- if (this.minTreehash[layer - 1] >= 0)
- {
- // initialize leaf
- byte[] seed = this.currentTreehash[layer - 1][this.minTreehash[layer - 1]]
- .getSeedActive();
- this.upperTreehashLeaf[layer - 1] = new GMSSLeaf(
- this.digestProvider.get(), this.otsIndex[layer - 1], t, seed);
- this.upperTreehashLeaf[layer - 1] = this.upperTreehashLeaf[layer - 1].nextLeaf();
- // System.out.println("restarted treehashleaf (" + (layer -
- // 1) + "," + this.minTreehash[layer - 1] + ")");
- }
- // ------------------------------------------------
-
- }
- else
- {
- // update the upper leaf for the treehash one step
- if (this.minTreehash[layer - 1] >= 0)
- {
- this.upperTreehashLeaf[layer - 1] = this.upperTreehashLeaf[layer - 1].nextLeaf();
- // if (minTreehash[layer - 1] > 3)
- // System.out.print("#");
- }
- }
-
- // compute (partial) the signature of ROOT+ (RootSig+) (not on top
- // layer)
- nextRootSig[layer - 1].updateSign();
-
- // compute (partial) AUTHPATH++ & ROOT++ (not on top layer)
- if (index[layer] == 1)
- {
- // init root and authpath calculation for tree after next
- // (AUTH++, ROOT++)
- this.nextNextRoot[layer - 1].initialize(new Vector());
- }
-
- // update root and authpath calculation for tree after next (AUTH++,
- // ROOT++)
- this.updateNextNextAuthRoot(layer);
- }
- // ----------- end distributed calculations part-----------------
- }
-
- /**
- * This method returns the index of the next Treehash instance that should
- * receive an update
- *
- * @param layer the layer of the GMSS tree
- * @return index of the treehash instance that should get the update
- */
- private int getMinTreehashIndex(int layer)
- {
- int minTreehash = -1;
- for (int h = 0; h < heightOfTrees[layer] - K[layer]; h++)
- {
- if (currentTreehash[layer][h].wasInitialized()
- && !currentTreehash[layer][h].wasFinished())
- {
- if (minTreehash == -1)
- {
- minTreehash = h;
- }
- else if (currentTreehash[layer][h].getLowestNodeHeight() < currentTreehash[layer][minTreehash]
- .getLowestNodeHeight())
- {
- minTreehash = h;
- }
- }
- }
- return minTreehash;
- }
-
- /**
- * Computes the upcoming currentAuthpath of layer <code>layer</code> using
- * the revisited authentication path computation of Dahmen/Schneider 2008
- *
- * @param layer the actual layer
- */
- private void computeAuthPaths(int layer)
- {
-
- int Phi = index[layer];
- int H = heightOfTrees[layer];
- int K = this.K[layer];
-
- // update all nextSeeds for seed scheduling
- for (int i = 0; i < H - K; i++)
- {
- currentTreehash[layer][i].updateNextSeed(gmssRandom);
- }
-
- // STEP 1 of Algorithm
- int Tau = heightOfPhi(Phi);
-
- byte[] OTSseed = new byte[mdLength];
- OTSseed = gmssRandom.nextSeed(currentSeeds[layer]);
-
- // STEP 2 of Algorithm
- // if phi's parent on height tau + 1 if left node, store auth_tau
- // in keep_tau.
- // TODO check it, formerly was
- // int L = Phi / (int) Math.floor(Math.pow(2, Tau + 1));
- // L %= 2;
- int L = (Phi >>> (Tau + 1)) & 1;
-
- byte[] tempKeep = new byte[mdLength];
- // store the keep node not in keep[layer][tau/2] because it might be in
- // use
- // wait until the space is freed in step 4a
- if (Tau < H - 1 && L == 0)
- {
- System.arraycopy(currentAuthPaths[layer][Tau], 0, tempKeep, 0,
- mdLength);
- }
-
- byte[] help = new byte[mdLength];
- // STEP 3 of Algorithm
- // if phi is left child, compute and store leaf for next currentAuthPath
- // path,
- // (obtained by veriying current signature)
- if (Tau == 0)
- {
- // LEAFCALC !!!
- if (layer == numLayer - 1)
- { // lowest layer computes the
- // necessary leaf completely at this
- // time
- WinternitzOTSignature ots = new WinternitzOTSignature(OTSseed,
- digestProvider.get(), otsIndex[layer]);
- help = ots.getPublicKey();
- }
- else
- { // other layers use the precomputed leafs in
- // nextNextLeaf
- byte[] dummy = new byte[mdLength];
- System.arraycopy(currentSeeds[layer], 0, dummy, 0, mdLength);
- gmssRandom.nextSeed(dummy);
- help = upperLeaf[layer].getLeaf();
- this.upperLeaf[layer].initLeafCalc(dummy);
-
- // WinternitzOTSVerify otsver = new
- // WinternitzOTSVerify(algNames, otsIndex[layer]);
- // byte[] help2 = otsver.Verify(currentRoot[layer],
- // currentRootSig[layer]);
- // System.out.println(" --- " + layer + " " +
- // ByteUtils.toHexString(help) + " " +
- // ByteUtils.toHexString(help2));
- }
- System.arraycopy(help, 0, currentAuthPaths[layer][0], 0, mdLength);
- }
- else
- {
- // STEP 4a of Algorithm
- // get new left currentAuthPath node on height tau
- byte[] toBeHashed = new byte[mdLength << 1];
- System.arraycopy(currentAuthPaths[layer][Tau - 1], 0, toBeHashed,
- 0, mdLength);
- // free the shared keep[layer][tau/2]
- System.arraycopy(keep[layer][(int)Math.floor((Tau - 1) / 2)], 0,
- toBeHashed, mdLength, mdLength);
- messDigestTrees.update(toBeHashed, 0, toBeHashed.length);
- currentAuthPaths[layer][Tau] = new byte[messDigestTrees.getDigestSize()];
- messDigestTrees.doFinal(currentAuthPaths[layer][Tau], 0);
-
- // STEP 4b and 4c of Algorithm
- // copy right nodes to currentAuthPath on height 0..Tau-1
- for (int i = 0; i < Tau; i++)
- {
-
- // STEP 4b of Algorithm
- // 1st: copy from treehashs
- if (i < H - K)
- {
- if (currentTreehash[layer][i].wasFinished())
- {
- System.arraycopy(currentTreehash[layer][i]
- .getFirstNode(), 0, currentAuthPaths[layer][i],
- 0, mdLength);
- currentTreehash[layer][i].destroy();
- }
- else
- {
- System.err
- .println("Treehash ("
- + layer
- + ","
- + i
- + ") not finished when needed in AuthPathComputation");
- }
- }
-
- // 2nd: copy precomputed values from Retain
- if (i < H - 1 && i >= H - K)
- {
- if (currentRetain[layer][i - (H - K)].size() > 0)
- {
- // pop element from retain
- System.arraycopy(currentRetain[layer][i - (H - K)]
- .lastElement(), 0, currentAuthPaths[layer][i],
- 0, mdLength);
- currentRetain[layer][i - (H - K)]
- .removeElementAt(currentRetain[layer][i
- - (H - K)].size() - 1);
- }
- }
-
- // STEP 4c of Algorithm
- // initialize new stack at heights 0..Tau-1
- if (i < H - K)
- {
- // create stacks anew
- int startPoint = Phi + 3 * (1 << i);
- if (startPoint < numLeafs[layer])
- {
- // if (layer < 2) {
- // System.out.println("initialized TH " + i + " on layer
- // " + layer);
- // }
- currentTreehash[layer][i].initialize();
- }
- }
- }
- }
-
- // now keep space is free to use
- if (Tau < H - 1 && L == 0)
- {
- System.arraycopy(tempKeep, 0,
- keep[layer][(int)Math.floor(Tau / 2)], 0, mdLength);
- }
-
- // only update empty stack at height h if all other stacks have
- // tailnodes with height >h
- // finds active stack with lowest node height, choses lower index in
- // case of tie
-
- // on the lowest layer leafs must be computed at once, no precomputation
- // is possible. So all treehash updates are done at once here
- if (layer == numLayer - 1)
- {
- for (int tmp = 1; tmp <= (H - K) / 2; tmp++)
- {
- // index of the treehash instance that receives the next update
- int minTreehash = getMinTreehashIndex(layer);
-
- // if active treehash is found update with a leaf
- if (minTreehash >= 0)
- {
- try
- {
- byte[] seed = new byte[mdLength];
- System.arraycopy(
- this.currentTreehash[layer][minTreehash]
- .getSeedActive(), 0, seed, 0, mdLength);
- byte[] seed2 = gmssRandom.nextSeed(seed);
- WinternitzOTSignature ots = new WinternitzOTSignature(
- seed2, this.digestProvider.get(), this.otsIndex[layer]);
- byte[] leaf = ots.getPublicKey();
- currentTreehash[layer][minTreehash].update(
- this.gmssRandom, leaf);
- }
- catch (Exception e)
- {
- System.out.println(e);
- }
- }
- }
- }
- else
- { // on higher layers the updates are done later
- this.minTreehash[layer] = getMinTreehashIndex(layer);
- }
- }
-
- /**
- * Returns the largest h such that 2^h | Phi
- *
- * @param Phi the leaf index
- * @return The largest <code>h</code> with <code>2^h | Phi</code> if
- * <code>Phi!=0</code> else return <code>-1</code>
- */
- private int heightOfPhi(int Phi)
- {
- if (Phi == 0)
- {
- return -1;
- }
- int Tau = 0;
- int modul = 1;
- while (Phi % modul == 0)
- {
- modul *= 2;
- Tau += 1;
- }
- return Tau - 1;
- }
-
- /**
- * Updates the authentication path and root calculation for the tree after
- * next (AUTH++, ROOT++) in layer <code>layer</code>
- *
- * @param layer
- */
- private void updateNextNextAuthRoot(int layer)
- {
-
- byte[] OTSseed = new byte[mdLength];
- OTSseed = gmssRandom.nextSeed(nextNextSeeds[layer - 1]);
-
- // get the necessary leaf
- if (layer == numLayer - 1)
- { // lowest layer computes the necessary
- // leaf completely at this time
- WinternitzOTSignature ots = new WinternitzOTSignature(OTSseed,
- digestProvider.get(), otsIndex[layer]);
- this.nextNextRoot[layer - 1].update(nextNextSeeds[layer - 1], ots
- .getPublicKey());
- }
- else
- { // other layers use the precomputed leafs in nextNextLeaf
- this.nextNextRoot[layer - 1].update(nextNextSeeds[layer - 1], nextNextLeaf[layer - 1].getLeaf());
- this.nextNextLeaf[layer - 1].initLeafCalc(nextNextSeeds[layer - 1]);
- }
- }
-
- public int[] getIndex()
- {
- return index;
- }
-
- /**
- * @return The current index of layer i
- */
- public int getIndex(int i)
- {
- return index[i];
- }
-
- public byte[][] getCurrentSeeds()
- {
- return Arrays.clone(currentSeeds);
- }
-
- public byte[][][] getCurrentAuthPaths()
- {
- return Arrays.clone(currentAuthPaths);
- }
-
- /**
- * @return The one-time signature of the root of the current subtree
- */
- public byte[] getSubtreeRootSig(int i)
- {
- return currentRootSig[i];
- }
-
-
- public GMSSDigestProvider getName()
- {
- return digestProvider;
- }
-
- /**
- * @return The number of leafs of each tree of layer i
- */
- public int getNumLeafs(int i)
- {
- return numLeafs[i];
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSPublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSPublicKeyParameters.java
deleted file mode 100644
index 492802d..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSPublicKeyParameters.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-
-public class GMSSPublicKeyParameters
- extends GMSSKeyParameters
-{
- /**
- * The GMSS public key
- */
- private byte[] gmssPublicKey;
-
- /**
- * The constructor.
- *
- * @param key a raw GMSS public key
- * @param gmssParameterSet an instance of GMSSParameterset
- */
- public GMSSPublicKeyParameters(byte[] key, GMSSParameters gmssParameterSet)
- {
- super(false, gmssParameterSet);
- this.gmssPublicKey = key;
- }
-
- /**
- * Returns the GMSS public key
- *
- * @return The GMSS public key
- */
- public byte[] getPublicKey()
- {
- return gmssPublicKey;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSRootCalc.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSRootCalc.java
deleted file mode 100644
index 35ac2e3..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSRootCalc.java
+++ /dev/null
@@ -1,596 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import java.util.Enumeration;
-import java.util.Vector;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Integers;
-import org.bouncycastle.util.encoders.Hex;
-
-
-/**
- * This class computes a whole Merkle tree and saves the needed values for
- * AuthPath computation. It is used for precomputation of the root of a
- * following tree. After initialization, 2^H updates are required to complete
- * the root. Every update requires one leaf value as parameter. While computing
- * the root all initial values for the authentication path algorithm (treehash,
- * auth, retain) are stored for later use.
- */
-public class GMSSRootCalc
-{
-
- /**
- * max height of the tree
- */
- private int heightOfTree;
-
- /**
- * length of the messageDigest
- */
- private int mdLength;
-
- /**
- * the treehash instances of the tree
- */
- private Treehash[] treehash;
-
- /**
- * stores the retain nodes for authPath computation
- */
- private Vector[] retain;
-
- /**
- * finally stores the root of the tree when finished
- */
- private byte[] root;
-
- /**
- * stores the authentication path y_1(i), i = 0..H-1
- */
- private byte[][] AuthPath;
-
- /**
- * the value K for the authentication path computation
- */
- private int K;
-
- /**
- * Vector element that stores the nodes on the stack
- */
- private Vector tailStack;
-
- /**
- * stores the height of all nodes laying on the tailStack
- */
- private Vector heightOfNodes;
- /**
- * The hash function used for the construction of the authentication trees
- */
- private Digest messDigestTree;
-
- /**
- * An array of strings containing the name of the hash function used to
- * construct the authentication trees and used by the OTS.
- */
- private GMSSDigestProvider digestProvider;
-
- /**
- * stores the index of the current node on each height of the tree
- */
- private int[] index;
-
- /**
- * true if instance was already initialized, false otherwise
- */
- private boolean isInitialized;
-
- /**
- * true it instance was finished
- */
- private boolean isFinished;
-
- /**
- * Integer that stores the index of the next seed that has to be omitted to
- * the treehashs
- */
- private int indexForNextSeed;
-
- /**
- * temporary integer that stores the height of the next treehash instance
- * that gets initialized with a seed
- */
- private int heightOfNextSeed;
-
- /**
- * This constructor regenerates a prior treehash object
- *
- * @param digest an array of strings, containing the digest of the used hash
- * function and PRNG and the digest of the corresponding
- * provider
- * @param statByte status bytes
- * @param statInt status ints
- */
- public GMSSRootCalc(Digest digest, byte[][] statByte, int[] statInt,
- Treehash[] treeH, Vector[] ret)
- {
- this.messDigestTree = digestProvider.get();
- this.digestProvider = digestProvider;
- // decode statInt
- this.heightOfTree = statInt[0];
- this.mdLength = statInt[1];
- this.K = statInt[2];
- this.indexForNextSeed = statInt[3];
- this.heightOfNextSeed = statInt[4];
- if (statInt[5] == 1)
- {
- this.isFinished = true;
- }
- else
- {
- this.isFinished = false;
- }
- if (statInt[6] == 1)
- {
- this.isInitialized = true;
- }
- else
- {
- this.isInitialized = false;
- }
-
- int tailLength = statInt[7];
-
- this.index = new int[heightOfTree];
- for (int i = 0; i < heightOfTree; i++)
- {
- this.index[i] = statInt[8 + i];
- }
-
- this.heightOfNodes = new Vector();
- for (int i = 0; i < tailLength; i++)
- {
- this.heightOfNodes.addElement(Integers.valueOf(statInt[8 + heightOfTree
- + i]));
- }
-
- // decode statByte
- this.root = statByte[0];
-
- this.AuthPath = new byte[heightOfTree][mdLength];
- for (int i = 0; i < heightOfTree; i++)
- {
- this.AuthPath[i] = statByte[1 + i];
- }
-
- this.tailStack = new Vector();
- for (int i = 0; i < tailLength; i++)
- {
- this.tailStack.addElement(statByte[1 + heightOfTree + i]);
- }
-
- // decode treeH
- this.treehash = GMSSUtils.clone(treeH);
-
- // decode ret
- this.retain = GMSSUtils.clone(ret);
- }
-
- /**
- * Constructor
- *
- * @param heightOfTree maximal height of the tree
- * @param digestProvider an array of strings, containing the name of the used hash
- * function and PRNG and the name of the corresponding
- * provider
- */
- public GMSSRootCalc(int heightOfTree, int K, GMSSDigestProvider digestProvider)
- {
- this.heightOfTree = heightOfTree;
- this.digestProvider = digestProvider;
- this.messDigestTree = digestProvider.get();
- this.mdLength = messDigestTree.getDigestSize();
- this.K = K;
- this.index = new int[heightOfTree];
- this.AuthPath = new byte[heightOfTree][mdLength];
- this.root = new byte[mdLength];
- // this.treehash = new Treehash[this.heightOfTree - this.K];
- this.retain = new Vector[this.K - 1];
- for (int i = 0; i < K - 1; i++)
- {
- this.retain[i] = new Vector();
- }
-
- }
-
- /**
- * Initializes the calculation of a new root
- *
- * @param sharedStack the stack shared by all treehash instances of this tree
- */
- public void initialize(Vector sharedStack)
- {
- this.treehash = new Treehash[this.heightOfTree - this.K];
- for (int i = 0; i < this.heightOfTree - this.K; i++)
- {
- this.treehash[i] = new Treehash(sharedStack, i, this.digestProvider.get());
- }
-
- this.index = new int[heightOfTree];
- this.AuthPath = new byte[heightOfTree][mdLength];
- this.root = new byte[mdLength];
-
- this.tailStack = new Vector();
- this.heightOfNodes = new Vector();
- this.isInitialized = true;
- this.isFinished = false;
-
- for (int i = 0; i < heightOfTree; i++)
- {
- this.index[i] = -1;
- }
-
- this.retain = new Vector[this.K - 1];
- for (int i = 0; i < K - 1; i++)
- {
- this.retain[i] = new Vector();
- }
-
- this.indexForNextSeed = 3;
- this.heightOfNextSeed = 0;
- }
-
- /**
- * updates the root with one leaf and stores needed values in retain,
- * treehash or authpath. Additionally counts the seeds used. This method is
- * used when performing the updates for TREE++.
- *
- * @param seed the initial seed for treehash: seedNext
- * @param leaf the height of the treehash
- */
- public void update(byte[] seed, byte[] leaf)
- {
- if (this.heightOfNextSeed < (this.heightOfTree - this.K)
- && this.indexForNextSeed - 2 == index[0])
- {
- this.initializeTreehashSeed(seed, this.heightOfNextSeed);
- this.heightOfNextSeed++;
- this.indexForNextSeed *= 2;
- }
- // now call the simple update
- this.update(leaf);
- }
-
- /**
- * Updates the root with one leaf and stores the needed values in retain,
- * treehash or authpath
- */
- public void update(byte[] leaf)
- {
-
- if (isFinished)
- {
- System.out.print("Too much updates for Tree!!");
- return;
- }
- if (!isInitialized)
- {
- System.err.println("GMSSRootCalc not initialized!");
- return;
- }
-
- // a new leaf was omitted, so raise index on lowest layer
- index[0]++;
-
- // store the nodes on the lowest layer in treehash or authpath
- if (index[0] == 1)
- {
- System.arraycopy(leaf, 0, AuthPath[0], 0, mdLength);
- }
- else if (index[0] == 3)
- {
- // store in treehash only if K < H
- if (heightOfTree > K)
- {
- treehash[0].setFirstNode(leaf);
- }
- }
-
- if ((index[0] - 3) % 2 == 0 && index[0] >= 3)
- {
- // store in retain if K = H
- if (heightOfTree == K)
- // TODO: check it
- {
- retain[0].insertElementAt(leaf, 0);
- }
- }
-
- // if first update to this tree is made
- if (index[0] == 0)
- {
- tailStack.addElement(leaf);
- heightOfNodes.addElement(Integers.valueOf(0));
- }
- else
- {
-
- byte[] help = new byte[mdLength];
- byte[] toBeHashed = new byte[mdLength << 1];
-
- // store the new leaf in help
- System.arraycopy(leaf, 0, help, 0, mdLength);
- int helpHeight = 0;
- // while top to nodes have same height
- while (tailStack.size() > 0
- && helpHeight == ((Integer)heightOfNodes.lastElement())
- .intValue())
- {
-
- // help <-- hash(stack top element || help)
- System.arraycopy(tailStack.lastElement(), 0, toBeHashed, 0,
- mdLength);
- tailStack.removeElementAt(tailStack.size() - 1);
- heightOfNodes.removeElementAt(heightOfNodes.size() - 1);
- System.arraycopy(help, 0, toBeHashed, mdLength, mdLength);
-
- messDigestTree.update(toBeHashed, 0, toBeHashed.length);
- help = new byte[messDigestTree.getDigestSize()];
- messDigestTree.doFinal(help, 0);
-
- // the new help node is one step higher
- helpHeight++;
- if (helpHeight < heightOfTree)
- {
- index[helpHeight]++;
-
- // add index 1 element to initial authpath
- if (index[helpHeight] == 1)
- {
- System.arraycopy(help, 0, AuthPath[helpHeight], 0,
- mdLength);
- }
-
- if (helpHeight >= heightOfTree - K)
- {
- if (helpHeight == 0)
- {
- System.out.println("M���P");
- }
- // add help element to retain stack if it is a right
- // node
- // and not stored in treehash
- if ((index[helpHeight] - 3) % 2 == 0
- && index[helpHeight] >= 3)
- // TODO: check it
- {
- retain[helpHeight - (heightOfTree - K)]
- .insertElementAt(help, 0);
- }
- }
- else
- {
- // if element is third in his line add it to treehash
- if (index[helpHeight] == 3)
- {
- treehash[helpHeight].setFirstNode(help);
- }
- }
- }
- }
- // push help element to the stack
- tailStack.addElement(help);
- heightOfNodes.addElement(Integers.valueOf(helpHeight));
-
- // is the root calculation finished?
- if (helpHeight == heightOfTree)
- {
- isFinished = true;
- isInitialized = false;
- root = (byte[])tailStack.lastElement();
- }
- }
-
- }
-
- /**
- * initializes the seeds for the treehashs of the tree precomputed by this
- * class
- *
- * @param seed the initial seed for treehash: seedNext
- * @param index the height of the treehash
- */
- public void initializeTreehashSeed(byte[] seed, int index)
- {
- treehash[index].initializeSeed(seed);
- }
-
- /**
- * Method to check whether the instance has been initialized or not
- *
- * @return true if treehash was already initialized
- */
- public boolean wasInitialized()
- {
- return isInitialized;
- }
-
- /**
- * Method to check whether the instance has been finished or not
- *
- * @return true if tree has reached its maximum height
- */
- public boolean wasFinished()
- {
- return isFinished;
- }
-
- /**
- * returns the authentication path of the first leaf of the tree
- *
- * @return the authentication path of the first leaf of the tree
- */
- public byte[][] getAuthPath()
- {
- return GMSSUtils.clone(AuthPath);
- }
-
- /**
- * returns the initial treehash instances, storing value y_3(i)
- *
- * @return the initial treehash instances, storing value y_3(i)
- */
- public Treehash[] getTreehash()
- {
- return GMSSUtils.clone(treehash);
- }
-
- /**
- * returns the retain stacks storing all right nodes near to the root
- *
- * @return the retain stacks storing all right nodes near to the root
- */
- public Vector[] getRetain()
- {
- return GMSSUtils.clone(retain);
- }
-
- /**
- * returns the finished root value
- *
- * @return the finished root value
- */
- public byte[] getRoot()
- {
- return Arrays.clone(root);
- }
-
- /**
- * returns the shared stack
- *
- * @return the shared stack
- */
- public Vector getStack()
- {
- Vector copy = new Vector();
- for (Enumeration en = tailStack.elements(); en.hasMoreElements();)
- {
- copy.addElement(en.nextElement());
- }
- return copy;
- }
-
- /**
- * Returns the status byte array used by the GMSSPrivateKeyASN.1 class
- *
- * @return The status bytes
- */
- public byte[][] getStatByte()
- {
-
- int tailLength;
- if (tailStack == null)
- {
- tailLength = 0;
- }
- else
- {
- tailLength = tailStack.size();
- }
- byte[][] statByte = new byte[1 + heightOfTree + tailLength][64]; //FIXME: messDigestTree.getByteLength()
- statByte[0] = root;
-
- for (int i = 0; i < heightOfTree; i++)
- {
- statByte[1 + i] = AuthPath[i];
- }
- for (int i = 0; i < tailLength; i++)
- {
- statByte[1 + heightOfTree + i] = (byte[])tailStack.elementAt(i);
- }
-
- return statByte;
- }
-
- /**
- * Returns the status int array used by the GMSSPrivateKeyASN.1 class
- *
- * @return The status ints
- */
- public int[] getStatInt()
- {
-
- int tailLength;
- if (tailStack == null)
- {
- tailLength = 0;
- }
- else
- {
- tailLength = tailStack.size();
- }
- int[] statInt = new int[8 + heightOfTree + tailLength];
- statInt[0] = heightOfTree;
- statInt[1] = mdLength;
- statInt[2] = K;
- statInt[3] = indexForNextSeed;
- statInt[4] = heightOfNextSeed;
- if (isFinished)
- {
- statInt[5] = 1;
- }
- else
- {
- statInt[5] = 0;
- }
- if (isInitialized)
- {
- statInt[6] = 1;
- }
- else
- {
- statInt[6] = 0;
- }
- statInt[7] = tailLength;
-
- for (int i = 0; i < heightOfTree; i++)
- {
- statInt[8 + i] = index[i];
- }
- for (int i = 0; i < tailLength; i++)
- {
- statInt[8 + heightOfTree + i] = ((Integer)heightOfNodes
- .elementAt(i)).intValue();
- }
-
- return statInt;
- }
-
- /**
- * @return a human readable version of the structure
- */
- public String toString()
- {
- String out = "";
- int tailLength;
- if (tailStack == null)
- {
- tailLength = 0;
- }
- else
- {
- tailLength = tailStack.size();
- }
-
- for (int i = 0; i < 8 + heightOfTree + tailLength; i++)
- {
- out = out + getStatInt()[i] + " ";
- }
- for (int i = 0; i < 1 + heightOfTree + tailLength; i++)
- {
- out = out + new String(Hex.encode(getStatByte()[i])) + " ";
- }
- out = out + " " + digestProvider.get().getDigestSize();
- return out;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSRootSig.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSRootSig.java
deleted file mode 100644
index 8a4796f..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSRootSig.java
+++ /dev/null
@@ -1,666 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom;
-import org.bouncycastle.util.encoders.Hex;
-
-
-/**
- * This class implements the distributed signature generation of the Winternitz
- * one-time signature scheme (OTSS), described in C.Dods, N.P. Smart, and M.
- * Stam, "Hash Based Digital Signature Schemes", LNCS 3796, pages 96&#8211;115,
- * 2005. The class is used by the GMSS classes.
- */
-public class GMSSRootSig
-{
-
- /**
- * The hash function used by the OTS
- */
- private Digest messDigestOTS;
-
- /**
- * The length of the message digest and private key
- */
- private int mdsize, keysize;
-
- /**
- * The private key
- */
- private byte[] privateKeyOTS;
-
- /**
- * The message bytes
- */
- private byte[] hash;
-
- /**
- * The signature bytes
- */
- private byte[] sign;
-
- /**
- * The Winternitz parameter
- */
- private int w;
-
- /**
- * The source of randomness for OTS private key generation
- */
- private GMSSRandom gmssRandom;
-
- /**
- * Sizes of the message
- */
- private int messagesize;
-
- /**
- * Some precalculated values
- */
- private int k;
-
- /**
- * Some variables for storing the actual status of distributed signing
- */
- private int r, test, counter, ii;
-
- /**
- * variables for storing big numbers for the actual status of distributed
- * signing
- */
- private long test8, big8;
-
- /**
- * The necessary steps of each updateSign() call
- */
- private int steps;
-
- /**
- * The checksum part
- */
- private int checksum;
-
- /**
- * The height of the tree
- */
- private int height;
-
- /**
- * The current intern OTSseed
- */
- private byte[] seed;
-
- /**
- * This constructor regenerates a prior GMSSRootSig object used by the
- * GMSSPrivateKeyASN.1 class
- *
- * @param digest an array of strings, containing the digest of the used hash
- * function, the digest of the PRGN and the names of the
- * corresponding providers
- * @param statByte status byte array
- * @param statInt status int array
- */
- public GMSSRootSig(Digest digest, byte[][] statByte, int[] statInt)
- {
- messDigestOTS = digest;
- gmssRandom = new GMSSRandom(messDigestOTS);
-
- this.counter = statInt[0];
- this.test = statInt[1];
- this.ii = statInt[2];
- this.r = statInt[3];
- this.steps = statInt[4];
- this.keysize = statInt[5];
- this.height = statInt[6];
- this.w = statInt[7];
- this.checksum = statInt[8];
-
- this.mdsize = messDigestOTS.getDigestSize();
-
- this.k = (1 << w) - 1;
-
- int mdsizeBit = mdsize << 3;
- this.messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w);
-
- this.privateKeyOTS = statByte[0];
- this.seed = statByte[1];
- this.hash = statByte[2];
-
- this.sign = statByte[3];
-
- this.test8 = ((statByte[4][0] & 0xff))
- | ((long)(statByte[4][1] & 0xff) << 8)
- | ((long)(statByte[4][2] & 0xff) << 16)
- | ((long)(statByte[4][3] & 0xff)) << 24
- | ((long)(statByte[4][4] & 0xff)) << 32
- | ((long)(statByte[4][5] & 0xff)) << 40
- | ((long)(statByte[4][6] & 0xff)) << 48
- | ((long)(statByte[4][7] & 0xff)) << 56;
-
- this.big8 = ((statByte[4][8] & 0xff))
- | ((long)(statByte[4][9] & 0xff) << 8)
- | ((long)(statByte[4][10] & 0xff) << 16)
- | ((long)(statByte[4][11] & 0xff)) << 24
- | ((long)(statByte[4][12] & 0xff)) << 32
- | ((long)(statByte[4][13] & 0xff)) << 40
- | ((long)(statByte[4][14] & 0xff)) << 48
- | ((long)(statByte[4][15] & 0xff)) << 56;
- }
-
- /**
- * The constructor generates the PRNG and initializes some variables
- *
- * @param digest an array of strings, containing the digest of the used hash
- * function, the digest of the PRGN and the names of the
- * corresponding providers
- * @param w the winternitz parameter
- * @param height the heigth of the tree
- */
- public GMSSRootSig(Digest digest, int w, int height)
- {
- messDigestOTS = digest;
- gmssRandom = new GMSSRandom(messDigestOTS);
-
- this.mdsize = messDigestOTS.getDigestSize();
- this.w = w;
- this.height = height;
-
- this.k = (1 << w) - 1;
-
- int mdsizeBit = mdsize << 3;
- this.messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w);
- }
-
- /**
- * This method initializes the distributed sigature calculation. Variables
- * are reseted and necessary steps are calculated
- *
- * @param seed0 the initial OTSseed
- * @param message the massage which will be signed
- */
- public void initSign(byte[] seed0, byte[] message)
- {
-
- // create hash of message m
- this.hash = new byte[mdsize];
- messDigestOTS.update(message, 0, message.length);
- this.hash = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(this.hash, 0);
-
- // variables for calculation of steps
- byte[] messPart = new byte[mdsize];
- System.arraycopy(hash, 0, messPart, 0, mdsize);
- int checkPart = 0;
- int sumH = 0;
- int checksumsize = getLog((messagesize << w) + 1);
-
- // ------- calculation of necessary steps ------
- if (8 % w == 0)
- {
- int dt = 8 / w;
- // message part
- for (int a = 0; a < mdsize; a++)
- {
- // count necessary hashs in 'sumH'
- for (int b = 0; b < dt; b++)
- {
- sumH += messPart[a] & k;
- messPart[a] = (byte)(messPart[a] >>> w);
- }
- }
- // checksum part
- this.checksum = (messagesize << w) - sumH;
- checkPart = checksum;
- // count necessary hashs in 'sumH'
- for (int b = 0; b < checksumsize; b += w)
- {
- sumH += checkPart & k;
- checkPart >>>= w;
- }
- } // end if ( 8 % w == 0 )
- else if (w < 8)
- {
- long big8;
- int ii = 0;
- int dt = mdsize / w;
-
- // first d*w bytes of hash (main message part)
- for (int i = 0; i < dt; i++)
- {
- big8 = 0;
- for (int j = 0; j < w; j++)
- {
- big8 ^= (messPart[ii] & 0xff) << (j << 3);
- ii++;
- }
- // count necessary hashs in 'sumH'
- for (int j = 0; j < 8; j++)
- {
- sumH += (int)(big8 & k);
- big8 >>>= w;
- }
- }
- // rest of message part
- dt = mdsize % w;
- big8 = 0;
- for (int j = 0; j < dt; j++)
- {
- big8 ^= (messPart[ii] & 0xff) << (j << 3);
- ii++;
- }
- dt <<= 3;
- // count necessary hashs in 'sumH'
- for (int j = 0; j < dt; j += w)
- {
- sumH += (int)(big8 & k);
- big8 >>>= w;
- }
- // checksum part
- this.checksum = (messagesize << w) - sumH;
- checkPart = checksum;
- // count necessary hashs in 'sumH'
- for (int i = 0; i < checksumsize; i += w)
- {
- sumH += checkPart & k;
- checkPart >>>= w;
- }
- }// end if(w<8)
- else if (w < 57)
- {
- long big8;
- int r = 0;
- int s, f, rest, ii;
-
- // first a*w bits of hash where a*w <= 8*mdsize < (a+1)*w (main
- // message part)
- while (r <= ((mdsize << 3) - w))
- {
- s = r >>> 3;
- rest = r % 8;
- r += w;
- f = (r + 7) >>> 3;
- big8 = 0;
- ii = 0;
- for (int j = s; j < f; j++)
- {
- big8 ^= (messPart[j] & 0xff) << (ii << 3);
- ii++;
- }
- big8 >>>= rest;
- // count necessary hashs in 'sumH'
- sumH += (big8 & k);
-
- }
- // rest of message part
- s = r >>> 3;
- if (s < mdsize)
- {
- rest = r % 8;
- big8 = 0;
- ii = 0;
- for (int j = s; j < mdsize; j++)
- {
- big8 ^= (messPart[j] & 0xff) << (ii << 3);
- ii++;
- }
-
- big8 >>>= rest;
- // count necessary hashs in 'sumH'
- sumH += (big8 & k);
- }
- // checksum part
- this.checksum = (messagesize << w) - sumH;
- checkPart = checksum;
- // count necessary hashs in 'sumH'
- for (int i = 0; i < checksumsize; i += w)
- {
- sumH += (checkPart & k);
- checkPart >>>= w;
- }
- }// end if(w<57)
-
- // calculate keysize
- this.keysize = messagesize
- + (int)Math.ceil((double)checksumsize / (double)w);
-
- // calculate steps: 'keysize' times PRNG, 'sumH' times hashing,
- // (1<<height)-1 updateSign() calls
- this.steps = (int)Math.ceil((double)(keysize + sumH)
- / (double)((1 << height)));
- // ----------------------------
-
- // reset variables
- this.sign = new byte[keysize * mdsize];
- this.counter = 0;
- this.test = 0;
- this.ii = 0;
- this.test8 = 0;
- this.r = 0;
- // define the private key messagesize
- this.privateKeyOTS = new byte[mdsize];
- // copy the seed
- this.seed = new byte[mdsize];
- System.arraycopy(seed0, 0, this.seed, 0, mdsize);
-
- }
-
- /**
- * This Method performs <code>steps</code> steps of distributed signature
- * calculaion
- *
- * @return true if signature is generated completly, else false
- */
- public boolean updateSign()
- {
- // steps times do
-
- for (int s = 0; s < steps; s++)
- { // do 'step' times
-
- if (counter < keysize)
- { // generate the private key or perform
- // the next hash
- oneStep();
- }
- if (counter == keysize)
- {// finish
- return true;
- }
- }
-
- return false; // leaf not finished yet
- }
-
- /**
- * @return The private OTS key
- */
- public byte[] getSig()
- {
-
- return sign;
- }
-
- /**
- * @return The one-time signature of the message, generated step by step
- */
- private void oneStep()
- {
- // -------- if (8 % w == 0) ----------
- if (8 % w == 0)
- {
- if (test == 0)
- {
- // get current OTSprivateKey
- this.privateKeyOTS = gmssRandom.nextSeed(seed);
- // System.arraycopy(privateKeyOTS, 0, hlp, 0, mdsize);
-
- if (ii < mdsize)
- { // for main message part
- test = hash[ii] & k;
- hash[ii] = (byte)(hash[ii] >>> w);
- }
- else
- { // for checksum part
- test = checksum & k;
- checksum >>>= w;
- }
- }
- else if (test > 0)
- { // hash the private Key 'test' times (on
- // time each step)
- messDigestOTS.update(privateKeyOTS, 0, privateKeyOTS.length);
- privateKeyOTS = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(privateKeyOTS, 0);
- test--;
- }
- if (test == 0)
- { // if all hashes done copy result to siganture
- // array
- System.arraycopy(privateKeyOTS, 0, sign, counter * mdsize,
- mdsize);
- counter++;
-
- if (counter % (8 / w) == 0)
- { // raise array index for main
- // massage part
- ii++;
- }
- }
-
- }// ----- end if (8 % w == 0) -----
- // ---------- if ( w < 8 ) ----------------
- else if (w < 8)
- {
-
- if (test == 0)
- {
- if (counter % 8 == 0 && ii < mdsize)
- { // after every 8th "add
- // to signature"-step
- big8 = 0;
- if (counter < ((mdsize / w) << 3))
- {// main massage
- // (generate w*8 Bits
- // every time) part
- for (int j = 0; j < w; j++)
- {
- big8 ^= (hash[ii] & 0xff) << (j << 3);
- ii++;
- }
- }
- else
- { // rest of massage part (once)
- for (int j = 0; j < mdsize % w; j++)
- {
- big8 ^= (hash[ii] & 0xff) << (j << 3);
- ii++;
- }
- }
- }
- if (counter == messagesize)
- { // checksum part (once)
- big8 = checksum;
- }
-
- test = (int)(big8 & k);
- // generate current OTSprivateKey
- this.privateKeyOTS = gmssRandom.nextSeed(seed);
- // System.arraycopy(privateKeyOTS, 0, hlp, 0, mdsize);
-
- }
- else if (test > 0)
- { // hash the private Key 'test' times (on
- // time each step)
- messDigestOTS.update(privateKeyOTS, 0, privateKeyOTS.length);
- privateKeyOTS = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(privateKeyOTS, 0);
- test--;
- }
- if (test == 0)
- { // if all hashes done copy result to siganture
- // array
- System.arraycopy(privateKeyOTS, 0, sign, counter * mdsize,
- mdsize);
- big8 >>>= w;
- counter++;
- }
-
- }// ------- end if(w<8)--------------------------------
- // --------- if w < 57 -----------------------------
- else if (w < 57)
- {
-
- if (test8 == 0)
- {
- int s, f, rest;
- big8 = 0;
- ii = 0;
- rest = r % 8;
- s = r >>> 3;
- // --- message part---
- if (s < mdsize)
- {
- if (r <= ((mdsize << 3) - w))
- { // first message part
- r += w;
- f = (r + 7) >>> 3;
- }
- else
- { // rest of message part (once)
- f = mdsize;
- r += w;
- }
- // generate long 'big8' with minimum w next bits of the
- // message array
- for (int i = s; i < f; i++)
- {
- big8 ^= (hash[i] & 0xff) << (ii << 3);
- ii++;
- }
- // delete bits on the right side, which were used already by
- // the last loop
- big8 >>>= rest;
- test8 = (big8 & k);
- }
- // --- checksum part
- else
- {
- test8 = (checksum & k);
- checksum >>>= w;
- }
- // generate current OTSprivateKey
- this.privateKeyOTS = gmssRandom.nextSeed(seed);
- // System.arraycopy(privateKeyOTS, 0, hlp, 0, mdsize);
-
- }
- else if (test8 > 0)
- { // hash the private Key 'test' times (on
- // time each step)
- messDigestOTS.update(privateKeyOTS, 0, privateKeyOTS.length);
- privateKeyOTS = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(privateKeyOTS, 0);
- test8--;
- }
- if (test8 == 0)
- { // if all hashes done copy result to siganture
- // array
- System.arraycopy(privateKeyOTS, 0, sign, counter * mdsize,
- mdsize);
- counter++;
- }
-
- }
- }
-
- /**
- * This method returns the least integer that is greater or equal to the
- * logarithm to the base 2 of an integer <code>intValue</code>.
- *
- * @param intValue an integer
- * @return The least integer greater or equal to the logarithm to the base 2
- * of <code>intValue</code>
- */
- public int getLog(int intValue)
- {
- int log = 1;
- int i = 2;
- while (i < intValue)
- {
- i <<= 1;
- log++;
- }
- return log;
- }
-
- /**
- * This method returns the status byte array
- *
- * @return statBytes
- */
- public byte[][] getStatByte()
- {
-
- byte[][] statByte = new byte[5][mdsize];
- statByte[0] = privateKeyOTS;
- statByte[1] = seed;
- statByte[2] = hash;
- statByte[3] = sign;
- statByte[4] = this.getStatLong();
-
- return statByte;
- }
-
- /**
- * This method returns the status int array
- *
- * @return statInt
- */
- public int[] getStatInt()
- {
- int[] statInt = new int[9];
- statInt[0] = counter;
- statInt[1] = test;
- statInt[2] = ii;
- statInt[3] = r;
- statInt[4] = steps;
- statInt[5] = keysize;
- statInt[6] = height;
- statInt[7] = w;
- statInt[8] = checksum;
- return statInt;
- }
-
- /**
- * Converts the long parameters into byte arrays to store it in
- * statByte-Array
- */
- public byte[] getStatLong()
- {
- byte[] bytes = new byte[16];
-
- bytes[0] = (byte)((test8) & 0xff);
- bytes[1] = (byte)((test8 >> 8) & 0xff);
- bytes[2] = (byte)((test8 >> 16) & 0xff);
- bytes[3] = (byte)((test8 >> 24) & 0xff);
- bytes[4] = (byte)((test8) >> 32 & 0xff);
- bytes[5] = (byte)((test8 >> 40) & 0xff);
- bytes[6] = (byte)((test8 >> 48) & 0xff);
- bytes[7] = (byte)((test8 >> 56) & 0xff);
-
- bytes[8] = (byte)((big8) & 0xff);
- bytes[9] = (byte)((big8 >> 8) & 0xff);
- bytes[10] = (byte)((big8 >> 16) & 0xff);
- bytes[11] = (byte)((big8 >> 24) & 0xff);
- bytes[12] = (byte)((big8) >> 32 & 0xff);
- bytes[13] = (byte)((big8 >> 40) & 0xff);
- bytes[14] = (byte)((big8 >> 48) & 0xff);
- bytes[15] = (byte)((big8 >> 56) & 0xff);
-
- return bytes;
- }
-
- /**
- * returns a string representation of the instance
- *
- * @return a string representation of the instance
- */
- public String toString()
- {
- String out = "" + this.big8 + " ";
- int[] statInt = new int[9];
- statInt = this.getStatInt();
- byte[][] statByte = new byte[5][mdsize];
- statByte = this.getStatByte();
- for (int i = 0; i < 9; i++)
- {
- out = out + statInt[i] + " ";
- }
- for (int i = 0; i < 5; i++)
- {
- out = out + new String(Hex.encode(statByte[i])) + " ";
- }
-
- return out;
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSSigner.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSSigner.java
deleted file mode 100644
index 8832fb3..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSSigner.java
+++ /dev/null
@@ -1,403 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.MessageSigner;
-import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom;
-import org.bouncycastle.pqc.crypto.gmss.util.GMSSUtil;
-import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSVerify;
-import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSignature;
-import org.bouncycastle.util.Arrays;
-
-/**
- * This class implements the GMSS signature scheme.
- */
-public class GMSSSigner
- implements MessageSigner
-{
-
- /**
- * Instance of GMSSParameterSpec
- */
- //private GMSSParameterSpec gmssParameterSpec;
-
- /**
- * Instance of GMSSUtilities
- */
- private GMSSUtil gmssUtil = new GMSSUtil();
-
-
- /**
- * The raw GMSS public key
- */
- private byte[] pubKeyBytes;
-
- /**
- * Hash function for the construction of the authentication trees
- */
- private Digest messDigestTrees;
-
- /**
- * The length of the hash function output
- */
- private int mdLength;
-
- /**
- * The number of tree layers
- */
- private int numLayer;
-
- /**
- * The hash function used by the OTS
- */
- private Digest messDigestOTS;
-
- /**
- * An instance of the Winternitz one-time signature
- */
- private WinternitzOTSignature ots;
-
- /**
- * Array of strings containing the name of the hash function used by the OTS
- * and the corresponding provider name
- */
- private GMSSDigestProvider digestProvider;
-
- /**
- * The current main tree and subtree indices
- */
- private int[] index;
-
- /**
- * Array of the authentication paths for the current trees of all layers
- */
- private byte[][][] currentAuthPaths;
-
- /**
- * The one-time signature of the roots of the current subtrees
- */
- private byte[][] subtreeRootSig;
-
-
- /**
- * The GMSSParameterset
- */
- private GMSSParameters gmssPS;
-
- /**
- * The PRNG
- */
- private GMSSRandom gmssRandom;
-
- GMSSKeyParameters key;
-
- // XXX needed? Source of randomness
- private SecureRandom random;
-
-
- /**
- * The standard constructor tries to generate the MerkleTree Algorithm
- * identifier with the corresponding OID.
- *
- * @param digest the digest to use
- */
- // TODO
- public GMSSSigner(GMSSDigestProvider digest)
- {
- digestProvider = digest;
- messDigestTrees = digest.get();
- messDigestOTS = messDigestTrees;
- mdLength = messDigestTrees.getDigestSize();
- gmssRandom = new GMSSRandom(messDigestTrees);
- }
-
- public void init(boolean forSigning,
- CipherParameters param)
- {
-
- if (forSigning)
- {
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)param;
-
- // XXX random needed?
- this.random = rParam.getRandom();
- this.key = (GMSSPrivateKeyParameters)rParam.getParameters();
- initSign();
-
- }
- else
- {
-
- this.random = new SecureRandom();
- this.key = (GMSSPrivateKeyParameters)param;
- initSign();
- }
- }
- else
- {
- this.key = (GMSSPublicKeyParameters)param;
- initVerify();
-
- }
-
- }
-
-
- /**
- * Initializes the signature algorithm for signing a message.
- */
- private void initSign()
- {
- messDigestTrees.reset();
- // set private key and take from it ots key, auth, tree and key
- // counter, rootSign
- GMSSPrivateKeyParameters gmssPrivateKey = (GMSSPrivateKeyParameters)key;
-
- if (gmssPrivateKey.isUsed())
- {
- throw new IllegalStateException("Private key already used");
- }
-
- // check if last signature has been generated
- if (gmssPrivateKey.getIndex(0) >= gmssPrivateKey.getNumLeafs(0))
- {
- throw new IllegalStateException("No more signatures can be generated");
- }
-
- // get Parameterset
- this.gmssPS = gmssPrivateKey.getParameters();
- // get numLayer
- this.numLayer = gmssPS.getNumOfLayers();
-
- // get OTS Instance of lowest layer
- byte[] seed = gmssPrivateKey.getCurrentSeeds()[numLayer - 1];
- byte[] OTSSeed = new byte[mdLength];
- byte[] dummy = new byte[mdLength];
- System.arraycopy(seed, 0, dummy, 0, mdLength);
- OTSSeed = gmssRandom.nextSeed(dummy); // secureRandom.nextBytes(currentSeeds[currentSeeds.length-1]);secureRandom.nextBytes(OTSseed);
- this.ots = new WinternitzOTSignature(OTSSeed, digestProvider.get(), gmssPS.getWinternitzParameter()[numLayer - 1]);
-
- byte[][][] helpCurrentAuthPaths = gmssPrivateKey.getCurrentAuthPaths();
- currentAuthPaths = new byte[numLayer][][];
-
- // copy the main tree authentication path
- for (int j = 0; j < numLayer; j++)
- {
- currentAuthPaths[j] = new byte[helpCurrentAuthPaths[j].length][mdLength];
- for (int i = 0; i < helpCurrentAuthPaths[j].length; i++)
- {
- System.arraycopy(helpCurrentAuthPaths[j][i], 0, currentAuthPaths[j][i], 0, mdLength);
- }
- }
-
- // copy index
- index = new int[numLayer];
- System.arraycopy(gmssPrivateKey.getIndex(), 0, index, 0, numLayer);
-
- // copy subtreeRootSig
- byte[] helpSubtreeRootSig;
- subtreeRootSig = new byte[numLayer - 1][];
- for (int i = 0; i < numLayer - 1; i++)
- {
- helpSubtreeRootSig = gmssPrivateKey.getSubtreeRootSig(i);
- subtreeRootSig[i] = new byte[helpSubtreeRootSig.length];
- System.arraycopy(helpSubtreeRootSig, 0, subtreeRootSig[i], 0, helpSubtreeRootSig.length);
- }
-
- gmssPrivateKey.markUsed();
- }
-
- /**
- * Signs a message.
- *
- * @return the signature.
- */
- public byte[] generateSignature(byte[] message)
- {
-
- byte[] otsSig = new byte[mdLength];
- byte[] authPathBytes;
- byte[] indexBytes;
-
- otsSig = ots.getSignature(message);
-
- // get concatenated lowest layer tree authentication path
- authPathBytes = gmssUtil.concatenateArray(currentAuthPaths[numLayer - 1]);
-
- // put lowest layer index into a byte array
- indexBytes = gmssUtil.intToBytesLittleEndian(index[numLayer - 1]);
-
- // create first part of GMSS signature
- byte[] gmssSigFirstPart = new byte[indexBytes.length + otsSig.length + authPathBytes.length];
- System.arraycopy(indexBytes, 0, gmssSigFirstPart, 0, indexBytes.length);
- System.arraycopy(otsSig, 0, gmssSigFirstPart, indexBytes.length, otsSig.length);
- System.arraycopy(authPathBytes, 0, gmssSigFirstPart, (indexBytes.length + otsSig.length), authPathBytes.length);
- // --- end first part
-
- // --- next parts of the signature
- // create initial array with length 0 for iteration
- byte[] gmssSigNextPart = new byte[0];
-
- for (int i = numLayer - 1 - 1; i >= 0; i--)
- {
-
- // get concatenated next tree authentication path
- authPathBytes = gmssUtil.concatenateArray(currentAuthPaths[i]);
-
- // put next tree index into a byte array
- indexBytes = gmssUtil.intToBytesLittleEndian(index[i]);
-
- // create next part of GMSS signature
-
- // create help array and copy actual gmssSig into it
- byte[] helpGmssSig = new byte[gmssSigNextPart.length];
- System.arraycopy(gmssSigNextPart, 0, helpGmssSig, 0, gmssSigNextPart.length);
- // adjust length of gmssSigNextPart for adding next part
- gmssSigNextPart = new byte[helpGmssSig.length + indexBytes.length + subtreeRootSig[i].length + authPathBytes.length];
-
- // copy old data (help array) and new data in gmssSigNextPart
- System.arraycopy(helpGmssSig, 0, gmssSigNextPart, 0, helpGmssSig.length);
- System.arraycopy(indexBytes, 0, gmssSigNextPart, helpGmssSig.length, indexBytes.length);
- System.arraycopy(subtreeRootSig[i], 0, gmssSigNextPart, (helpGmssSig.length + indexBytes.length), subtreeRootSig[i].length);
- System.arraycopy(authPathBytes, 0, gmssSigNextPart, (helpGmssSig.length + indexBytes.length + subtreeRootSig[i].length), authPathBytes.length);
-
- }
- // --- end next parts
-
- // concatenate the two parts of the GMSS signature
- byte[] gmssSig = new byte[gmssSigFirstPart.length + gmssSigNextPart.length];
- System.arraycopy(gmssSigFirstPart, 0, gmssSig, 0, gmssSigFirstPart.length);
- System.arraycopy(gmssSigNextPart, 0, gmssSig, gmssSigFirstPart.length, gmssSigNextPart.length);
-
- // return the GMSS signature
- return gmssSig;
- }
-
- /**
- * Initializes the signature algorithm for verifying a signature.
- */
- private void initVerify()
- {
- messDigestTrees.reset();
-
- GMSSPublicKeyParameters gmssPublicKey = (GMSSPublicKeyParameters)key;
- pubKeyBytes = gmssPublicKey.getPublicKey();
- gmssPS = gmssPublicKey.getParameters();
- // get numLayer
- this.numLayer = gmssPS.getNumOfLayers();
-
-
- }
-
- /**
- * This function verifies the signature of the message that has been
- * updated, with the aid of the public key.
- *
- * @param message the message
- * @param signature the signature associated with the message
- * @return true if the signature has been verified, false otherwise.
- */
- public boolean verifySignature(byte[] message, byte[] signature)
- {
-
- boolean success = false;
- // int halfSigLength = signature.length >>> 1;
- messDigestOTS.reset();
- WinternitzOTSVerify otsVerify;
- int otsSigLength;
-
- byte[] help = message;
-
- byte[] otsSig;
- byte[] otsPublicKey;
- byte[][] authPath;
- byte[] dest;
- int nextEntry = 0;
- int index;
- // Verify signature
-
- // --- begin with message = 'message that was signed'
- // and then in each step message = subtree root
- for (int j = numLayer - 1; j >= 0; j--)
- {
- otsVerify = new WinternitzOTSVerify(digestProvider.get(), gmssPS.getWinternitzParameter()[j]);
- otsSigLength = otsVerify.getSignatureLength();
-
- message = help;
- // get the subtree index
- index = gmssUtil.bytesToIntLittleEndian(signature, nextEntry);
-
- // 4 is the number of bytes in integer
- nextEntry += 4;
-
- // get one-time signature
- otsSig = new byte[otsSigLength];
- System.arraycopy(signature, nextEntry, otsSig, 0, otsSigLength);
- nextEntry += otsSigLength;
-
- // compute public OTS key from the one-time signature
- otsPublicKey = otsVerify.Verify(message, otsSig);
-
- // test if OTSsignature is correct
- if (otsPublicKey == null)
- {
- System.err.println("OTS Public Key is null in GMSSSignature.verify");
- return false;
- }
-
- // get authentication path from the signature
- authPath = new byte[gmssPS.getHeightOfTrees()[j]][mdLength];
- for (int i = 0; i < authPath.length; i++)
- {
- System.arraycopy(signature, nextEntry, authPath[i], 0, mdLength);
- nextEntry = nextEntry + mdLength;
- }
-
- // compute the root of the subtree from the authentication path
- help = new byte[mdLength];
-
- help = otsPublicKey;
-
- int count = 1 << authPath.length;
- count = count + index;
-
- for (int i = 0; i < authPath.length; i++)
- {
- dest = new byte[mdLength << 1];
-
- if ((count % 2) == 0)
- {
- System.arraycopy(help, 0, dest, 0, mdLength);
- System.arraycopy(authPath[i], 0, dest, mdLength, mdLength);
- count = count / 2;
- }
- else
- {
- System.arraycopy(authPath[i], 0, dest, 0, mdLength);
- System.arraycopy(help, 0, dest, mdLength, help.length);
- count = (count - 1) / 2;
- }
- messDigestTrees.update(dest, 0, dest.length);
- help = new byte[messDigestTrees.getDigestSize()];
- messDigestTrees.doFinal(help, 0);
- }
- }
-
- // now help contains the root of the maintree
-
- // test if help is equal to the GMSS public key
- if (Arrays.areEqual(pubKeyBytes, help))
- {
- success = true;
- }
-
- return success;
- }
-
-
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSUtils.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSUtils.java
deleted file mode 100644
index 9d28951..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/GMSSUtils.java
+++ /dev/null
@@ -1,145 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import java.util.Enumeration;
-import java.util.Vector;
-
-import org.bouncycastle.util.Arrays;
-
-class GMSSUtils
-{
- static GMSSLeaf[] clone(GMSSLeaf[] data)
- {
- if (data == null)
- {
- return null;
- }
- GMSSLeaf[] copy = new GMSSLeaf[data.length];
-
- System.arraycopy(data, 0, copy, 0, data.length);
-
- return copy;
- }
-
- static GMSSRootCalc[] clone(GMSSRootCalc[] data)
- {
- if (data == null)
- {
- return null;
- }
- GMSSRootCalc[] copy = new GMSSRootCalc[data.length];
-
- System.arraycopy(data, 0, copy, 0, data.length);
-
- return copy;
- }
-
- static GMSSRootSig[] clone(GMSSRootSig[] data)
- {
- if (data == null)
- {
- return null;
- }
- GMSSRootSig[] copy = new GMSSRootSig[data.length];
-
- System.arraycopy(data, 0, copy, 0, data.length);
-
- return copy;
- }
-
- static byte[][] clone(byte[][] data)
- {
- if (data == null)
- {
- return null;
- }
- byte[][] copy = new byte[data.length][];
-
- for (int i = 0; i != data.length; i++)
- {
- copy[i] = Arrays.clone(data[i]);
- }
-
- return copy;
- }
-
- static byte[][][] clone(byte[][][] data)
- {
- if (data == null)
- {
- return null;
- }
- byte[][][] copy = new byte[data.length][][];
-
- for (int i = 0; i != data.length; i++)
- {
- copy[i] = clone(data[i]);
- }
-
- return copy;
- }
-
- static Treehash[] clone(Treehash[] data)
- {
- if (data == null)
- {
- return null;
- }
- Treehash[] copy = new Treehash[data.length];
-
- System.arraycopy(data, 0, copy, 0, data.length);
-
- return copy;
- }
-
- static Treehash[][] clone(Treehash[][] data)
- {
- if (data == null)
- {
- return null;
- }
- Treehash[][] copy = new Treehash[data.length][];
-
- for (int i = 0; i != data.length; i++)
- {
- copy[i] = clone(data[i]);
- }
-
- return copy;
- }
-
- static Vector[] clone(Vector[] data)
- {
- if (data == null)
- {
- return null;
- }
- Vector[] copy = new Vector[data.length];
-
- for (int i = 0; i != data.length; i++)
- {
- copy[i] = new Vector();
- for (Enumeration en = data[i].elements(); en.hasMoreElements();)
- {
- copy[i].addElement(en.nextElement());
- }
- }
-
- return copy;
- }
-
- static Vector[][] clone(Vector[][] data)
- {
- if (data == null)
- {
- return null;
- }
- Vector[][] copy = new Vector[data.length][];
-
- for (int i = 0; i != data.length; i++)
- {
- copy[i] = clone(data[i]);
- }
-
- return copy;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/Treehash.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/Treehash.java
deleted file mode 100644
index 797355c..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/Treehash.java
+++ /dev/null
@@ -1,525 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss;
-
-import java.util.Vector;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom;
-import org.bouncycastle.util.Integers;
-import org.bouncycastle.util.encoders.Hex;
-
-
-/**
- * This class implements a treehash instance for the Merkle tree traversal
- * algorithm. The first node of the stack is stored in this instance itself,
- * additional tail nodes are stored on a tailstack.
- */
-public class Treehash
-{
-
- /**
- * max height of current treehash instance.
- */
- private int maxHeight;
-
- /**
- * Vector element that stores the nodes on the stack
- */
- private Vector tailStack;
-
- /**
- * Vector element that stores the height of the nodes on the stack
- */
- private Vector heightOfNodes;
-
- /**
- * the first node is stored in the treehash instance itself, not on stack
- */
- private byte[] firstNode;
-
- /**
- * seedActive needed for the actual node
- */
- private byte[] seedActive;
-
- /**
- * the seed needed for the next re-initialization of the treehash instance
- */
- private byte[] seedNext;
-
- /**
- * number of nodes stored on the stack and belonging to this treehash
- * instance
- */
- private int tailLength;
-
- /**
- * the height in the tree of the first node stored in treehash
- */
- private int firstNodeHeight;
-
- /**
- * true if treehash instance was already initialized, false otherwise
- */
- private boolean isInitialized;
-
- /**
- * true if the first node's height equals the maxHeight of the treehash
- */
- private boolean isFinished;
-
- /**
- * true if the nextSeed has been initialized with index 3*2^h needed for the
- * seed scheduling
- */
- private boolean seedInitialized;
-
- /**
- * denotes the Message Digest used by the tree to create nodes
- */
- private Digest messDigestTree;
-
- /**
- * This constructor regenerates a prior treehash object
- *
- * @param name an array of strings, containing the name of the used hash
- * function and PRNG and the name of the corresponding provider
- * @param statByte status bytes
- * @param statInt status ints
- */
- public Treehash(Digest name, byte[][] statByte, int[] statInt)
- {
- this.messDigestTree = name;
-
- // decode statInt
- this.maxHeight = statInt[0];
- this.tailLength = statInt[1];
- this.firstNodeHeight = statInt[2];
-
- if (statInt[3] == 1)
- {
- this.isFinished = true;
- }
- else
- {
- this.isFinished = false;
- }
- if (statInt[4] == 1)
- {
- this.isInitialized = true;
- }
- else
- {
- this.isInitialized = false;
- }
- if (statInt[5] == 1)
- {
- this.seedInitialized = true;
- }
- else
- {
- this.seedInitialized = false;
- }
-
- this.heightOfNodes = new Vector();
- for (int i = 0; i < tailLength; i++)
- {
- this.heightOfNodes.addElement(Integers.valueOf(statInt[6 + i]));
- }
-
- // decode statByte
- this.firstNode = statByte[0];
- this.seedActive = statByte[1];
- this.seedNext = statByte[2];
-
- this.tailStack = new Vector();
- for (int i = 0; i < tailLength; i++)
- {
- this.tailStack.addElement(statByte[3 + i]);
- }
- }
-
- /**
- * Constructor
- *
- * @param tailStack a vector element where the stack nodes are stored
- * @param maxHeight maximal height of the treehash instance
- * @param digest an array of strings, containing the name of the used hash
- * function and PRNG and the name of the corresponding provider
- */
- public Treehash(Vector tailStack, int maxHeight, Digest digest)
- {
- this.tailStack = tailStack;
- this.maxHeight = maxHeight;
- this.firstNode = null;
- this.isInitialized = false;
- this.isFinished = false;
- this.seedInitialized = false;
- this.messDigestTree = digest;
-
- this.seedNext = new byte[messDigestTree.getDigestSize()];
- this.seedActive = new byte[messDigestTree.getDigestSize()];
- }
-
- /**
- * Method to initialize the seeds needed for the precomputation of right
- * nodes. Should be initialized with index 3*2^i for treehash_i
- *
- * @param seedIn
- */
- public void initializeSeed(byte[] seedIn)
- {
- System.arraycopy(seedIn, 0, this.seedNext, 0, this.messDigestTree
- .getDigestSize());
- this.seedInitialized = true;
- }
-
- /**
- * initializes the treehash instance. The seeds must already have been
- * initialized to work correctly.
- */
- public void initialize()
- {
- if (!this.seedInitialized)
- {
- System.err.println("Seed " + this.maxHeight + " not initialized");
- return;
- }
-
- this.heightOfNodes = new Vector();
- this.tailLength = 0;
- this.firstNode = null;
- this.firstNodeHeight = -1;
- this.isInitialized = true;
- System.arraycopy(this.seedNext, 0, this.seedActive, 0, messDigestTree
- .getDigestSize());
- }
-
- /**
- * Calculates one update of the treehash instance, i.e. creates a new leaf
- * and hashes if possible
- *
- * @param gmssRandom an instance of the PRNG
- * @param leaf The byte value of the leaf needed for the update
- */
- public void update(GMSSRandom gmssRandom, byte[] leaf)
- {
-
- if (this.isFinished)
- {
- System.err
- .println("No more update possible for treehash instance!");
- return;
- }
- if (!this.isInitialized)
- {
- System.err
- .println("Treehash instance not initialized before update");
- return;
- }
-
- byte[] help = new byte[this.messDigestTree.getDigestSize()];
- int helpHeight = -1;
-
- gmssRandom.nextSeed(this.seedActive);
-
- // if treehash gets first update
- if (this.firstNode == null)
- {
- this.firstNode = leaf;
- this.firstNodeHeight = 0;
- }
- else
- {
- // store the new node in help array, do not push it on the stack
- help = leaf;
- helpHeight = 0;
-
- // hash the nodes on the stack if possible
- while (this.tailLength > 0
- && helpHeight == ((Integer)heightOfNodes.lastElement())
- .intValue())
- {
- // put top element of the stack and help node in array
- // 'tobehashed'
- // and hash them together, put result again in help array
- byte[] toBeHashed = new byte[this.messDigestTree
- .getDigestSize() << 1];
-
- // pop element from stack
- System.arraycopy(this.tailStack.lastElement(), 0, toBeHashed,
- 0, this.messDigestTree.getDigestSize());
- this.tailStack.removeElementAt(this.tailStack.size() - 1);
- this.heightOfNodes
- .removeElementAt(this.heightOfNodes.size() - 1);
-
- System.arraycopy(help, 0, toBeHashed, this.messDigestTree
- .getDigestSize(), this.messDigestTree
- .getDigestSize());
- messDigestTree.update(toBeHashed, 0, toBeHashed.length);
- help = new byte[messDigestTree.getDigestSize()];
- messDigestTree.doFinal(help, 0);
-
- // increase help height, stack was reduced by one element
- helpHeight++;
- this.tailLength--;
- }
-
- // push the new node on the stack
- this.tailStack.addElement(help);
- this.heightOfNodes.addElement(Integers.valueOf(helpHeight));
- this.tailLength++;
-
- // finally check whether the top node on stack and the first node
- // in treehash have same height. If so hash them together
- // and store them in treehash
- if (((Integer)heightOfNodes.lastElement()).intValue() == this.firstNodeHeight)
- {
- byte[] toBeHashed = new byte[this.messDigestTree
- .getDigestSize() << 1];
- System.arraycopy(this.firstNode, 0, toBeHashed, 0,
- this.messDigestTree.getDigestSize());
-
- // pop element from tailStack and copy it into help2 array
- System.arraycopy(this.tailStack.lastElement(), 0, toBeHashed,
- this.messDigestTree.getDigestSize(),
- this.messDigestTree.getDigestSize());
- this.tailStack.removeElementAt(this.tailStack.size() - 1);
- this.heightOfNodes
- .removeElementAt(this.heightOfNodes.size() - 1);
-
- // store new element in firstNode, stack is then empty
- messDigestTree.update(toBeHashed, 0, toBeHashed.length);
- this.firstNode = new byte[messDigestTree.getDigestSize()];
- messDigestTree.doFinal(this.firstNode, 0);
- this.firstNodeHeight++;
-
- // empty the stack
- this.tailLength = 0;
- }
- }
-
- // check if treehash instance is completed
- if (this.firstNodeHeight == this.maxHeight)
- {
- this.isFinished = true;
- }
- }
-
- /**
- * Destroys a treehash instance after the top node was taken for
- * authentication path.
- */
- public void destroy()
- {
- this.isInitialized = false;
- this.isFinished = false;
- this.firstNode = null;
- this.tailLength = 0;
- this.firstNodeHeight = -1;
- }
-
- /**
- * Returns the height of the lowest node stored either in treehash or on the
- * stack. It must not be set to infinity (as mentioned in the paper) because
- * this cases are considered in the computeAuthPaths method of
- * JDKGMSSPrivateKey
- *
- * @return Height of the lowest node
- */
- public int getLowestNodeHeight()
- {
- if (this.firstNode == null)
- {
- return this.maxHeight;
- }
- else if (this.tailLength == 0)
- {
- return this.firstNodeHeight;
- }
- else
- {
- return Math.min(this.firstNodeHeight, ((Integer)heightOfNodes
- .lastElement()).intValue());
- }
- }
-
- /**
- * Returns the top node height
- *
- * @return Height of the first node, the top node
- */
- public int getFirstNodeHeight()
- {
- if (firstNode == null)
- {
- return maxHeight;
- }
- return firstNodeHeight;
- }
-
- /**
- * Method to check whether the instance has been initialized or not
- *
- * @return true if treehash was already initialized
- */
- public boolean wasInitialized()
- {
- return this.isInitialized;
- }
-
- /**
- * Method to check whether the instance has been finished or not
- *
- * @return true if treehash has reached its maximum height
- */
- public boolean wasFinished()
- {
- return this.isFinished;
- }
-
- /**
- * returns the first node stored in treehash instance itself
- *
- * @return the first node stored in treehash instance itself
- */
- public byte[] getFirstNode()
- {
- return this.firstNode;
- }
-
- /**
- * returns the active seed
- *
- * @return the active seed
- */
- public byte[] getSeedActive()
- {
- return this.seedActive;
- }
-
- /**
- * This method sets the first node stored in the treehash instance itself
- *
- * @param hash
- */
- public void setFirstNode(byte[] hash)
- {
- if (!this.isInitialized)
- {
- this.initialize();
- }
- this.firstNode = hash;
- this.firstNodeHeight = this.maxHeight;
- this.isFinished = true;
- }
-
- /**
- * updates the nextSeed of this treehash instance one step needed for the
- * schedulng of the seeds
- *
- * @param gmssRandom the prng used for the seeds
- */
- public void updateNextSeed(GMSSRandom gmssRandom)
- {
- gmssRandom.nextSeed(seedNext);
- }
-
- /**
- * Returns the tailstack
- *
- * @return the tailstack
- */
- public Vector getTailStack()
- {
- return this.tailStack;
- }
-
- /**
- * Returns the status byte array used by the GMSSPrivateKeyASN.1 class
- *
- * @return The status bytes
- */
- public byte[][] getStatByte()
- {
-
- byte[][] statByte = new byte[3 + tailLength][this.messDigestTree
- .getDigestSize()];
- statByte[0] = firstNode;
- statByte[1] = seedActive;
- statByte[2] = seedNext;
- for (int i = 0; i < tailLength; i++)
- {
- statByte[3 + i] = (byte[])tailStack.elementAt(i);
- }
- return statByte;
- }
-
- /**
- * Returns the status int array used by the GMSSPrivateKeyASN.1 class
- *
- * @return The status ints
- */
- public int[] getStatInt()
- {
-
- int[] statInt = new int[6 + tailLength];
- statInt[0] = maxHeight;
- statInt[1] = tailLength;
- statInt[2] = firstNodeHeight;
- if (this.isFinished)
- {
- statInt[3] = 1;
- }
- else
- {
- statInt[3] = 0;
- }
- if (this.isInitialized)
- {
- statInt[4] = 1;
- }
- else
- {
- statInt[4] = 0;
- }
- if (this.seedInitialized)
- {
- statInt[5] = 1;
- }
- else
- {
- statInt[5] = 0;
- }
- for (int i = 0; i < tailLength; i++)
- {
- statInt[6 + i] = ((Integer)heightOfNodes.elementAt(i)).intValue();
- }
- return statInt;
- }
-
- /**
- * returns a String representation of the treehash instance
- */
- public String toString()
- {
- String out = "Treehash : ";
- for (int i = 0; i < 6 + tailLength; i++)
- {
- out = out + this.getStatInt()[i] + " ";
- }
- for (int i = 0; i < 3 + tailLength; i++)
- {
- if (this.getStatByte()[i] != null)
- {
- out = out + new String(Hex.encode((this.getStatByte()[i]))) + " ";
- }
- else
- {
- out = out + "null ";
- }
- }
- out = out + " " + this.messDigestTree.getDigestSize();
- return out;
- }
-
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/GMSSRandom.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/GMSSRandom.java
deleted file mode 100644
index c6d3022..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/GMSSRandom.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss.util;
-
-import org.bouncycastle.crypto.Digest;
-
-/**
- * This class provides a PRNG for GMSS
- */
-public class GMSSRandom
-{
- /**
- * Hash function for the construction of the authentication trees
- */
- private Digest messDigestTree;
-
- /**
- * Constructor
- *
- * @param messDigestTree2
- */
- public GMSSRandom(Digest messDigestTree2)
- {
-
- this.messDigestTree = messDigestTree2;
- }
-
- /**
- * computes the next seed value, returns a random byte array and sets
- * outseed to the next value
- *
- * @param outseed byte array in which ((1 + SEEDin +RAND) mod 2^n) will be
- * stored
- * @return byte array of H(SEEDin)
- */
- public byte[] nextSeed(byte[] outseed)
- {
- // RAND <-- H(SEEDin)
- byte[] rand = new byte[outseed.length];
- messDigestTree.update(outseed, 0, outseed.length);
- rand = new byte[messDigestTree.getDigestSize()];
- messDigestTree.doFinal(rand, 0);
-
- // SEEDout <-- (1 + SEEDin +RAND) mod 2^n
- addByteArrays(outseed, rand);
- addOne(outseed);
-
- // System.arraycopy(outseed, 0, outseed, 0, outseed.length);
-
- return rand;
- }
-
- private void addByteArrays(byte[] a, byte[] b)
- {
-
- byte overflow = 0;
- int temp;
-
- for (int i = 0; i < a.length; i++)
- {
- temp = (0xFF & a[i]) + (0xFF & b[i]) + overflow;
- a[i] = (byte)temp;
- overflow = (byte)(temp >> 8);
- }
- }
-
- private void addOne(byte[] a)
- {
-
- byte overflow = 1;
- int temp;
-
- for (int i = 0; i < a.length; i++)
- {
- temp = (0xFF & a[i]) + overflow;
- a[i] = (byte)temp;
- overflow = (byte)(temp >> 8);
- }
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/GMSSUtil.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/GMSSUtil.java
deleted file mode 100644
index 80f8828..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/GMSSUtil.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss.util;
-
-/**
- * This class provides several methods that are required by the GMSS classes.
- */
-public class GMSSUtil
-{
- /**
- * Converts a 32 bit integer into a byte array beginning at
- * <code>offset</code> (little-endian representation)
- *
- * @param value the integer to convert
- */
- public byte[] intToBytesLittleEndian(int value)
- {
- byte[] bytes = new byte[4];
-
- bytes[0] = (byte)((value) & 0xff);
- bytes[1] = (byte)((value >> 8) & 0xff);
- bytes[2] = (byte)((value >> 16) & 0xff);
- bytes[3] = (byte)((value >> 24) & 0xff);
- return bytes;
- }
-
- /**
- * Converts a byte array beginning at <code>offset</code> into a 32 bit
- * integer (little-endian representation)
- *
- * @param bytes the byte array
- * @return The resulting integer
- */
- public int bytesToIntLittleEndian(byte[] bytes)
- {
-
- return ((bytes[0] & 0xff)) | ((bytes[1] & 0xff) << 8)
- | ((bytes[2] & 0xff) << 16) | ((bytes[3] & 0xff)) << 24;
- }
-
- /**
- * Converts a byte array beginning at <code>offset</code> into a 32 bit
- * integer (little-endian representation)
- *
- * @param bytes the byte array
- * @param offset the integer offset into the byte array
- * @return The resulting integer
- */
- public int bytesToIntLittleEndian(byte[] bytes, int offset)
- {
- return ((bytes[offset++] & 0xff)) | ((bytes[offset++] & 0xff) << 8)
- | ((bytes[offset++] & 0xff) << 16)
- | ((bytes[offset] & 0xff)) << 24;
- }
-
- /**
- * This method concatenates a 2-dimensional byte array into a 1-dimensional
- * byte array
- *
- * @param arraycp a 2-dimensional byte array.
- * @return 1-dimensional byte array with concatenated input array
- */
- public byte[] concatenateArray(byte[][] arraycp)
- {
- byte[] dest = new byte[arraycp.length * arraycp[0].length];
- int indx = 0;
- for (int i = 0; i < arraycp.length; i++)
- {
- System.arraycopy(arraycp[i], 0, dest, indx, arraycp[i].length);
- indx = indx + arraycp[i].length;
- }
- return dest;
- }
-
- /**
- * This method prints the values of a 2-dimensional byte array
- *
- * @param text a String
- * @param array a 2-dimensional byte array
- */
- public void printArray(String text, byte[][] array)
- {
- System.out.println(text);
- int counter = 0;
- for (int i = 0; i < array.length; i++)
- {
- for (int j = 0; j < array[0].length; j++)
- {
- System.out.println(counter + "; " + array[i][j]);
- counter++;
- }
- }
- }
-
- /**
- * This method prints the values of a 1-dimensional byte array
- *
- * @param text a String
- * @param array a 1-dimensional byte array.
- */
- public void printArray(String text, byte[] array)
- {
- System.out.println(text);
- int counter = 0;
- for (int i = 0; i < array.length; i++)
- {
- System.out.println(counter + "; " + array[i]);
- counter++;
- }
- }
-
- /**
- * This method tests if an integer is a power of 2.
- *
- * @param testValue an integer
- * @return <code>TRUE</code> if <code>testValue</code> is a power of 2,
- * <code>FALSE</code> otherwise
- */
- public boolean testPowerOfTwo(int testValue)
- {
- int a = 1;
- while (a < testValue)
- {
- a <<= 1;
- }
- if (testValue == a)
- {
- return true;
- }
-
- return false;
- }
-
- /**
- * This method returns the least integer that is greater or equal to the
- * logarithm to the base 2 of an integer <code>intValue</code>.
- *
- * @param intValue an integer
- * @return The least integer greater or equal to the logarithm to the base 2
- * of <code>intValue</code>
- */
- public int getLog(int intValue)
- {
- int log = 1;
- int i = 2;
- while (i < intValue)
- {
- i <<= 1;
- log++;
- }
- return log;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/WinternitzOTSVerify.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/WinternitzOTSVerify.java
deleted file mode 100644
index d012ce7..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/WinternitzOTSVerify.java
+++ /dev/null
@@ -1,344 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss.util;
-
-import org.bouncycastle.crypto.Digest;
-
-/**
- * This class implements signature verification of the Winternitz one-time
- * signature scheme (OTSS), described in C.Dods, N.P. Smart, and M. Stam, "Hash
- * Based Digital Signature Schemes", LNCS 3796, pages 96&#8211;115, 2005. The
- * class is used by the GMSS classes.
- */
-public class WinternitzOTSVerify
-{
-
- private Digest messDigestOTS;
-
- /**
- * The Winternitz parameter
- */
- private int w;
-
- /**
- * The constructor
- *
- * @param digest the name of the hash function used by the OTS and the provider
- * name of the hash function
- * @param w the Winternitz parameter
- */
- public WinternitzOTSVerify(Digest digest, int w)
- {
- this.w = w;
-
- messDigestOTS = digest;
- }
-
- /**
- * @return The length of the one-time signature
- */
- public int getSignatureLength()
- {
- int mdsize = messDigestOTS.getDigestSize();
- int size = ((mdsize << 3) + (w - 1)) / w;
- int logs = getLog((size << w) + 1);
- size += (logs + w - 1) / w;
-
- return mdsize * size;
- }
-
- /**
- * This method computes the public OTS key from the one-time signature of a
- * message. This is *NOT* a complete OTS signature verification, but it
- * suffices for usage with CMSS.
- *
- * @param message the message
- * @param signature the one-time signature
- * @return The public OTS key
- */
- public byte[] Verify(byte[] message, byte[] signature)
- {
-
- int mdsize = messDigestOTS.getDigestSize();
- byte[] hash = new byte[mdsize]; // hash of message m
-
- // create hash of message m
- messDigestOTS.update(message, 0, message.length);
- hash = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hash, 0);
-
- int size = ((mdsize << 3) + (w - 1)) / w;
- int logs = getLog((size << w) + 1);
- int keysize = size + (logs + w - 1) / w;
-
- int testKeySize = mdsize * keysize;
-
- if (testKeySize != signature.length)
- {
- return null;
- }
-
- byte[] testKey = new byte[testKeySize];
-
- int c = 0;
- int counter = 0;
- int test;
-
- if (8 % w == 0)
- {
- int d = 8 / w;
- int k = (1 << w) - 1;
- byte[] hlp = new byte[mdsize];
-
- // verify signature
- for (int i = 0; i < hash.length; i++)
- {
- for (int j = 0; j < d; j++)
- {
- test = hash[i] & k;
- c += test;
-
- System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize);
-
- while (test < k)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test++;
- }
-
- System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize);
- hash[i] = (byte)(hash[i] >>> w);
- counter++;
- }
- }
-
- c = (size << w) - c;
- for (int i = 0; i < logs; i += w)
- {
- test = c & k;
-
- System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize);
-
- while (test < k)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test++;
- }
- System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize);
- c >>>= w;
- counter++;
- }
- }
- else if (w < 8)
- {
- int d = mdsize / w;
- int k = (1 << w) - 1;
- byte[] hlp = new byte[mdsize];
- long big8;
- int ii = 0;
- // create signature
- // first d*w bytes of hash
- for (int i = 0; i < d; i++)
- {
- big8 = 0;
- for (int j = 0; j < w; j++)
- {
- big8 ^= (hash[ii] & 0xff) << (j << 3);
- ii++;
- }
- for (int j = 0; j < 8; j++)
- {
- test = (int)(big8 & k);
- c += test;
-
- System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize);
-
- while (test < k)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test++;
- }
-
- System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize);
- big8 >>>= w;
- counter++;
- }
- }
- // rest of hash
- d = mdsize % w;
- big8 = 0;
- for (int j = 0; j < d; j++)
- {
- big8 ^= (hash[ii] & 0xff) << (j << 3);
- ii++;
- }
- d <<= 3;
- for (int j = 0; j < d; j += w)
- {
- test = (int)(big8 & k);
- c += test;
-
- System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize);
-
- while (test < k)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test++;
- }
-
- System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize);
- big8 >>>= w;
- counter++;
- }
-
- // check bytes
- c = (size << w) - c;
- for (int i = 0; i < logs; i += w)
- {
- test = c & k;
-
- System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize);
-
- while (test < k)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test++;
- }
-
- System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize);
- c >>>= w;
- counter++;
- }
- }// end if(w<8)
- else if (w < 57)
- {
- int d = (mdsize << 3) - w;
- int k = (1 << w) - 1;
- byte[] hlp = new byte[mdsize];
- long big8, test8;
- int r = 0;
- int s, f, rest, ii;
- // create signature
- // first a*w bits of hash where a*w <= 8*mdsize < (a+1)*w
- while (r <= d)
- {
- s = r >>> 3;
- rest = r % 8;
- r += w;
- f = (r + 7) >>> 3;
- big8 = 0;
- ii = 0;
- for (int j = s; j < f; j++)
- {
- big8 ^= (hash[j] & 0xff) << (ii << 3);
- ii++;
- }
-
- big8 >>>= rest;
- test8 = (big8 & k);
- c += test8;
-
- System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize);
-
- while (test8 < k)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test8++;
- }
-
- System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize);
- counter++;
-
- }
- // rest of hash
- s = r >>> 3;
- if (s < mdsize)
- {
- rest = r % 8;
- big8 = 0;
- ii = 0;
- for (int j = s; j < mdsize; j++)
- {
- big8 ^= (hash[j] & 0xff) << (ii << 3);
- ii++;
- }
-
- big8 >>>= rest;
- test8 = (big8 & k);
- c += test8;
-
- System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize);
-
- while (test8 < k)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test8++;
- }
-
- System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize);
- counter++;
- }
- // check bytes
- c = (size << w) - c;
- for (int i = 0; i < logs; i += w)
- {
- test8 = (c & k);
-
- System.arraycopy(signature, counter * mdsize, hlp, 0, mdsize);
-
- while (test8 < k)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test8++;
- }
-
- System.arraycopy(hlp, 0, testKey, counter * mdsize, mdsize);
- c >>>= w;
- counter++;
- }
- }// end if(w<57)
-
- byte[] TKey = new byte[mdsize];
- messDigestOTS.update(testKey, 0, testKey.length);
- TKey = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(TKey, 0);
-
- return TKey;
-
- }
-
- /**
- * This method returns the least integer that is greater or equal to the
- * logarithm to the base 2 of an integer <code>intValue</code>.
- *
- * @param intValue an integer
- * @return The least integer greater or equal to the logarithm to the base
- * 256 of <code>intValue</code>
- */
- public int getLog(int intValue)
- {
- int log = 1;
- int i = 2;
- while (i < intValue)
- {
- i <<= 1;
- log++;
- }
- return log;
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/WinternitzOTSignature.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/WinternitzOTSignature.java
deleted file mode 100644
index 23bf3fa..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/gmss/util/WinternitzOTSignature.java
+++ /dev/null
@@ -1,404 +0,0 @@
-package org.bouncycastle.pqc.crypto.gmss.util;
-
-import org.bouncycastle.crypto.Digest;
-
-/**
- * This class implements key pair generation and signature generation of the
- * Winternitz one-time signature scheme (OTSS), described in C.Dods, N.P. Smart,
- * and M. Stam, "Hash Based Digital Signature Schemes", LNCS 3796, pages
- * 96&#8211;115, 2005. The class is used by the GMSS classes.
- */
-
-public class WinternitzOTSignature
-{
-
- /**
- * The hash function used by the OTS
- */
- private Digest messDigestOTS;
-
- /**
- * The length of the message digest and private key
- */
- private int mdsize, keysize;
-
- /**
- * An array of strings, containing the name of the used hash function, the
- * name of the PRGN and the names of the corresponding providers
- */
- // private String[] name = new String[2];
- /**
- * The private key
- */
- private byte[][] privateKeyOTS;
-
- /**
- * The Winternitz parameter
- */
- private int w;
-
- /**
- * The source of randomness for OTS private key generation
- */
- private GMSSRandom gmssRandom;
-
- /**
- * Sizes of the message and the checksum, both
- */
- private int messagesize, checksumsize;
-
- /**
- * The constructor generates an OTS key pair, using <code>seed0</code> and
- * the PRNG
- *
- * @param seed0 the seed for the PRGN
- * @param digest an array of strings, containing the name of the used hash
- * function, the name of the PRGN and the names of the
- * corresponding providers
- * @param w the Winternitz parameter
- */
- public WinternitzOTSignature(byte[] seed0, Digest digest, int w)
- {
- // this.name = name;
- this.w = w;
-
- messDigestOTS = digest;
-
- gmssRandom = new GMSSRandom(messDigestOTS);
-
- // calulate keysize for private and public key and also the help
- // array
-
- mdsize = messDigestOTS.getDigestSize();
- int mdsizeBit = mdsize << 3;
- messagesize = (int)Math.ceil((double)(mdsizeBit) / (double)w);
-
- checksumsize = getLog((messagesize << w) + 1);
-
- keysize = messagesize
- + (int)Math.ceil((double)checksumsize / (double)w);
-
- /*
- * mdsize = messDigestOTS.getDigestLength(); messagesize =
- * ((mdsize<<3)+(w-1))/w;
- *
- * checksumsize = getlog((messagesize<<w)+1);
- *
- * keysize = messagesize + (checksumsize+w-1)/w;
- */
- // define the private key messagesize
- privateKeyOTS = new byte[keysize][mdsize];
-
- // gmssRandom.setSeed(seed0);
- byte[] dummy = new byte[mdsize];
- System.arraycopy(seed0, 0, dummy, 0, dummy.length);
-
- // generate random bytes and
- // assign them to the private key
- for (int i = 0; i < keysize; i++)
- {
- privateKeyOTS[i] = gmssRandom.nextSeed(dummy);
- }
- }
-
- /**
- * @return The private OTS key
- */
- public byte[][] getPrivateKey()
- {
- return privateKeyOTS;
- }
-
- /**
- * @return The public OTS key
- */
- public byte[] getPublicKey()
- {
- byte[] helppubKey = new byte[keysize * mdsize];
-
- byte[] help = new byte[mdsize];
- int two_power_t = 1 << w;
-
- for (int i = 0; i < keysize; i++)
- {
- // hash w-1 time the private key and assign it to the public key
- messDigestOTS.update(privateKeyOTS[i], 0, privateKeyOTS[i].length);
- help = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(help, 0);
- for (int j = 2; j < two_power_t; j++)
- {
- messDigestOTS.update(help, 0, help.length);
- help = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(help, 0);
- }
- System.arraycopy(help, 0, helppubKey, mdsize * i, mdsize);
- }
-
- messDigestOTS.update(helppubKey, 0, helppubKey.length);
- byte[] tmp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(tmp, 0);
- return tmp;
- }
-
- /**
- * @return The one-time signature of the message, generated with the private
- * key
- */
- public byte[] getSignature(byte[] message)
- {
- byte[] sign = new byte[keysize * mdsize];
- // byte [] message; // message m as input
- byte[] hash = new byte[mdsize]; // hash of message m
- int counter = 0;
- int c = 0;
- int test = 0;
- // create hash of message m
- messDigestOTS.update(message, 0, message.length);
- hash = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hash, 0);
-
- if (8 % w == 0)
- {
- int d = 8 / w;
- int k = (1 << w) - 1;
- byte[] hlp = new byte[mdsize];
-
- // create signature
- for (int i = 0; i < hash.length; i++)
- {
- for (int j = 0; j < d; j++)
- {
- test = hash[i] & k;
- c += test;
-
- System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize);
-
- while (test > 0)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test--;
- }
- System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize);
- hash[i] = (byte)(hash[i] >>> w);
- counter++;
- }
- }
-
- c = (messagesize << w) - c;
- for (int i = 0; i < checksumsize; i += w)
- {
- test = c & k;
-
- System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize);
-
- while (test > 0)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test--;
- }
- System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize);
- c >>>= w;
- counter++;
- }
- }
- else if (w < 8)
- {
- int d = mdsize / w;
- int k = (1 << w) - 1;
- byte[] hlp = new byte[mdsize];
- long big8;
- int ii = 0;
- // create signature
- // first d*w bytes of hash
- for (int i = 0; i < d; i++)
- {
- big8 = 0;
- for (int j = 0; j < w; j++)
- {
- big8 ^= (hash[ii] & 0xff) << (j << 3);
- ii++;
- }
- for (int j = 0; j < 8; j++)
- {
- test = (int)(big8 & k);
- c += test;
-
- System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize);
-
- while (test > 0)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test--;
- }
- System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize);
- big8 >>>= w;
- counter++;
- }
- }
- // rest of hash
- d = mdsize % w;
- big8 = 0;
- for (int j = 0; j < d; j++)
- {
- big8 ^= (hash[ii] & 0xff) << (j << 3);
- ii++;
- }
- d <<= 3;
- for (int j = 0; j < d; j += w)
- {
- test = (int)(big8 & k);
- c += test;
-
- System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize);
-
- while (test > 0)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test--;
- }
- System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize);
- big8 >>>= w;
- counter++;
- }
-
- // check bytes
- c = (messagesize << w) - c;
- for (int i = 0; i < checksumsize; i += w)
- {
- test = c & k;
-
- System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize);
-
- while (test > 0)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test--;
- }
- System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize);
- c >>>= w;
- counter++;
- }
- }// end if(w<8)
- else if (w < 57)
- {
- int d = (mdsize << 3) - w;
- int k = (1 << w) - 1;
- byte[] hlp = new byte[mdsize];
- long big8, test8;
- int r = 0;
- int s, f, rest, ii;
- // create signature
- // first a*w bits of hash where a*w <= 8*mdsize < (a+1)*w
- while (r <= d)
- {
- s = r >>> 3;
- rest = r % 8;
- r += w;
- f = (r + 7) >>> 3;
- big8 = 0;
- ii = 0;
- for (int j = s; j < f; j++)
- {
- big8 ^= (hash[j] & 0xff) << (ii << 3);
- ii++;
- }
-
- big8 >>>= rest;
- test8 = (big8 & k);
- c += test8;
-
- System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize);
- while (test8 > 0)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test8--;
- }
- System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize);
- counter++;
-
- }
- // rest of hash
- s = r >>> 3;
- if (s < mdsize)
- {
- rest = r % 8;
- big8 = 0;
- ii = 0;
- for (int j = s; j < mdsize; j++)
- {
- big8 ^= (hash[j] & 0xff) << (ii << 3);
- ii++;
- }
-
- big8 >>>= rest;
- test8 = (big8 & k);
- c += test8;
-
- System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize);
- while (test8 > 0)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test8--;
- }
- System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize);
- counter++;
- }
- // check bytes
- c = (messagesize << w) - c;
- for (int i = 0; i < checksumsize; i += w)
- {
- test8 = (c & k);
-
- System.arraycopy(privateKeyOTS[counter], 0, hlp, 0, mdsize);
-
- while (test8 > 0)
- {
- messDigestOTS.update(hlp, 0, hlp.length);
- hlp = new byte[messDigestOTS.getDigestSize()];
- messDigestOTS.doFinal(hlp, 0);
- test8--;
- }
- System.arraycopy(hlp, 0, sign, counter * mdsize, mdsize);
- c >>>= w;
- counter++;
- }
- }// end if(w<57)
-
- return sign;
- }
-
- /**
- * This method returns the least integer that is greater or equal to the
- * logarithm to the base 2 of an integer <code>intValue</code>.
- *
- * @param intValue an integer
- * @return The least integer greater or equal to the logarithm to the base 2
- * of <code>intValue</code>
- */
- public int getLog(int intValue)
- {
- int log = 1;
- int i = 2;
- while (i < intValue)
- {
- i <<= 1;
- log++;
- }
- return log;
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/Conversions.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/Conversions.java
deleted file mode 100644
index 752d51c..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/Conversions.java
+++ /dev/null
@@ -1,236 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import java.math.BigInteger;
-
-import org.bouncycastle.pqc.math.linearalgebra.BigIntUtils;
-import org.bouncycastle.pqc.math.linearalgebra.GF2Vector;
-import org.bouncycastle.pqc.math.linearalgebra.IntegerFunctions;
-
-
-/**
- * Provides methods for CCA2-Secure Conversions of McEliece PKCS
- */
-final class Conversions
-{
- private static final BigInteger ZERO = BigInteger.valueOf(0);
- private static final BigInteger ONE = BigInteger.valueOf(1);
-
- /**
- * Default constructor (private).
- */
- private Conversions()
- {
- }
-
- /**
- * Encode a number between 0 and (n|t) (binomial coefficient) into a binary
- * vector of length n with weight t. The number is given as a byte array.
- * Only the first s bits are used, where s = floor[log(n|t)].
- *
- * @param n integer
- * @param t integer
- * @param m the message as a byte array
- * @return the encoded message as {@link GF2Vector}
- */
- public static GF2Vector encode(final int n, final int t, final byte[] m)
- {
- if (n < t)
- {
- throw new IllegalArgumentException("n < t");
- }
-
- // compute the binomial c = (n|t)
- BigInteger c = IntegerFunctions.binomial(n, t);
- // get the number encoded in m
- BigInteger i = new BigInteger(1, m);
- // compare
- if (i.compareTo(c) >= 0)
- {
- throw new IllegalArgumentException("Encoded number too large.");
- }
-
- GF2Vector result = new GF2Vector(n);
-
- int nn = n;
- int tt = t;
- for (int j = 0; j < n; j++)
- {
- c = c.multiply(BigInteger.valueOf(nn - tt)).divide(
- BigInteger.valueOf(nn));
- nn--;
- if (c.compareTo(i) <= 0)
- {
- result.setBit(j);
- i = i.subtract(c);
- tt--;
- if (nn == tt)
- {
- c = ONE;
- }
- else
- {
- c = (c.multiply(BigInteger.valueOf(tt + 1)))
- .divide(BigInteger.valueOf(nn - tt));
- }
- }
- }
-
- return result;
- }
-
- /**
- * Decode a binary vector of length n and weight t into a number between 0
- * and (n|t) (binomial coefficient). The result is given as a byte array of
- * length floor[(s+7)/8], where s = floor[log(n|t)].
- *
- * @param n integer
- * @param t integer
- * @param vec the binary vector
- * @return the decoded vector as a byte array
- */
- public static byte[] decode(int n, int t, GF2Vector vec)
- {
- if ((vec.getLength() != n) || (vec.getHammingWeight() != t))
- {
- throw new IllegalArgumentException(
- "vector has wrong length or hamming weight");
- }
- int[] vecArray = vec.getVecArray();
-
- BigInteger bc = IntegerFunctions.binomial(n, t);
- BigInteger d = ZERO;
- int nn = n;
- int tt = t;
- for (int i = 0; i < n; i++)
- {
- bc = bc.multiply(BigInteger.valueOf(nn - tt)).divide(
- BigInteger.valueOf(nn));
- nn--;
-
- int q = i >> 5;
- int e = vecArray[q] & (1 << (i & 0x1f));
- if (e != 0)
- {
- d = d.add(bc);
- tt--;
- if (nn == tt)
- {
- bc = ONE;
- }
- else
- {
- bc = bc.multiply(BigInteger.valueOf(tt + 1)).divide(
- BigInteger.valueOf(nn - tt));
- }
-
- }
- }
-
- return BigIntUtils.toMinimalByteArray(d);
- }
-
- /**
- * Compute a message representative of a message given as a vector of length
- * <tt>n</tt> bit and of hamming weight <tt>t</tt>. The result is a
- * byte array of length <tt>(s+7)/8</tt>, where
- * <tt>s = floor[log(n|t)]</tt>.
- *
- * @param n integer
- * @param t integer
- * @param m the message vector as a byte array
- * @return a message representative for <tt>m</tt>
- */
- public static byte[] signConversion(int n, int t, byte[] m)
- {
- if (n < t)
- {
- throw new IllegalArgumentException("n < t");
- }
-
- BigInteger bc = IntegerFunctions.binomial(n, t);
- // finds s = floor[log(binomial(n,t))]
- int s = bc.bitLength() - 1;
- // s = sq*8 + sr;
- int sq = s >> 3;
- int sr = s & 7;
- if (sr == 0)
- {
- sq--;
- sr = 8;
- }
-
- // n = nq*8+nr;
- int nq = n >> 3;
- int nr = n & 7;
- if (nr == 0)
- {
- nq--;
- nr = 8;
- }
- // take s bit from m
- byte[] data = new byte[nq + 1];
- if (m.length < data.length)
- {
- System.arraycopy(m, 0, data, 0, m.length);
- for (int i = m.length; i < data.length; i++)
- {
- data[i] = 0;
- }
- }
- else
- {
- System.arraycopy(m, 0, data, 0, nq);
- int h = (1 << nr) - 1;
- data[nq] = (byte)(h & m[nq]);
- }
-
- BigInteger d = ZERO;
- int nn = n;
- int tt = t;
- for (int i = 0; i < n; i++)
- {
- bc = (bc.multiply(new BigInteger(Integer.toString(nn - tt))))
- .divide(new BigInteger(Integer.toString(nn)));
- nn--;
-
- int q = i >>> 3;
- int r = i & 7;
- r = 1 << r;
- byte e = (byte)(r & data[q]);
- if (e != 0)
- {
- d = d.add(bc);
- tt--;
- if (nn == tt)
- {
- bc = ONE;
- }
- else
- {
- bc = (bc
- .multiply(new BigInteger(Integer.toString(tt + 1))))
- .divide(new BigInteger(Integer.toString(nn - tt)));
- }
- }
- }
-
- byte[] result = new byte[sq + 1];
- byte[] help = d.toByteArray();
- if (help.length < result.length)
- {
- System.arraycopy(help, 0, result, 0, help.length);
- for (int i = help.length; i < result.length; i++)
- {
- result[i] = 0;
- }
- }
- else
- {
- System.arraycopy(help, 0, result, 0, sq);
- result[sq] = (byte)(((1 << sr) - 1) & help[sq]);
- }
-
- return result;
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyGenerationParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyGenerationParameters.java
deleted file mode 100644
index dbd5a82..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyGenerationParameters.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.KeyGenerationParameters;
-
-public class McElieceCCA2KeyGenerationParameters
- extends KeyGenerationParameters
-{
- private McElieceCCA2Parameters params;
-
- public McElieceCCA2KeyGenerationParameters(
- SecureRandom random,
- McElieceCCA2Parameters params)
- {
- // XXX key size?
- super(random, 128);
- this.params = params;
- }
-
- public McElieceCCA2Parameters getParameters()
- {
- return params;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyPairGenerator.java
deleted file mode 100644
index 198e5d2..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyPairGenerator.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
-import org.bouncycastle.crypto.KeyGenerationParameters;
-import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix;
-import org.bouncycastle.pqc.math.linearalgebra.GF2mField;
-import org.bouncycastle.pqc.math.linearalgebra.GoppaCode;
-import org.bouncycastle.pqc.math.linearalgebra.GoppaCode.MaMaPe;
-import org.bouncycastle.pqc.math.linearalgebra.Permutation;
-import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM;
-import org.bouncycastle.pqc.math.linearalgebra.PolynomialRingGF2m;
-
-
-/**
- * This class implements key pair generation of the McEliece Public Key
- * Cryptosystem (McEliecePKC).
- */
-public class McElieceCCA2KeyPairGenerator
- implements AsymmetricCipherKeyPairGenerator
-{
-
-
- /**
- * The OID of the algorithm.
- */
- public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2";
-
- private McElieceCCA2KeyGenerationParameters mcElieceCCA2Params;
-
- // the extension degree of the finite field GF(2^m)
- private int m;
-
- // the length of the code
- private int n;
-
- // the error correction capability
- private int t;
-
- // the field polynomial
- private int fieldPoly;
-
- // the source of randomness
- private SecureRandom random;
-
- // flag indicating whether the key pair generator has been initialized
- private boolean initialized = false;
-
- /**
- * Default initialization of the key pair generator.
- */
- private void initializeDefault()
- {
- McElieceCCA2KeyGenerationParameters mcCCA2Params = new McElieceCCA2KeyGenerationParameters(new SecureRandom(), new McElieceCCA2Parameters());
- init(mcCCA2Params);
- }
-
- // TODO
- public void init(
- KeyGenerationParameters param)
- {
- this.mcElieceCCA2Params = (McElieceCCA2KeyGenerationParameters)param;
-
- // set source of randomness
- this.random = new SecureRandom();
-
- this.m = this.mcElieceCCA2Params.getParameters().getM();
- this.n = this.mcElieceCCA2Params.getParameters().getN();
- this.t = this.mcElieceCCA2Params.getParameters().getT();
- this.fieldPoly = this.mcElieceCCA2Params.getParameters().getFieldPoly();
- this.initialized = true;
- }
-
-
- public AsymmetricCipherKeyPair generateKeyPair()
- {
-
- if (!initialized)
- {
- initializeDefault();
- }
-
- // finite field GF(2^m)
- GF2mField field = new GF2mField(m, fieldPoly);
-
- // irreducible Goppa polynomial
- PolynomialGF2mSmallM gp = new PolynomialGF2mSmallM(field, t,
- PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL, random);
- PolynomialRingGF2m ring = new PolynomialRingGF2m(field, gp);
-
- // matrix for computing square roots in (GF(2^m))^t
- PolynomialGF2mSmallM[] qInv = ring.getSquareRootMatrix();
-
- // generate canonical check matrix
- GF2Matrix h = GoppaCode.createCanonicalCheckMatrix(field, gp);
-
- // compute short systematic form of check matrix
- MaMaPe mmp = GoppaCode.computeSystematicForm(h, random);
- GF2Matrix shortH = mmp.getSecondMatrix();
- Permutation p = mmp.getPermutation();
-
- // compute short systematic form of generator matrix
- GF2Matrix shortG = (GF2Matrix)shortH.computeTranspose();
-
- // obtain number of rows of G (= dimension of the code)
- int k = shortG.getNumRows();
-
- // generate keys
- McElieceCCA2PublicKeyParameters pubKey = new McElieceCCA2PublicKeyParameters(OID, n, t, shortG, mcElieceCCA2Params.getParameters());
- McElieceCCA2PrivateKeyParameters privKey = new McElieceCCA2PrivateKeyParameters(OID, n, k,
- field, gp, p, h, qInv, mcElieceCCA2Params.getParameters());
-
- // return key pair
- return new AsymmetricCipherKeyPair(pubKey, privKey);
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyParameters.java
deleted file mode 100644
index 8011476..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyParameters.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-
-
-public class McElieceCCA2KeyParameters
- extends AsymmetricKeyParameter
-{
- private McElieceCCA2Parameters params;
-
- public McElieceCCA2KeyParameters(
- boolean isPrivate,
- McElieceCCA2Parameters params)
- {
- super(isPrivate);
- this.params = params;
- }
-
-
- public McElieceCCA2Parameters getParameters()
- {
- return params;
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Parameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Parameters.java
deleted file mode 100644
index 7f80010..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Parameters.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA256Digest;
-
-/**
- * This class provides a specification for the parameters of the CCA2-secure
- * variants of the McEliece PKCS that are used with
- * {@link McElieceFujisakiCipher}, {@link McElieceKobaraImaiCipher}, and
- * {@link McEliecePointchevalCipher}.
- *
- * @see McElieceFujisakiCipher
- * @see McElieceKobaraImaiCipher
- * @see McEliecePointchevalCipher
- */
-public class McElieceCCA2Parameters
- extends McElieceParameters
-{
-
-
- public Digest digest;
-
-
- /**
- * Construct the default parameters.
- * The default message digest is SHA256.
- */
- public McElieceCCA2Parameters()
- {
- this.digest = new SHA256Digest();
- }
-
- public McElieceCCA2Parameters(int m, int t)
- {
- super(m, t);
- this.digest = new SHA256Digest();
- }
-
- public McElieceCCA2Parameters(Digest digest)
- {
- this.digest = digest;
- }
-
- public Digest getDigest()
- {
- return this.digest;
- }
-
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Primitives.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Primitives.java
deleted file mode 100644
index 726add1..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Primitives.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix;
-import org.bouncycastle.pqc.math.linearalgebra.GF2Vector;
-import org.bouncycastle.pqc.math.linearalgebra.GF2mField;
-import org.bouncycastle.pqc.math.linearalgebra.GoppaCode;
-import org.bouncycastle.pqc.math.linearalgebra.Permutation;
-import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM;
-import org.bouncycastle.pqc.math.linearalgebra.Vector;
-
-/**
- * Core operations for the CCA-secure variants of McEliece.
- */
-public final class McElieceCCA2Primitives
-{
-
- /**
- * Default constructor (private).
- */
- private McElieceCCA2Primitives()
- {
- }
-
- /**
- * The McEliece encryption primitive.
- *
- * @param pubKey the public key
- * @param m the message vector
- * @param z the error vector
- * @return <tt>m*G + z</tt>
- */
-
-
- public static GF2Vector encryptionPrimitive(McElieceCCA2PublicKeyParameters pubKey,
- GF2Vector m, GF2Vector z)
- {
-
- GF2Matrix matrixG = pubKey.getMatrixG();
- Vector mG = matrixG.leftMultiplyLeftCompactForm(m);
- return (GF2Vector)mG.add(z);
- }
-
- /**
- * The McEliece decryption primitive.
- *
- * @param privKey the private key
- * @param c the ciphertext vector <tt>c = m*G + z</tt>
- * @return the message vector <tt>m</tt> and the error vector <tt>z</tt>
- */
- public static GF2Vector[] decryptionPrimitive(
- McElieceCCA2PrivateKeyParameters privKey, GF2Vector c)
- {
-
- // obtain values from private key
- int k = privKey.getK();
- Permutation p = privKey.getP();
- GF2mField field = privKey.getField();
- PolynomialGF2mSmallM gp = privKey.getGoppaPoly();
- GF2Matrix h = privKey.getH();
- PolynomialGF2mSmallM[] q = privKey.getQInv();
-
- // compute inverse permutation P^-1
- Permutation pInv = p.computeInverse();
-
- // multiply c with permutation P^-1
- GF2Vector cPInv = (GF2Vector)c.multiply(pInv);
-
- // compute syndrome of cP^-1
- GF2Vector syndVec = (GF2Vector)h.rightMultiply(cPInv);
-
- // decode syndrome
- GF2Vector errors = GoppaCode.syndromeDecode(syndVec, field, gp, q);
- GF2Vector mG = (GF2Vector)cPInv.add(errors);
-
- // multiply codeword and error vector with P
- mG = (GF2Vector)mG.multiply(p);
- errors = (GF2Vector)errors.multiply(p);
-
- // extract plaintext vector (last k columns of mG)
- GF2Vector m = mG.extractRightVector(k);
-
- // return vectors
- return new GF2Vector[]{m, errors};
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PrivateKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PrivateKeyParameters.java
deleted file mode 100644
index 980ecdc..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PrivateKeyParameters.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-
-import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix;
-import org.bouncycastle.pqc.math.linearalgebra.GF2mField;
-import org.bouncycastle.pqc.math.linearalgebra.Permutation;
-import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM;
-
-/**
- *
- *
- *
- */
-public class McElieceCCA2PrivateKeyParameters
- extends McElieceCCA2KeyParameters
-{
-
- // the OID of the algorithm
- private String oid;
-
- // the length of the code
- private int n;
-
- // the dimension of the code
- private int k;
-
- // the finte field GF(2^m)
- private GF2mField field;
-
- // the irreducible Goppa polynomial
- private PolynomialGF2mSmallM goppaPoly;
-
- // the permutation
- private Permutation p;
-
- // the canonical check matrix
- private GF2Matrix h;
-
- // the matrix used to compute square roots in (GF(2^m))^t
- private PolynomialGF2mSmallM[] qInv;
-
- /**
- * Constructor.
- *
- * @param n the length of the code
- * @param k the dimension of the code
- * @param field the finite field <tt>GF(2<sup>m</sup>)</tt>
- * @param gp the irreducible Goppa polynomial
- * @param p the permutation
- * @param h the canonical check matrix
- * @param qInv the matrix used to compute square roots in
- * <tt>(GF(2^m))^t</tt>
- * @param params McElieceCCA2Parameters
- */
- public McElieceCCA2PrivateKeyParameters(String oid, int n, int k, GF2mField field,
- PolynomialGF2mSmallM gp, Permutation p, GF2Matrix h,
- PolynomialGF2mSmallM[] qInv, McElieceCCA2Parameters params)
- {
- super(true, params);
- this.oid = oid;
- this.n = n;
- this.k = k;
- this.field = field;
- this.goppaPoly = gp;
- this.p = p;
- this.h = h;
- this.qInv = qInv;
- }
-
- /**
- * Constructor used by the {@link McElieceKeyFactory}.
- *
- * @param n the length of the code
- * @param k the dimension of the code
- * @param encFieldPoly the encoded field polynomial defining the finite field
- * <tt>GF(2<sup>m</sup>)</tt>
- * @param encGoppaPoly the encoded irreducible Goppa polynomial
- * @param encP the encoded permutation
- * @param encH the encoded canonical check matrix
- * @param encQInv the encoded matrix used to compute square roots in
- * <tt>(GF(2^m))^t</tt>
- * @param params McElieceCCA2Parameters
- */
- public McElieceCCA2PrivateKeyParameters(String oid, int n, int k, byte[] encFieldPoly,
- byte[] encGoppaPoly, byte[] encP, byte[] encH, byte[][] encQInv, McElieceCCA2Parameters params)
- {
- super(true, params);
- this.oid = oid;
- this.n = n;
- this.k = k;
- field = new GF2mField(encFieldPoly);
- goppaPoly = new PolynomialGF2mSmallM(field, encGoppaPoly);
- p = new Permutation(encP);
- h = new GF2Matrix(encH);
- qInv = new PolynomialGF2mSmallM[encQInv.length];
- for (int i = 0; i < encQInv.length; i++)
- {
- qInv[i] = new PolynomialGF2mSmallM(field, encQInv[i]);
- }
- }
-
- /**
- * @return the length of the code
- */
- public int getN()
- {
- return n;
- }
-
- /**
- * @return the dimension of the code
- */
- public int getK()
- {
- return k;
- }
-
- /**
- * @return the degree of the Goppa polynomial (error correcting capability)
- */
- public int getT()
- {
- return goppaPoly.getDegree();
- }
-
- /**
- * @return the finite field
- */
- public GF2mField getField()
- {
- return field;
- }
-
- /**
- * @return the irreducible Goppa polynomial
- */
- public PolynomialGF2mSmallM getGoppaPoly()
- {
- return goppaPoly;
- }
-
- /**
- * @return the permutation P
- */
- public Permutation getP()
- {
- return p;
- }
-
- /**
- * @return the canonical check matrix H
- */
- public GF2Matrix getH()
- {
- return h;
- }
-
- /**
- * @return the matrix used to compute square roots in <tt>(GF(2^m))^t</tt>
- */
- public PolynomialGF2mSmallM[] getQInv()
- {
- return qInv;
- }
-
- public String getOIDString()
- {
- return oid;
-
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PublicKeyParameters.java
deleted file mode 100644
index e63377c..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PublicKeyParameters.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix;
-
-/**
- *
- *
- *
- */
-public class McElieceCCA2PublicKeyParameters
- extends McElieceCCA2KeyParameters
-{
-
- // the OID of the algorithm
- private String oid;
-
- // the length of the code
- private int n;
-
- // the error correction capability of the code
- private int t;
-
- // the generator matrix
- private GF2Matrix matrixG;
-
- /**
- * Constructor.
- *
- * @param n length of the code
- * @param t error correction capability
- * @param matrix generator matrix
- * @param params McElieceCCA2Parameters
- */
- public McElieceCCA2PublicKeyParameters(String oid, int n, int t, GF2Matrix matrix, McElieceCCA2Parameters params)
- {
- super(false, params);
- this.oid = oid;
- this.n = n;
- this.t = t;
- this.matrixG = new GF2Matrix(matrix);
- }
-
- /**
- * Constructor (used by {@link McElieceKeyFactory}).
- *
- * @param n length of the code
- * @param t error correction capability of the code
- * @param encMatrix encoded generator matrix
- * @param params McElieceCCA2Parameters
- */
- public McElieceCCA2PublicKeyParameters(String oid, int n, int t, byte[] encMatrix, McElieceCCA2Parameters params)
- {
- super(false, params);
- this.oid = oid;
- this.n = n;
- this.t = t;
- this.matrixG = new GF2Matrix(encMatrix);
- }
-
- /**
- * @return the length of the code
- */
- public int getN()
- {
- return n;
- }
-
- /**
- * @return the error correction capability of the code
- */
- public int getT()
- {
- return t;
- }
-
- /**
- * @return the generator matrix
- */
- public GF2Matrix getMatrixG()
- {
- return matrixG;
- }
-
- /**
- * @return the dimension of the code
- */
- public int getK()
- {
- return matrixG.getNumRows();
- }
-
- public String getOIDString()
- {
- return oid;
-
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiCipher.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiCipher.java
deleted file mode 100644
index c414540..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiCipher.java
+++ /dev/null
@@ -1,218 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA1Digest;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.crypto.prng.DigestRandomGenerator;
-import org.bouncycastle.pqc.crypto.MessageEncryptor;
-import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
-import org.bouncycastle.pqc.math.linearalgebra.GF2Vector;
-
-/**
- * This class implements the Fujisaki/Okamoto conversion of the McEliecePKCS.
- * Fujisaki and Okamoto propose hybrid encryption that merges a symmetric
- * encryption scheme which is secure in the find-guess model with an asymmetric
- * one-way encryption scheme which is sufficiently probabilistic to obtain a
- * public key cryptosystem which is CCA2-secure. For details, see D. Engelbert,
- * R. Overbeck, A. Schmidt, "A summary of the development of the McEliece
- * Cryptosystem", technical report.
- */
-public class McElieceFujisakiCipher
- implements MessageEncryptor
-{
-
-
- /**
- * The OID of the algorithm.
- */
- public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2.1";
-
- private static final String DEFAULT_PRNG_NAME = "SHA1PRNG";
-
- private Digest messDigest;
-
- private SecureRandom sr;
-
- /**
- * The McEliece main parameters
- */
- private int n, k, t;
-
- McElieceCCA2KeyParameters key;
-
-
- public void init(boolean forSigning,
- CipherParameters param)
- {
-
- if (forSigning)
- {
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)param;
-
- this.sr = rParam.getRandom();
- this.key = (McElieceCCA2PublicKeyParameters)rParam.getParameters();
- this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key);
-
- }
- else
- {
- this.sr = new SecureRandom();
- this.key = (McElieceCCA2PublicKeyParameters)param;
- this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key);
- }
- }
- else
- {
- this.key = (McElieceCCA2PrivateKeyParameters)param;
- this.initCipherDecrypt((McElieceCCA2PrivateKeyParameters)key);
- }
-
- }
-
-
- public int getKeySize(McElieceCCA2KeyParameters key)
- throws IllegalArgumentException
- {
-
- if (key instanceof McElieceCCA2PublicKeyParameters)
- {
- return ((McElieceCCA2PublicKeyParameters)key).getN();
-
- }
- if (key instanceof McElieceCCA2PrivateKeyParameters)
- {
- return ((McElieceCCA2PrivateKeyParameters)key).getN();
- }
- throw new IllegalArgumentException("unsupported type");
-
- }
-
-
- private void initCipherEncrypt(McElieceCCA2PublicKeyParameters pubKey)
- {
- this.sr = sr != null ? sr : new SecureRandom();
- this.messDigest = pubKey.getParameters().getDigest();
- n = pubKey.getN();
- k = pubKey.getK();
- t = pubKey.getT();
- }
-
-
- public void initCipherDecrypt(McElieceCCA2PrivateKeyParameters privKey)
- {
- this.messDigest = privKey.getParameters().getDigest();
- n = privKey.getN();
- t = privKey.getT();
- }
-
-
- public byte[] messageEncrypt(byte[] input)
- throws Exception
- {
-
- // generate random vector r of length k bits
- GF2Vector r = new GF2Vector(k, sr);
-
- // convert r to byte array
- byte[] rBytes = r.getEncoded();
-
- // compute (r||input)
- byte[] rm = ByteUtils.concatenate(rBytes, input);
-
- // compute H(r||input)
- messDigest.update(rm, 0, rm.length);
- byte[] hrm = new byte[messDigest.getDigestSize()];
- messDigest.doFinal(hrm, 0);
-
- // convert H(r||input) to error vector z
- GF2Vector z = Conversions.encode(n, t, hrm);
-
- // compute c1 = E(r, z)
- byte[] c1 = McElieceCCA2Primitives.encryptionPrimitive((McElieceCCA2PublicKeyParameters)key, r, z)
- .getEncoded();
-
- // get PRNG object
- DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest());
-
- // seed PRNG with r'
- sr0.addSeedMaterial(rBytes);
-
- // generate random c2
- byte[] c2 = new byte[input.length];
- sr0.nextBytes(c2);
-
- // XOR with input
- for (int i = 0; i < input.length; i++)
- {
- c2[i] ^= input[i];
- }
-
- // return (c1||c2)
- return ByteUtils.concatenate(c1, c2);
- }
-
- public byte[] messageDecrypt(byte[] input)
- throws Exception
- {
-
- int c1Len = (n + 7) >> 3;
- int c2Len = input.length - c1Len;
-
- // split ciphertext (c1||c2)
- byte[][] c1c2 = ByteUtils.split(input, c1Len);
- byte[] c1 = c1c2[0];
- byte[] c2 = c1c2[1];
-
- // decrypt c1 ...
- GF2Vector hrmVec = GF2Vector.OS2VP(n, c1);
- GF2Vector[] decC1 = McElieceCCA2Primitives.decryptionPrimitive((McElieceCCA2PrivateKeyParameters)key,
- hrmVec);
- byte[] rBytes = decC1[0].getEncoded();
- // ... and obtain error vector z
- GF2Vector z = decC1[1];
-
- // get PRNG object
- DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest());
-
- // seed PRNG with r'
- sr0.addSeedMaterial(rBytes);
-
- // generate random sequence
- byte[] mBytes = new byte[c2Len];
- sr0.nextBytes(mBytes);
-
- // XOR with c2 to obtain m
- for (int i = 0; i < c2Len; i++)
- {
- mBytes[i] ^= c2[i];
- }
-
- // compute H(r||m)
- byte[] rmBytes = ByteUtils.concatenate(rBytes, mBytes);
- byte[] hrm = new byte[messDigest.getDigestSize()];
- messDigest.update(rmBytes, 0, rmBytes.length);
- messDigest.doFinal(hrm, 0);
-
-
- // compute Conv(H(r||m))
- hrmVec = Conversions.encode(n, t, hrm);
-
- // check that Conv(H(m||r)) = z
- if (!hrmVec.equals(z))
- {
-
- throw new Exception("Bad Padding: invalid ciphertext");
-
- }
-
- // return plaintext m
- return mBytes;
- }
-
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiDigestCipher.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiDigestCipher.java
deleted file mode 100644
index 423e6ff..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiDigestCipher.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.MessageEncryptor;
-
-// TODO should implement some interface?
-public class McElieceFujisakiDigestCipher
-{
-
- private final Digest messDigest;
-
- private final MessageEncryptor mcElieceCCA2Cipher;
-
- private boolean forEncrypting;
-
-
- public McElieceFujisakiDigestCipher(MessageEncryptor mcElieceCCA2Cipher, Digest messDigest)
- {
- this.mcElieceCCA2Cipher = mcElieceCCA2Cipher;
- this.messDigest = messDigest;
- }
-
-
- public void init(boolean forEncrypting,
- CipherParameters param)
- {
-
- this.forEncrypting = forEncrypting;
- AsymmetricKeyParameter k;
-
- if (param instanceof ParametersWithRandom)
- {
- k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters();
- }
- else
- {
- k = (AsymmetricKeyParameter)param;
- }
-
- if (forEncrypting && k.isPrivate())
- {
- throw new IllegalArgumentException("Encrypting Requires Public Key.");
- }
-
- if (!forEncrypting && !k.isPrivate())
- {
- throw new IllegalArgumentException("Decrypting Requires Private Key.");
- }
-
- reset();
-
- mcElieceCCA2Cipher.init(forEncrypting, param);
- }
-
-
- public byte[] messageEncrypt()
- {
- if (!forEncrypting)
- {
- throw new IllegalStateException("McElieceFujisakiDigestCipher not initialised for encrypting.");
- }
-
- byte[] hash = new byte[messDigest.getDigestSize()];
- messDigest.doFinal(hash, 0);
- byte[] enc = null;
-
- try
- {
- enc = mcElieceCCA2Cipher.messageEncrypt(hash);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
-
- return enc;
- }
-
-
- public byte[] messageDecrypt(byte[] ciphertext)
- {
- byte[] output = null;
- if (forEncrypting)
- {
- throw new IllegalStateException("McElieceFujisakiDigestCipher not initialised for decrypting.");
- }
-
-
- try
- {
- output = mcElieceCCA2Cipher.messageDecrypt(ciphertext);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
-
- return output;
- }
-
-
- public void update(byte b)
- {
- messDigest.update(b);
-
- }
-
- public void update(byte[] in, int off, int len)
- {
- messDigest.update(in, off, len);
-
- }
-
-
- public void reset()
- {
- messDigest.reset();
-
- }
-
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyGenerationParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyGenerationParameters.java
deleted file mode 100644
index 1b1fa65..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyGenerationParameters.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.KeyGenerationParameters;
-
-public class McElieceKeyGenerationParameters
- extends KeyGenerationParameters
-{
- private McElieceParameters params;
-
- public McElieceKeyGenerationParameters(
- SecureRandom random,
- McElieceParameters params)
- {
- // XXX key size?
- super(random, 256);
- this.params = params;
- }
-
- public McElieceParameters getParameters()
- {
- return params;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java
deleted file mode 100644
index 6ad7fc2..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
-import org.bouncycastle.crypto.KeyGenerationParameters;
-import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix;
-import org.bouncycastle.pqc.math.linearalgebra.GF2mField;
-import org.bouncycastle.pqc.math.linearalgebra.GoppaCode;
-import org.bouncycastle.pqc.math.linearalgebra.GoppaCode.MaMaPe;
-import org.bouncycastle.pqc.math.linearalgebra.Permutation;
-import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM;
-import org.bouncycastle.pqc.math.linearalgebra.PolynomialRingGF2m;
-
-
-/**
- * This class implements key pair generation of the McEliece Public Key
- * Cryptosystem (McEliecePKC).
- */
-public class McElieceKeyPairGenerator
- implements AsymmetricCipherKeyPairGenerator
-{
-
-
- public McElieceKeyPairGenerator()
- {
-
- }
-
-
- /**
- * The OID of the algorithm.
- */
- private static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.1";
-
- private McElieceKeyGenerationParameters mcElieceParams;
-
- // the extension degree of the finite field GF(2^m)
- private int m;
-
- // the length of the code
- private int n;
-
- // the error correction capability
- private int t;
-
- // the field polynomial
- private int fieldPoly;
-
- // the source of randomness
- private SecureRandom random;
-
- // flag indicating whether the key pair generator has been initialized
- private boolean initialized = false;
-
-
- /**
- * Default initialization of the key pair generator.
- */
- private void initializeDefault()
- {
- McElieceKeyGenerationParameters mcParams = new McElieceKeyGenerationParameters(new SecureRandom(), new McElieceParameters());
- initialize(mcParams);
- }
-
- private void initialize(
- KeyGenerationParameters param)
- {
- this.mcElieceParams = (McElieceKeyGenerationParameters)param;
-
- // set source of randomness
- this.random = new SecureRandom();
-
- this.m = this.mcElieceParams.getParameters().getM();
- this.n = this.mcElieceParams.getParameters().getN();
- this.t = this.mcElieceParams.getParameters().getT();
- this.fieldPoly = this.mcElieceParams.getParameters().getFieldPoly();
- this.initialized = true;
- }
-
-
- private AsymmetricCipherKeyPair genKeyPair()
- {
-
- if (!initialized)
- {
- initializeDefault();
- }
-
- // finite field GF(2^m)
- GF2mField field = new GF2mField(m, fieldPoly);
-
- // irreducible Goppa polynomial
- PolynomialGF2mSmallM gp = new PolynomialGF2mSmallM(field, t,
- PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL, random);
- PolynomialRingGF2m ring = new PolynomialRingGF2m(field, gp);
-
- // matrix used to compute square roots in (GF(2^m))^t
- PolynomialGF2mSmallM[] sqRootMatrix = ring.getSquareRootMatrix();
-
- // generate canonical check matrix
- GF2Matrix h = GoppaCode.createCanonicalCheckMatrix(field, gp);
-
- // compute short systematic form of check matrix
- MaMaPe mmp = GoppaCode.computeSystematicForm(h, random);
- GF2Matrix shortH = mmp.getSecondMatrix();
- Permutation p1 = mmp.getPermutation();
-
- // compute short systematic form of generator matrix
- GF2Matrix shortG = (GF2Matrix)shortH.computeTranspose();
-
- // extend to full systematic form
- GF2Matrix gPrime = shortG.extendLeftCompactForm();
-
- // obtain number of rows of G (= dimension of the code)
- int k = shortG.getNumRows();
-
- // generate random invertible (k x k)-matrix S and its inverse S^-1
- GF2Matrix[] matrixSandInverse = GF2Matrix
- .createRandomRegularMatrixAndItsInverse(k, random);
-
- // generate random permutation P2
- Permutation p2 = new Permutation(n, random);
-
- // compute public matrix G=S*G'*P2
- GF2Matrix g = (GF2Matrix)matrixSandInverse[0].rightMultiply(gPrime);
- g = (GF2Matrix)g.rightMultiply(p2);
-
-
- // generate keys
- McEliecePublicKeyParameters pubKey = new McEliecePublicKeyParameters(OID, n, t, g, mcElieceParams.getParameters());
- McEliecePrivateKeyParameters privKey = new McEliecePrivateKeyParameters(OID, n, k,
- field, gp, matrixSandInverse[1], p1, p2, h, sqRootMatrix, mcElieceParams.getParameters());
-
- // return key pair
- return new AsymmetricCipherKeyPair(pubKey, privKey);
- }
-
- public void init(KeyGenerationParameters param)
- {
- this.initialize(param);
-
- }
-
- public AsymmetricCipherKeyPair generateKeyPair()
- {
- return genKeyPair();
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyParameters.java
deleted file mode 100644
index 007e743..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyParameters.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-
-
-public class McElieceKeyParameters
- extends AsymmetricKeyParameter
-{
- private McElieceParameters params;
-
- public McElieceKeyParameters(
- boolean isPrivate,
- McElieceParameters params)
- {
- super(isPrivate);
- this.params = params;
- }
-
-
- public McElieceParameters getParameters()
- {
- return params;
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiCipher.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiCipher.java
deleted file mode 100644
index fe3ebf9..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiCipher.java
+++ /dev/null
@@ -1,319 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA1Digest;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.crypto.prng.DigestRandomGenerator;
-import org.bouncycastle.pqc.crypto.MessageEncryptor;
-import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
-import org.bouncycastle.pqc.math.linearalgebra.GF2Vector;
-import org.bouncycastle.pqc.math.linearalgebra.IntegerFunctions;
-
-/**
- * This class implements the Kobara/Imai conversion of the McEliecePKCS. This is
- * a conversion of the McEliecePKCS which is CCA2-secure. For details, see D.
- * Engelbert, R. Overbeck, A. Schmidt, "A summary of the development of the
- * McEliece Cryptosystem", technical report.
- */
-public class McElieceKobaraImaiCipher
- implements MessageEncryptor
-{
-
- /**
- * The OID of the algorithm.
- */
- public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2.3";
-
- private static final String DEFAULT_PRNG_NAME = "SHA1PRNG";
-
- /**
- * A predetermined public constant.
- */
- public static final byte[] PUBLIC_CONSTANT = "a predetermined public constant"
- .getBytes();
-
-
- private Digest messDigest;
-
- private SecureRandom sr;
-
- McElieceCCA2KeyParameters key;
-
- /**
- * The McEliece main parameters
- */
- private int n, k, t;
-
-
- public void init(boolean forSigning,
- CipherParameters param)
- {
-
- if (forSigning)
- {
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)param;
-
- this.sr = rParam.getRandom();
- this.key = (McElieceCCA2PublicKeyParameters)rParam.getParameters();
- this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key);
-
- }
- else
- {
- this.sr = new SecureRandom();
- this.key = (McElieceCCA2PublicKeyParameters)param;
- this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key);
- }
- }
- else
- {
- this.key = (McElieceCCA2PrivateKeyParameters)param;
- this.initCipherDecrypt((McElieceCCA2PrivateKeyParameters)key);
- }
-
- }
-
- /**
- * Return the key size of the given key object.
- *
- * @param key the McElieceCCA2KeyParameters object
- * @return the key size of the given key object
- */
- public int getKeySize(McElieceCCA2KeyParameters key)
- {
- if (key instanceof McElieceCCA2PublicKeyParameters)
- {
- return ((McElieceCCA2PublicKeyParameters)key).getN();
-
- }
- if (key instanceof McElieceCCA2PrivateKeyParameters)
- {
- return ((McElieceCCA2PrivateKeyParameters)key).getN();
- }
- throw new IllegalArgumentException("unsupported type");
- }
-
- private void initCipherEncrypt(McElieceCCA2PublicKeyParameters pubKey)
- {
- this.messDigest = pubKey.getParameters().getDigest();
- n = pubKey.getN();
- k = pubKey.getK();
- t = pubKey.getT();
-
- }
-
- public void initCipherDecrypt(McElieceCCA2PrivateKeyParameters privKey)
- {
- this.messDigest = privKey.getParameters().getDigest();
- n = privKey.getN();
- k = privKey.getK();
- t = privKey.getT();
- }
-
- public byte[] messageEncrypt(byte[] input)
- throws Exception
- {
-
- int c2Len = messDigest.getDigestSize();
- int c4Len = k >> 3;
- int c5Len = (IntegerFunctions.binomial(n, t).bitLength() - 1) >> 3;
-
-
- int mLen = c4Len + c5Len - c2Len - PUBLIC_CONSTANT.length;
- if (input.length > mLen)
- {
- mLen = input.length;
- }
-
- int c1Len = mLen + PUBLIC_CONSTANT.length;
- int c6Len = c1Len + c2Len - c4Len - c5Len;
-
- // compute (m||const)
- byte[] mConst = new byte[c1Len];
- System.arraycopy(input, 0, mConst, 0, input.length);
- System.arraycopy(PUBLIC_CONSTANT, 0, mConst, mLen,
- PUBLIC_CONSTANT.length);
-
- // generate random r of length c2Len bytes
- byte[] r = new byte[c2Len];
- sr.nextBytes(r);
-
- // get PRNG object
- // get PRNG object
- DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest());
-
- // seed PRNG with r'
- sr0.addSeedMaterial(r);
-
- // generate random sequence ...
- byte[] c1 = new byte[c1Len];
- sr0.nextBytes(c1);
-
- // ... and XOR with (m||const) to obtain c1
- for (int i = c1Len - 1; i >= 0; i--)
- {
- c1[i] ^= mConst[i];
- }
-
- // compute H(c1) ...
- byte[] c2 = new byte[messDigest.getDigestSize()];
- messDigest.update(c1, 0, c1.length);
- messDigest.doFinal(c2, 0);
-
- // ... and XOR with r
- for (int i = c2Len - 1; i >= 0; i--)
- {
- c2[i] ^= r[i];
- }
-
- // compute (c2||c1)
- byte[] c2c1 = ByteUtils.concatenate(c2, c1);
-
- // split (c2||c1) into (c6||c5||c4), where c4Len is k/8 bytes, c5Len is
- // floor[log(n|t)]/8 bytes, and c6Len is c1Len+c2Len-c4Len-c5Len (may be
- // 0).
- byte[] c6 = new byte[0];
- if (c6Len > 0)
- {
- c6 = new byte[c6Len];
- System.arraycopy(c2c1, 0, c6, 0, c6Len);
- }
-
- byte[] c5 = new byte[c5Len];
- System.arraycopy(c2c1, c6Len, c5, 0, c5Len);
-
- byte[] c4 = new byte[c4Len];
- System.arraycopy(c2c1, c6Len + c5Len, c4, 0, c4Len);
-
- // convert c4 to vector over GF(2)
- GF2Vector c4Vec = GF2Vector.OS2VP(k, c4);
-
- // convert c5 to error vector z
- GF2Vector z = Conversions.encode(n, t, c5);
-
- // compute encC4 = E(c4, z)
- byte[] encC4 = McElieceCCA2Primitives.encryptionPrimitive((McElieceCCA2PublicKeyParameters)key,
- c4Vec, z).getEncoded();
-
- // if c6Len > 0
- if (c6Len > 0)
- {
- // return (c6||encC4)
- return ByteUtils.concatenate(c6, encC4);
- }
- // else, return encC4
- return encC4;
- }
-
-
- public byte[] messageDecrypt(byte[] input)
- throws Exception
- {
-
- int nDiv8 = n >> 3;
-
- if (input.length < nDiv8)
- {
- throw new Exception("Bad Padding: Ciphertext too short.");
- }
-
- int c2Len = messDigest.getDigestSize();
- int c4Len = k >> 3;
- int c6Len = input.length - nDiv8;
-
- // split cipher text (c6||encC4), where c6 may be empty
- byte[] c6, encC4;
- if (c6Len > 0)
- {
- byte[][] c6EncC4 = ByteUtils.split(input, c6Len);
- c6 = c6EncC4[0];
- encC4 = c6EncC4[1];
- }
- else
- {
- c6 = new byte[0];
- encC4 = input;
- }
-
- // convert encC4 into vector over GF(2)
- GF2Vector encC4Vec = GF2Vector.OS2VP(n, encC4);
-
- // decrypt encC4Vec to obtain c4 and error vector z
- GF2Vector[] c4z = McElieceCCA2Primitives.decryptionPrimitive((McElieceCCA2PrivateKeyParameters)key,
- encC4Vec);
- byte[] c4 = c4z[0].getEncoded();
- GF2Vector z = c4z[1];
-
- // if length of c4 is greater than c4Len (because of padding) ...
- if (c4.length > c4Len)
- {
- // ... truncate the padding bytes
- c4 = ByteUtils.subArray(c4, 0, c4Len);
- }
-
- // compute c5 = Conv^-1(z)
- byte[] c5 = Conversions.decode(n, t, z);
-
- // compute (c6||c5||c4)
- byte[] c6c5c4 = ByteUtils.concatenate(c6, c5);
- c6c5c4 = ByteUtils.concatenate(c6c5c4, c4);
-
- // split (c6||c5||c4) into (c2||c1), where c2Len = mdLen and c1Len =
- // input.length-c2Len bytes.
- int c1Len = c6c5c4.length - c2Len;
- byte[][] c2c1 = ByteUtils.split(c6c5c4, c2Len);
- byte[] c2 = c2c1[0];
- byte[] c1 = c2c1[1];
-
- // compute H(c1) ...
- byte[] rPrime = new byte[messDigest.getDigestSize()];
- messDigest.update(c1, 0, c1.length);
- messDigest.doFinal(rPrime, 0);
-
- // ... and XOR with c2 to obtain r'
- for (int i = c2Len - 1; i >= 0; i--)
- {
- rPrime[i] ^= c2[i];
- }
-
- // get PRNG object
- DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest());
-
- // seed PRNG with r'
- sr0.addSeedMaterial(rPrime);
-
- // generate random sequence R(r') ...
- byte[] mConstPrime = new byte[c1Len];
- sr0.nextBytes(mConstPrime);
-
- // ... and XOR with c1 to obtain (m||const')
- for (int i = c1Len - 1; i >= 0; i--)
- {
- mConstPrime[i] ^= c1[i];
- }
-
- if (mConstPrime.length < c1Len)
- {
- throw new Exception("Bad Padding: invalid ciphertext");
- }
-
- byte[][] temp = ByteUtils.split(mConstPrime, c1Len
- - PUBLIC_CONSTANT.length);
- byte[] mr = temp[0];
- byte[] constPrime = temp[1];
-
- if (!ByteUtils.equals(constPrime, PUBLIC_CONSTANT))
- {
- throw new Exception("Bad Padding: invalid ciphertext");
- }
-
- return mr;
- }
-
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiDigestCipher.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiDigestCipher.java
deleted file mode 100644
index 365f387..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiDigestCipher.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.MessageEncryptor;
-
-// TODO should implement some interface?
-public class McElieceKobaraImaiDigestCipher
-{
-
- private final Digest messDigest;
-
- private final MessageEncryptor mcElieceCCA2Cipher;
-
- private boolean forEncrypting;
-
-
- public McElieceKobaraImaiDigestCipher(MessageEncryptor mcElieceCCA2Cipher, Digest messDigest)
- {
- this.mcElieceCCA2Cipher = mcElieceCCA2Cipher;
- this.messDigest = messDigest;
- }
-
-
- public void init(boolean forEncrypting,
- CipherParameters param)
- {
-
- this.forEncrypting = forEncrypting;
- AsymmetricKeyParameter k;
-
- if (param instanceof ParametersWithRandom)
- {
- k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters();
- }
- else
- {
- k = (AsymmetricKeyParameter)param;
- }
-
- if (forEncrypting && k.isPrivate())
- {
- throw new IllegalArgumentException("Encrypting Requires Public Key.");
- }
-
- if (!forEncrypting && !k.isPrivate())
- {
- throw new IllegalArgumentException("Decrypting Requires Private Key.");
- }
-
- reset();
-
- mcElieceCCA2Cipher.init(forEncrypting, param);
- }
-
-
- public byte[] messageEncrypt()
- {
- if (!forEncrypting)
- {
- throw new IllegalStateException("McElieceKobaraImaiDigestCipher not initialised for encrypting.");
- }
-
- byte[] hash = new byte[messDigest.getDigestSize()];
- messDigest.doFinal(hash, 0);
- byte[] enc = null;
-
- try
- {
- enc = mcElieceCCA2Cipher.messageEncrypt(hash);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
-
- return enc;
- }
-
-
- public byte[] messageDecrypt(byte[] ciphertext)
- {
- byte[] output = null;
- if (forEncrypting)
- {
- throw new IllegalStateException("McElieceKobaraImaiDigestCipher not initialised for decrypting.");
- }
-
-
- try
- {
- output = mcElieceCCA2Cipher.messageDecrypt(ciphertext);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
-
- return output;
- }
-
-
- public void update(byte b)
- {
- messDigest.update(b);
-
- }
-
- public void update(byte[] in, int off, int len)
- {
- messDigest.update(in, off, len);
-
- }
-
-
- public void reset()
- {
- messDigest.reset();
-
- }
-
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSCipher.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSCipher.java
deleted file mode 100644
index b4eecfb..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSCipher.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.MessageEncryptor;
-import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix;
-import org.bouncycastle.pqc.math.linearalgebra.GF2Vector;
-import org.bouncycastle.pqc.math.linearalgebra.GF2mField;
-import org.bouncycastle.pqc.math.linearalgebra.GoppaCode;
-import org.bouncycastle.pqc.math.linearalgebra.Permutation;
-import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM;
-import org.bouncycastle.pqc.math.linearalgebra.Vector;
-
-/**
- * This class implements the McEliece Public Key cryptosystem (McEliecePKCS). It
- * was first described in R.J. McEliece, "A public key cryptosystem based on
- * algebraic coding theory", DSN progress report, 42-44:114-116, 1978. The
- * McEliecePKCS is the first cryptosystem which is based on error correcting
- * codes. The trapdoor for the McEliece cryptosystem using Goppa codes is the
- * knowledge of the Goppa polynomial used to generate the code.
- */
-public class McEliecePKCSCipher
- implements MessageEncryptor
-{
-
- /**
- * The OID of the algorithm.
- */
- public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.1";
-
-
- // the source of randomness
- private SecureRandom sr;
-
- // the McEliece main parameters
- private int n, k, t;
-
- // The maximum number of bytes the cipher can decrypt
- public int maxPlainTextSize;
-
- // The maximum number of bytes the cipher can encrypt
- public int cipherTextSize;
-
- McElieceKeyParameters key;
-
-
- public void init(boolean forSigning,
- CipherParameters param)
- {
-
- if (forSigning)
- {
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)param;
-
- this.sr = rParam.getRandom();
- this.key = (McEliecePublicKeyParameters)rParam.getParameters();
- this.initCipherEncrypt((McEliecePublicKeyParameters)key);
-
- }
- else
- {
- this.sr = new SecureRandom();
- this.key = (McEliecePublicKeyParameters)param;
- this.initCipherEncrypt((McEliecePublicKeyParameters)key);
- }
- }
- else
- {
- this.key = (McEliecePrivateKeyParameters)param;
- this.initCipherDecrypt((McEliecePrivateKeyParameters)key);
- }
-
- }
-
-
- /**
- * Return the key size of the given key object.
- *
- * @param key the McElieceKeyParameters object
- * @return the keysize of the given key object
- */
-
- public int getKeySize(McElieceKeyParameters key)
- {
-
- if (key instanceof McEliecePublicKeyParameters)
- {
- return ((McEliecePublicKeyParameters)key).getN();
-
- }
- if (key instanceof McEliecePrivateKeyParameters)
- {
- return ((McEliecePrivateKeyParameters)key).getN();
- }
- throw new IllegalArgumentException("unsupported type");
-
- }
-
-
- public void initCipherEncrypt(McEliecePublicKeyParameters pubKey)
- {
- this.sr = sr != null ? sr : new SecureRandom();
- n = pubKey.getN();
- k = pubKey.getK();
- t = pubKey.getT();
- cipherTextSize = n >> 3;
- maxPlainTextSize = (k >> 3);
- }
-
-
- public void initCipherDecrypt(McEliecePrivateKeyParameters privKey)
- {
- n = privKey.getN();
- k = privKey.getK();
-
- maxPlainTextSize = (k >> 3);
- cipherTextSize = n >> 3;
- }
-
- /**
- * Encrypt a plain text.
- *
- * @param input the plain text
- * @return the cipher text
- */
- public byte[] messageEncrypt(byte[] input)
- {
- GF2Vector m = computeMessageRepresentative(input);
- GF2Vector z = new GF2Vector(n, t, sr);
-
- GF2Matrix g = ((McEliecePublicKeyParameters)key).getG();
- Vector mG = g.leftMultiply(m);
- GF2Vector mGZ = (GF2Vector)mG.add(z);
-
- return mGZ.getEncoded();
- }
-
- private GF2Vector computeMessageRepresentative(byte[] input)
- {
- byte[] data = new byte[maxPlainTextSize + ((k & 0x07) != 0 ? 1 : 0)];
- System.arraycopy(input, 0, data, 0, input.length);
- data[input.length] = 0x01;
- return GF2Vector.OS2VP(k, data);
- }
-
- /**
- * Decrypt a cipher text.
- *
- * @param input the cipher text
- * @return the plain text
- * @throws Exception if the cipher text is invalid.
- */
- public byte[] messageDecrypt(byte[] input)
- throws Exception
- {
- GF2Vector vec = GF2Vector.OS2VP(n, input);
- McEliecePrivateKeyParameters privKey = (McEliecePrivateKeyParameters)key;
- GF2mField field = privKey.getField();
- PolynomialGF2mSmallM gp = privKey.getGoppaPoly();
- GF2Matrix sInv = privKey.getSInv();
- Permutation p1 = privKey.getP1();
- Permutation p2 = privKey.getP2();
- GF2Matrix h = privKey.getH();
- PolynomialGF2mSmallM[] qInv = privKey.getQInv();
-
- // compute permutation P = P1 * P2
- Permutation p = p1.rightMultiply(p2);
-
- // compute P^-1
- Permutation pInv = p.computeInverse();
-
- // compute c P^-1
- GF2Vector cPInv = (GF2Vector)vec.multiply(pInv);
-
- // compute syndrome of c P^-1
- GF2Vector syndrome = (GF2Vector)h.rightMultiply(cPInv);
-
- // decode syndrome
- GF2Vector z = GoppaCode.syndromeDecode(syndrome, field, gp, qInv);
- GF2Vector mSG = (GF2Vector)cPInv.add(z);
-
- // multiply codeword with P1 and error vector with P
- mSG = (GF2Vector)mSG.multiply(p1);
- z = (GF2Vector)z.multiply(p);
-
- // extract mS (last k columns of mSG)
- GF2Vector mS = mSG.extractRightVector(k);
-
- // compute plaintext vector
- GF2Vector mVec = (GF2Vector)sInv.leftMultiply(mS);
-
- // compute and return plaintext
- return computeMessage(mVec);
- }
-
- private byte[] computeMessage(GF2Vector mr)
- throws Exception
- {
- byte[] mrBytes = mr.getEncoded();
- // find first non-zero byte
- int index;
- for (index = mrBytes.length - 1; index >= 0 && mrBytes[index] == 0; index--)
- {
- ;
- }
-
- // check if padding byte is valid
- if (index<0 || mrBytes[index] != 0x01)
- {
- throw new Exception("Bad Padding: invalid ciphertext");
- }
-
- // extract and return message
- byte[] mBytes = new byte[index];
- System.arraycopy(mrBytes, 0, mBytes, 0, index);
- return mBytes;
- }
-
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSDigestCipher.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSDigestCipher.java
deleted file mode 100644
index d8e6ba2..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSDigestCipher.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.MessageEncryptor;
-
-// TODO should implement some interface?
-public class McEliecePKCSDigestCipher
-{
-
- private final Digest messDigest;
-
- private final MessageEncryptor mcElieceCipher;
-
- private boolean forEncrypting;
-
-
- public McEliecePKCSDigestCipher(MessageEncryptor mcElieceCipher, Digest messDigest)
- {
- this.mcElieceCipher = mcElieceCipher;
- this.messDigest = messDigest;
- }
-
-
- public void init(boolean forEncrypting,
- CipherParameters param)
- {
-
- this.forEncrypting = forEncrypting;
- AsymmetricKeyParameter k;
-
- if (param instanceof ParametersWithRandom)
- {
- k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters();
- }
- else
- {
- k = (AsymmetricKeyParameter)param;
- }
-
- if (forEncrypting && k.isPrivate())
- {
- throw new IllegalArgumentException("Encrypting Requires Public Key.");
- }
-
- if (!forEncrypting && !k.isPrivate())
- {
- throw new IllegalArgumentException("Decrypting Requires Private Key.");
- }
-
- reset();
-
- mcElieceCipher.init(forEncrypting, param);
- }
-
-
- public byte[] messageEncrypt()
- {
- if (!forEncrypting)
- {
- throw new IllegalStateException("McEliecePKCSDigestCipher not initialised for encrypting.");
- }
-
- byte[] hash = new byte[messDigest.getDigestSize()];
- messDigest.doFinal(hash, 0);
- byte[] enc = null;
-
- try
- {
- enc = mcElieceCipher.messageEncrypt(hash);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
-
- return enc;
- }
-
-
- public byte[] messageDecrypt(byte[] ciphertext)
- {
- byte[] output = null;
- if (forEncrypting)
- {
- throw new IllegalStateException("McEliecePKCSDigestCipher not initialised for decrypting.");
- }
-
-
- try
- {
- output = mcElieceCipher.messageDecrypt(ciphertext);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
-
- return output;
- }
-
-
- public void update(byte b)
- {
- messDigest.update(b);
-
- }
-
- public void update(byte[] in, int off, int len)
- {
- messDigest.update(in, off, len);
-
- }
-
-
- public void reset()
- {
- messDigest.reset();
-
- }
-
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceParameters.java
deleted file mode 100644
index e90c784..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceParameters.java
+++ /dev/null
@@ -1,181 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.pqc.math.linearalgebra.PolynomialRingGF2;
-
-public class McElieceParameters
- implements CipherParameters
-{
-
- /**
- * The default extension degree
- */
- public static final int DEFAULT_M = 11;
-
- /**
- * The default error correcting capability.
- */
- public static final int DEFAULT_T = 50;
-
- /**
- * extension degree of the finite field GF(2^m)
- */
- private int m;
-
- /**
- * error correction capability of the code
- */
- private int t;
-
- /**
- * length of the code
- */
- private int n;
-
- /**
- * the field polynomial
- */
- private int fieldPoly;
-
- /**
- * Constructor. Set the default parameters: extension degree.
- */
- public McElieceParameters()
- {
- this(DEFAULT_M, DEFAULT_T);
- }
-
- /**
- * Constructor.
- *
- * @param keysize the length of a Goppa code
- * @throws IllegalArgumentException if <tt>keysize &lt; 1</tt>.
- */
- public McElieceParameters(int keysize)
- throws IllegalArgumentException
- {
- if (keysize < 1)
- {
- throw new IllegalArgumentException("key size must be positive");
- }
- m = 0;
- n = 1;
- while (n < keysize)
- {
- n <<= 1;
- m++;
- }
- t = n >>> 1;
- t /= m;
- fieldPoly = PolynomialRingGF2.getIrreduciblePolynomial(m);
- }
-
- /**
- * Constructor.
- *
- * @param m degree of the finite field GF(2^m)
- * @param t error correction capability of the code
- * @throws IllegalArgumentException if <tt>m &lt; 1</tt> or <tt>m &gt; 32</tt> or
- * <tt>t &lt; 0</tt> or <tt>t &gt; n</tt>.
- */
- public McElieceParameters(int m, int t)
- throws IllegalArgumentException
- {
- if (m < 1)
- {
- throw new IllegalArgumentException("m must be positive");
- }
- if (m > 32)
- {
- throw new IllegalArgumentException("m is too large");
- }
- this.m = m;
- n = 1 << m;
- if (t < 0)
- {
- throw new IllegalArgumentException("t must be positive");
- }
- if (t > n)
- {
- throw new IllegalArgumentException("t must be less than n = 2^m");
- }
- this.t = t;
- fieldPoly = PolynomialRingGF2.getIrreduciblePolynomial(m);
- }
-
- /**
- * Constructor.
- *
- * @param m degree of the finite field GF(2^m)
- * @param t error correction capability of the code
- * @param poly the field polynomial
- * @throws IllegalArgumentException if <tt>m &lt; 1</tt> or <tt>m &gt; 32</tt> or
- * <tt>t &lt; 0</tt> or <tt>t &gt; n</tt> or
- * <tt>poly</tt> is not an irreducible field polynomial.
- */
- public McElieceParameters(int m, int t, int poly)
- throws IllegalArgumentException
- {
- this.m = m;
- if (m < 1)
- {
- throw new IllegalArgumentException("m must be positive");
- }
- if (m > 32)
- {
- throw new IllegalArgumentException(" m is too large");
- }
- this.n = 1 << m;
- this.t = t;
- if (t < 0)
- {
- throw new IllegalArgumentException("t must be positive");
- }
- if (t > n)
- {
- throw new IllegalArgumentException("t must be less than n = 2^m");
- }
- if ((PolynomialRingGF2.degree(poly) == m)
- && (PolynomialRingGF2.isIrreducible(poly)))
- {
- this.fieldPoly = poly;
- }
- else
- {
- throw new IllegalArgumentException(
- "polynomial is not a field polynomial for GF(2^m)");
- }
- }
-
- /**
- * @return the extension degree of the finite field GF(2^m)
- */
- public int getM()
- {
- return m;
- }
-
- /**
- * @return the length of the code
- */
- public int getN()
- {
- return n;
- }
-
- /**
- * @return the error correction capability of the code
- */
- public int getT()
- {
- return t;
- }
-
- /**
- * @return the field polynomial
- */
- public int getFieldPoly()
- {
- return fieldPoly;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalCipher.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalCipher.java
deleted file mode 100644
index 854d79e..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalCipher.java
+++ /dev/null
@@ -1,241 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA1Digest;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.crypto.prng.DigestRandomGenerator;
-import org.bouncycastle.pqc.crypto.MessageEncryptor;
-import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
-import org.bouncycastle.pqc.math.linearalgebra.GF2Vector;
-
-/**
- * This class implements the Pointcheval conversion of the McEliecePKCS.
- * Pointcheval presents a generic technique to make a CCA2-secure cryptosystem
- * from any partially trapdoor one-way function in the random oracle model. For
- * details, see D. Engelbert, R. Overbeck, A. Schmidt, "A summary of the
- * development of the McEliece Cryptosystem", technical report.
- */
-public class McEliecePointchevalCipher
- implements MessageEncryptor
-{
-
-
- /**
- * The OID of the algorithm.
- */
- public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2.2";
-
- private Digest messDigest;
-
- private SecureRandom sr;
-
- /**
- * The McEliece main parameters
- */
- private int n, k, t;
-
- McElieceCCA2KeyParameters key;
-
- public void init(boolean forSigning,
- CipherParameters param)
- {
-
- if (forSigning)
- {
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)param;
-
- this.sr = rParam.getRandom();
- this.key = (McElieceCCA2PublicKeyParameters)rParam.getParameters();
- this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key);
-
- }
- else
- {
- this.sr = new SecureRandom();
- this.key = (McElieceCCA2PublicKeyParameters)param;
- this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key);
- }
- }
- else
- {
- this.key = (McElieceCCA2PrivateKeyParameters)param;
- this.initCipherDecrypt((McElieceCCA2PrivateKeyParameters)key);
- }
-
- }
-
- /**
- * Return the key size of the given key object.
- *
- * @param key the McElieceCCA2KeyParameters object
- * @return the key size of the given key object
- * @throws IllegalArgumentException if the key is invalid
- */
- public int getKeySize(McElieceCCA2KeyParameters key)
- throws IllegalArgumentException
- {
-
- if (key instanceof McElieceCCA2PublicKeyParameters)
- {
- return ((McElieceCCA2PublicKeyParameters)key).getN();
-
- }
- if (key instanceof McElieceCCA2PrivateKeyParameters)
- {
- return ((McElieceCCA2PrivateKeyParameters)key).getN();
- }
- throw new IllegalArgumentException("unsupported type");
-
- }
-
-
- protected int decryptOutputSize(int inLen)
- {
- return 0;
- }
-
- protected int encryptOutputSize(int inLen)
- {
- return 0;
- }
-
-
- public void initCipherEncrypt(McElieceCCA2PublicKeyParameters pubKey)
- {
- this.sr = sr != null ? sr : new SecureRandom();
- this.messDigest = pubKey.getParameters().getDigest();
- n = pubKey.getN();
- k = pubKey.getK();
- t = pubKey.getT();
- }
-
- public void initCipherDecrypt(McElieceCCA2PrivateKeyParameters privKey)
- {
- this.messDigest = privKey.getParameters().getDigest();
- n = privKey.getN();
- k = privKey.getK();
- t = privKey.getT();
- }
-
- public byte[] messageEncrypt(byte[] input)
- throws Exception
- {
-
- int kDiv8 = k >> 3;
-
- // generate random r of length k div 8 bytes
- byte[] r = new byte[kDiv8];
- sr.nextBytes(r);
-
- // generate random vector r' of length k bits
- GF2Vector rPrime = new GF2Vector(k, sr);
-
- // convert r' to byte array
- byte[] rPrimeBytes = rPrime.getEncoded();
-
- // compute (input||r)
- byte[] mr = ByteUtils.concatenate(input, r);
-
- // compute H(input||r)
- messDigest.update(mr, 0, mr.length);
- byte[] hmr = new byte[messDigest.getDigestSize()];
- messDigest.doFinal(hmr, 0);
-
-
- // convert H(input||r) to error vector z
- GF2Vector z = Conversions.encode(n, t, hmr);
-
- // compute c1 = E(rPrime, z)
- byte[] c1 = McElieceCCA2Primitives.encryptionPrimitive((McElieceCCA2PublicKeyParameters)key, rPrime,
- z).getEncoded();
-
- // get PRNG object
- DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest());
-
- // seed PRNG with r'
- sr0.addSeedMaterial(rPrimeBytes);
-
- // generate random c2
- byte[] c2 = new byte[input.length + kDiv8];
- sr0.nextBytes(c2);
-
- // XOR with input
- for (int i = 0; i < input.length; i++)
- {
- c2[i] ^= input[i];
- }
- // XOR with r
- for (int i = 0; i < kDiv8; i++)
- {
- c2[input.length + i] ^= r[i];
- }
-
- // return (c1||c2)
- return ByteUtils.concatenate(c1, c2);
- }
-
- public byte[] messageDecrypt(byte[] input)
- throws Exception
- {
-
- int c1Len = (n + 7) >> 3;
- int c2Len = input.length - c1Len;
-
- // split cipher text (c1||c2)
- byte[][] c1c2 = ByteUtils.split(input, c1Len);
- byte[] c1 = c1c2[0];
- byte[] c2 = c1c2[1];
-
- // decrypt c1 ...
- GF2Vector c1Vec = GF2Vector.OS2VP(n, c1);
- GF2Vector[] c1Dec = McElieceCCA2Primitives.decryptionPrimitive((McElieceCCA2PrivateKeyParameters)key,
- c1Vec);
- byte[] rPrimeBytes = c1Dec[0].getEncoded();
- // ... and obtain error vector z
- GF2Vector z = c1Dec[1];
-
- // get PRNG object
- DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest());
-
- // seed PRNG with r'
- sr0.addSeedMaterial(rPrimeBytes);
-
- // generate random sequence
- byte[] mrBytes = new byte[c2Len];
- sr0.nextBytes(mrBytes);
-
- // XOR with c2 to obtain (m||r)
- for (int i = 0; i < c2Len; i++)
- {
- mrBytes[i] ^= c2[i];
- }
-
- // compute H(m||r)
- messDigest.update(mrBytes, 0, mrBytes.length);
- byte[] hmr = new byte[messDigest.getDigestSize()];
- messDigest.doFinal(hmr, 0);
-
- // compute Conv(H(m||r))
- c1Vec = Conversions.encode(n, t, hmr);
-
- // check that Conv(H(m||r)) = z
- if (!c1Vec.equals(z))
- {
- throw new Exception("Bad Padding: Invalid ciphertext.");
- }
-
- // split (m||r) to obtain m
- int kDiv8 = k >> 3;
- byte[][] mr = ByteUtils.split(mrBytes, c2Len - kDiv8);
-
- // return plain text m
- return mr[0];
- }
-
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalDigestCipher.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalDigestCipher.java
deleted file mode 100644
index 8a1ed62..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalDigestCipher.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.MessageEncryptor;
-
-// TODO should implement some interface?
-public class McEliecePointchevalDigestCipher
-{
-
- private final Digest messDigest;
-
- private final MessageEncryptor mcElieceCCA2Cipher;
-
- private boolean forEncrypting;
-
-
- public McEliecePointchevalDigestCipher(MessageEncryptor mcElieceCCA2Cipher, Digest messDigest)
- {
- this.mcElieceCCA2Cipher = mcElieceCCA2Cipher;
- this.messDigest = messDigest;
- }
-
-
- public void init(boolean forEncrypting,
- CipherParameters param)
- {
-
- this.forEncrypting = forEncrypting;
- AsymmetricKeyParameter k;
-
- if (param instanceof ParametersWithRandom)
- {
- k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters();
- }
- else
- {
- k = (AsymmetricKeyParameter)param;
- }
-
- if (forEncrypting && k.isPrivate())
- {
- throw new IllegalArgumentException("Encrypting Requires Public Key.");
- }
-
- if (!forEncrypting && !k.isPrivate())
- {
- throw new IllegalArgumentException("Decrypting Requires Private Key.");
- }
-
- reset();
-
- mcElieceCCA2Cipher.init(forEncrypting, param);
- }
-
-
- public byte[] messageEncrypt()
- {
- if (!forEncrypting)
- {
- throw new IllegalStateException("McEliecePointchevalDigestCipher not initialised for encrypting.");
- }
-
- byte[] hash = new byte[messDigest.getDigestSize()];
- messDigest.doFinal(hash, 0);
- byte[] enc = null;
-
- try
- {
- enc = mcElieceCCA2Cipher.messageEncrypt(hash);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
-
- return enc;
- }
-
-
- public byte[] messageDecrypt(byte[] ciphertext)
- {
- byte[] output = null;
- if (forEncrypting)
- {
- throw new IllegalStateException("McEliecePointchevalDigestCipher not initialised for decrypting.");
- }
-
-
- try
- {
- output = mcElieceCCA2Cipher.messageDecrypt(ciphertext);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
-
- return output;
- }
-
-
- public void update(byte b)
- {
- messDigest.update(b);
-
- }
-
- public void update(byte[] in, int off, int len)
- {
- messDigest.update(in, off, len);
-
- }
-
-
- public void reset()
- {
- messDigest.reset();
-
- }
-
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePrivateKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePrivateKeyParameters.java
deleted file mode 100644
index 762c2a2..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePrivateKeyParameters.java
+++ /dev/null
@@ -1,197 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix;
-import org.bouncycastle.pqc.math.linearalgebra.GF2mField;
-import org.bouncycastle.pqc.math.linearalgebra.Permutation;
-import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM;
-
-
-public class McEliecePrivateKeyParameters
- extends McElieceKeyParameters
-{
-
- // the OID of the algorithm
- private String oid;
-
- // the length of the code
- private int n;
-
- // the dimension of the code, where <tt>k &gt;= n - mt</tt>
- private int k;
-
- // the underlying finite field
- private GF2mField field;
-
- // the irreducible Goppa polynomial
- private PolynomialGF2mSmallM goppaPoly;
-
- // a k x k random binary non-singular matrix
- private GF2Matrix sInv;
-
- // the permutation used to generate the systematic check matrix
- private Permutation p1;
-
- // the permutation used to compute the public generator matrix
- private Permutation p2;
-
- // the canonical check matrix of the code
- private GF2Matrix h;
-
- // the matrix used to compute square roots in <tt>(GF(2^m))^t</tt>
- private PolynomialGF2mSmallM[] qInv;
-
- /**
- * Constructor.
- *
- * @param oid
- * @param n the length of the code
- * @param k the dimension of the code
- * @param field the field polynomial defining the finite field
- * <tt>GF(2<sup>m</sup>)</tt>
- * @param goppaPoly the irreducible Goppa polynomial
- * @param sInv the matrix <tt>S<sup>-1</sup></tt>
- * @param p1 the permutation used to generate the systematic check
- * matrix
- * @param p2 the permutation used to compute the public generator
- * matrix
- * @param h the canonical check matrix
- * @param qInv the matrix used to compute square roots in
- * <tt>(GF(2<sup>m</sup>))<sup>t</sup></tt>
- * @param params McElieceParameters
- */
- public McEliecePrivateKeyParameters(String oid, int n, int k, GF2mField field,
- PolynomialGF2mSmallM goppaPoly, GF2Matrix sInv, Permutation p1,
- Permutation p2, GF2Matrix h, PolynomialGF2mSmallM[] qInv, McElieceParameters params)
- {
- super(true, params);
- this.oid = oid;
- this.k = k;
- this.n = n;
- this.field = field;
- this.goppaPoly = goppaPoly;
- this.sInv = sInv;
- this.p1 = p1;
- this.p2 = p2;
- this.h = h;
- this.qInv = qInv;
- }
-
- /**
- * Constructor (used by the {@link McElieceKeyFactory}).
- *
- * @param oid
- * @param n the length of the code
- * @param k the dimension of the code
- * @param encField the encoded field polynomial defining the finite field
- * <tt>GF(2<sup>m</sup>)</tt>
- * @param encGoppaPoly the encoded irreducible Goppa polynomial
- * @param encSInv the encoded matrix <tt>S<sup>-1</sup></tt>
- * @param encP1 the encoded permutation used to generate the systematic
- * check matrix
- * @param encP2 the encoded permutation used to compute the public
- * generator matrix
- * @param encH the encoded canonical check matrix
- * @param encQInv the encoded matrix used to compute square roots in
- * <tt>(GF(2<sup>m</sup>))<sup>t</sup></tt>
- * @param params McElieceParameters
- */
- public McEliecePrivateKeyParameters(String oid, int n, int k, byte[] encField,
- byte[] encGoppaPoly, byte[] encSInv, byte[] encP1, byte[] encP2,
- byte[] encH, byte[][] encQInv, McElieceParameters params)
- {
- super(true, params);
- this.oid = oid;
- this.n = n;
- this.k = k;
- field = new GF2mField(encField);
- goppaPoly = new PolynomialGF2mSmallM(field, encGoppaPoly);
- sInv = new GF2Matrix(encSInv);
- p1 = new Permutation(encP1);
- p2 = new Permutation(encP2);
- h = new GF2Matrix(encH);
- qInv = new PolynomialGF2mSmallM[encQInv.length];
- for (int i = 0; i < encQInv.length; i++)
- {
- qInv[i] = new PolynomialGF2mSmallM(field, encQInv[i]);
- }
- }
-
- /**
- * @return the length of the code
- */
- public int getN()
- {
- return n;
- }
-
- /**
- * @return the dimension of the code
- */
- public int getK()
- {
- return k;
- }
-
- /**
- * @return the finite field <tt>GF(2<sup>m</sup>)</tt>
- */
- public GF2mField getField()
- {
- return field;
- }
-
- /**
- * @return the irreducible Goppa polynomial
- */
- public PolynomialGF2mSmallM getGoppaPoly()
- {
- return goppaPoly;
- }
-
- /**
- * @return the k x k random binary non-singular matrix S^-1
- */
- public GF2Matrix getSInv()
- {
- return sInv;
- }
-
- /**
- * @return the permutation used to generate the systematic check matrix
- */
- public Permutation getP1()
- {
- return p1;
- }
-
- /**
- * @return the permutation used to compute the public generator matrix
- */
- public Permutation getP2()
- {
- return p2;
- }
-
- /**
- * @return the canonical check matrix H
- */
- public GF2Matrix getH()
- {
- return h;
- }
-
- /**
- * @return the matrix used to compute square roots in
- * <tt>(GF(2<sup>m</sup>))<sup>t</sup></tt>
- */
- public PolynomialGF2mSmallM[] getQInv()
- {
- return qInv;
- }
-
- public String getOIDString()
- {
- return oid;
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePublicKeyParameters.java
deleted file mode 100644
index 6059e2e..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePublicKeyParameters.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package org.bouncycastle.pqc.crypto.mceliece;
-
-import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix;
-
-
-public class McEliecePublicKeyParameters
- extends McElieceKeyParameters
-{
-
- // the OID of the algorithm
- private String oid;
-
- // the length of the code
- private int n;
-
- // the error correction capability of the code
- private int t;
-
- // the generator matrix
- private GF2Matrix g;
-
- /**
- * Constructor (used by {@link McElieceKeyFactory}).
- *
- * @param oid
- * @param n the length of the code
- * @param t the error correction capability of the code
- * @param g the generator matrix
- * @param params McElieceParameters
- */
- public McEliecePublicKeyParameters(String oid, int n, int t, GF2Matrix g, McElieceParameters params)
- {
- super(false, params);
- this.oid = oid;
- this.n = n;
- this.t = t;
- this.g = new GF2Matrix(g);
- }
-
- /**
- * Constructor (used by {@link McElieceKeyFactory}).
- *
- * @param oid
- * @param n the length of the code
- * @param t the error correction capability of the code
- * @param encG the encoded generator matrix
- * @param params McElieceParameters
- */
- public McEliecePublicKeyParameters(String oid, int t, int n, byte[] encG, McElieceParameters params)
- {
- super(false, params);
- this.oid = oid;
- this.n = n;
- this.t = t;
- this.g = new GF2Matrix(encG);
- }
-
- /**
- * @return the length of the code
- */
- public int getN()
- {
- return n;
- }
-
- /**
- * @return the error correction capability of the code
- */
- public int getT()
- {
- return t;
- }
-
- /**
- * @return the generator matrix
- */
- public GF2Matrix getG()
- {
- return g;
- }
-
- public String getOIDString()
- {
- return oid;
-
- }
-
- /**
- * @return the dimension of the code
- */
- public int getK()
- {
- return g.getNumRows();
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/IndexGenerator.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/IndexGenerator.java
deleted file mode 100644
index 82974b3..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/IndexGenerator.java
+++ /dev/null
@@ -1,239 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.util.Arrays;
-
-/**
- * An implementation of the Index Generation Function in IEEE P1363.1.
- */
-public class IndexGenerator
-{
- private byte[] seed;
- private int N;
- private int c;
- private int minCallsR;
- private int totLen;
- private int remLen;
- private BitString buf;
- private int counter;
- private boolean initialized;
- private Digest hashAlg;
- private int hLen;
-
- /**
- * Constructs a new index generator.
- *
- * @param seed a seed of arbitrary length to initialize the index generator with
- * @param params NtruEncrypt parameters
- */
- IndexGenerator(byte[] seed, NTRUEncryptionParameters params)
- {
- this.seed = seed;
- N = params.N;
- c = params.c;
- minCallsR = params.minCallsR;
-
- totLen = 0;
- remLen = 0;
- counter = 0;
- hashAlg = params.hashAlg;
-
- hLen = hashAlg.getDigestSize(); // hash length
- initialized = false;
- }
-
- /**
- * Returns a number <code>i</code> such that <code>0 &lt;= i &lt; N</code>.
- *
- * @return
- */
- int nextIndex()
- {
- if (!initialized)
- {
- buf = new BitString();
- byte[] hash = new byte[hashAlg.getDigestSize()];
- while (counter < minCallsR)
- {
- appendHash(buf, hash);
- counter++;
- }
- totLen = minCallsR * 8 * hLen;
- remLen = totLen;
- initialized = true;
- }
-
- while (true)
- {
- totLen += c;
- BitString M = buf.getTrailing(remLen);
- if (remLen < c)
- {
- int tmpLen = c - remLen;
- int cThreshold = counter + (tmpLen + hLen - 1) / hLen;
- byte[] hash = new byte[hashAlg.getDigestSize()];
- while (counter < cThreshold)
- {
- appendHash(M, hash);
- counter++;
- if (tmpLen > 8 * hLen)
- {
- tmpLen -= 8 * hLen;
- }
- }
- remLen = 8 * hLen - tmpLen;
- buf = new BitString();
- buf.appendBits(hash);
- }
- else
- {
- remLen -= c;
- }
-
- int i = M.getLeadingAsInt(c); // assume c<32
- if (i < (1 << c) - ((1 << c) % N))
- {
- return i % N;
- }
- }
- }
-
- private void appendHash(BitString m, byte[] hash)
- {
- hashAlg.update(seed, 0, seed.length);
-
- putInt(hashAlg, counter);
-
- hashAlg.doFinal(hash, 0);
-
- m.appendBits(hash);
- }
-
- private void putInt(Digest hashAlg, int counter)
- {
- hashAlg.update((byte)(counter >> 24));
- hashAlg.update((byte)(counter >> 16));
- hashAlg.update((byte)(counter >> 8));
- hashAlg.update((byte)counter);
- }
-
- /**
- * Represents a string of bits and supports appending, reading the head, and reading the tail.
- */
- public static class BitString
- {
- byte[] bytes = new byte[4];
- int numBytes; // includes the last byte even if only some of its bits are used
- int lastByteBits; // lastByteBits <= 8
-
- /**
- * Appends all bits in a byte array to the end of the bit string.
- *
- * @param bytes a byte array
- */
- void appendBits(byte[] bytes)
- {
- for (int i = 0; i != bytes.length; i++)
- {
- appendBits(bytes[i]);
- }
- }
-
- /**
- * Appends all bits in a byte to the end of the bit string.
- *
- * @param b a byte
- */
- public void appendBits(byte b)
- {
- if (numBytes == bytes.length)
- {
- bytes = copyOf(bytes, 2 * bytes.length);
- }
-
- if (numBytes == 0)
- {
- numBytes = 1;
- bytes[0] = b;
- lastByteBits = 8;
- }
- else if (lastByteBits == 8)
- {
- bytes[numBytes++] = b;
- }
- else
- {
- int s = 8 - lastByteBits;
- bytes[numBytes - 1] |= (b & 0xFF) << lastByteBits;
- bytes[numBytes++] = (byte)((b & 0xFF) >> s);
- }
- }
-
- /**
- * Returns the last <code>numBits</code> bits from the end of the bit string.
- *
- * @param numBits number of bits
- * @return a new <code>BitString</code> of length <code>numBits</code>
- */
- public BitString getTrailing(int numBits)
- {
- BitString newStr = new BitString();
- newStr.numBytes = (numBits + 7) / 8;
- newStr.bytes = new byte[newStr.numBytes];
- for (int i = 0; i < newStr.numBytes; i++)
- {
- newStr.bytes[i] = bytes[i];
- }
-
- newStr.lastByteBits = numBits % 8;
- if (newStr.lastByteBits == 0)
- {
- newStr.lastByteBits = 8;
- }
- else
- {
- int s = 32 - newStr.lastByteBits;
- newStr.bytes[newStr.numBytes - 1] = (byte)(newStr.bytes[newStr.numBytes - 1] << s >>> s);
- }
-
- return newStr;
- }
-
- /**
- * Returns up to 32 bits from the beginning of the bit string.
- *
- * @param numBits number of bits
- * @return an <code>int</code> whose lower <code>numBits</code> bits are the beginning of the bit string
- */
- public int getLeadingAsInt(int numBits)
- {
- int startBit = (numBytes - 1) * 8 + lastByteBits - numBits;
- int startByte = startBit / 8;
-
- int startBitInStartByte = startBit % 8;
- int sum = (bytes[startByte] & 0xFF) >>> startBitInStartByte;
- int shift = 8 - startBitInStartByte;
- for (int i = startByte + 1; i < numBytes; i++)
- {
- sum |= (bytes[i] & 0xFF) << shift;
- shift += 8;
- }
-
- return sum;
- }
-
- public byte[] getBytes()
- {
- return Arrays.clone(bytes);
- }
- }
-
- private static byte[] copyOf(byte[] src, int len)
- {
- byte[] tmp = new byte[len];
-
- System.arraycopy(src, 0, tmp, 0, len < src.length ? len : src.length);
-
- return tmp;
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyGenerationParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyGenerationParameters.java
deleted file mode 100644
index 8d64ae2..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyGenerationParameters.java
+++ /dev/null
@@ -1,463 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.SecureRandom;
-import java.util.Arrays;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.KeyGenerationParameters;
-import org.bouncycastle.crypto.digests.SHA256Digest;
-import org.bouncycastle.crypto.digests.SHA512Digest;
-
-/**
- * A set of parameters for NtruEncrypt. Several predefined parameter sets are available and new ones can be created as well.
- */
-public class NTRUEncryptionKeyGenerationParameters
- extends KeyGenerationParameters
- implements Cloneable
-{
- /**
- * A conservative (in terms of security) parameter set that gives 256 bits of security and is optimized for key size.
- */
- public static final NTRUEncryptionKeyGenerationParameters EES1087EP2 = new NTRUEncryptionKeyGenerationParameters(1087, 2048, 120, 120, 256, 13, 25, 14, true, new byte[]{0, 6, 3}, true, false, new SHA512Digest());
-
- /**
- * A conservative (in terms of security) parameter set that gives 256 bits of security and is a tradeoff between key size and encryption/decryption speed.
- */
- public static final NTRUEncryptionKeyGenerationParameters EES1171EP1 = new NTRUEncryptionKeyGenerationParameters(1171, 2048, 106, 106, 256, 13, 20, 15, true, new byte[]{0, 6, 4}, true, false, new SHA512Digest());
-
- /**
- * A conservative (in terms of security) parameter set that gives 256 bits of security and is optimized for encryption/decryption speed.
- */
- public static final NTRUEncryptionKeyGenerationParameters EES1499EP1 = new NTRUEncryptionKeyGenerationParameters(1499, 2048, 79, 79, 256, 13, 17, 19, true, new byte[]{0, 6, 5}, true, false, new SHA512Digest());
-
- /**
- * A parameter set that gives 128 bits of security and uses simple ternary polynomials.
- */
- public static final NTRUEncryptionKeyGenerationParameters APR2011_439 = new NTRUEncryptionKeyGenerationParameters(439, 2048, 146, 130, 128, 9, 32, 9, true, new byte[]{0, 7, 101}, true, false, new SHA256Digest());
-
- /**
- * Like <code>APR2011_439</code>, this parameter set gives 128 bits of security but uses product-form polynomials and <code>f=1+pF</code>.
- */
- public static final NTRUEncryptionKeyGenerationParameters APR2011_439_FAST = new NTRUEncryptionKeyGenerationParameters(439, 2048, 9, 8, 5, 130, 128, 9, 32, 9, true, new byte[]{0, 7, 101}, true, true, new SHA256Digest());
-
- /**
- * A parameter set that gives 256 bits of security and uses simple ternary polynomials.
- */
- public static final NTRUEncryptionKeyGenerationParameters APR2011_743 = new NTRUEncryptionKeyGenerationParameters(743, 2048, 248, 220, 256, 10, 27, 14, true, new byte[]{0, 7, 105}, false, false, new SHA512Digest());
-
- /**
- * Like <code>APR2011_743</code>, this parameter set gives 256 bits of security but uses product-form polynomials and <code>f=1+pF</code>.
- */
- public static final NTRUEncryptionKeyGenerationParameters APR2011_743_FAST = new NTRUEncryptionKeyGenerationParameters(743, 2048, 11, 11, 15, 220, 256, 10, 27, 14, true, new byte[]{0, 7, 105}, false, true, new SHA512Digest());
-
- public int N, q, df, df1, df2, df3;
- public int dr;
- public int dr1;
- public int dr2;
- public int dr3;
- public int dg;
- int llen;
- public int maxMsgLenBytes;
- public int db;
- public int bufferLenBits;
- int bufferLenTrits;
- public int dm0;
- public int pkLen;
- public int c;
- public int minCallsR;
- public int minCallsMask;
- public boolean hashSeed;
- public byte[] oid;
- public boolean sparse;
- public boolean fastFp;
- public int polyType;
- public Digest hashAlg;
-
- /**
- * Constructs a parameter set that uses ternary private keys (i.e. <code>polyType=SIMPLE</code>).
- *
- * @param N number of polynomial coefficients
- * @param q modulus
- * @param df number of ones in the private polynomial <code>f</code>
- * @param dm0 minimum acceptable number of -1's, 0's, and 1's in the polynomial <code>m'</code> in the last encryption step
- * @param db number of random bits to prepend to the message
- * @param c a parameter for the Index Generation Function ({@link org.bouncycastle.pqc.crypto.ntru.IndexGenerator})
- * @param minCallsR minimum number of hash calls for the IGF to make
- * @param minCallsMask minimum number of calls to generate the masking polynomial
- * @param hashSeed whether to hash the seed in the MGF first (true) or use the seed directly (false)
- * @param oid three bytes that uniquely identify the parameter set
- * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial})
- * @param fastFp whether <code>f=1+p*F</code> for a ternary <code>F</code> (true) or <code>f</code> is ternary (false)
- * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>. The <code>MessageDigest</code> must support the <code>getDigestLength()</code> method.
- */
- public NTRUEncryptionKeyGenerationParameters(int N, int q, int df, int dm0, int db, int c, int minCallsR, int minCallsMask, boolean hashSeed, byte[] oid, boolean sparse, boolean fastFp, Digest hashAlg)
- {
- super(new SecureRandom(), db);
- this.N = N;
- this.q = q;
- this.df = df;
- this.db = db;
- this.dm0 = dm0;
- this.c = c;
- this.minCallsR = minCallsR;
- this.minCallsMask = minCallsMask;
- this.hashSeed = hashSeed;
- this.oid = oid;
- this.sparse = sparse;
- this.fastFp = fastFp;
- this.polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE;
- this.hashAlg = hashAlg;
- init();
- }
-
- /**
- * Constructs a parameter set that uses product-form private keys (i.e. <code>polyType=PRODUCT</code>).
- *
- * @param N number of polynomial coefficients
- * @param q modulus
- * @param df1 number of ones in the private polynomial <code>f1</code>
- * @param df2 number of ones in the private polynomial <code>f2</code>
- * @param df3 number of ones in the private polynomial <code>f3</code>
- * @param dm0 minimum acceptable number of -1's, 0's, and 1's in the polynomial <code>m'</code> in the last encryption step
- * @param db number of random bits to prepend to the message
- * @param c a parameter for the Index Generation Function ({@link org.bouncycastle.pqc.crypto.ntru.IndexGenerator})
- * @param minCallsR minimum number of hash calls for the IGF to make
- * @param minCallsMask minimum number of calls to generate the masking polynomial
- * @param hashSeed whether to hash the seed in the MGF first (true) or use the seed directly (false)
- * @param oid three bytes that uniquely identify the parameter set
- * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial})
- * @param fastFp whether <code>f=1+p*F</code> for a ternary <code>F</code> (true) or <code>f</code> is ternary (false)
- * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>
- */
- public NTRUEncryptionKeyGenerationParameters(int N, int q, int df1, int df2, int df3, int dm0, int db, int c, int minCallsR, int minCallsMask, boolean hashSeed, byte[] oid, boolean sparse, boolean fastFp, Digest hashAlg)
- {
- super(new SecureRandom(), db);
-
- this.N = N;
- this.q = q;
- this.df1 = df1;
- this.df2 = df2;
- this.df3 = df3;
- this.db = db;
- this.dm0 = dm0;
- this.c = c;
- this.minCallsR = minCallsR;
- this.minCallsMask = minCallsMask;
- this.hashSeed = hashSeed;
- this.oid = oid;
- this.sparse = sparse;
- this.fastFp = fastFp;
- this.polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT;
- this.hashAlg = hashAlg;
- init();
- }
-
- private void init()
- {
- dr = df;
- dr1 = df1;
- dr2 = df2;
- dr3 = df3;
- dg = N / 3;
- llen = 1; // ceil(log2(maxMsgLenBytes))
- maxMsgLenBytes = N * 3 / 2 / 8 - llen - db / 8 - 1;
- bufferLenBits = (N * 3 / 2 + 7) / 8 * 8 + 1;
- bufferLenTrits = N - 1;
- pkLen = db;
- }
-
- /**
- * Reads a parameter set from an input stream.
- *
- * @param is an input stream
- * @throws java.io.IOException
- */
- public NTRUEncryptionKeyGenerationParameters(InputStream is)
- throws IOException
- {
- super(new SecureRandom(), -1);
- DataInputStream dis = new DataInputStream(is);
- N = dis.readInt();
- q = dis.readInt();
- df = dis.readInt();
- df1 = dis.readInt();
- df2 = dis.readInt();
- df3 = dis.readInt();
- db = dis.readInt();
- dm0 = dis.readInt();
- c = dis.readInt();
- minCallsR = dis.readInt();
- minCallsMask = dis.readInt();
- hashSeed = dis.readBoolean();
- oid = new byte[3];
- dis.read(oid);
- sparse = dis.readBoolean();
- fastFp = dis.readBoolean();
- polyType = dis.read();
-
- String alg = dis.readUTF();
-
- if ("SHA-512".equals(alg))
- {
- hashAlg = new SHA512Digest();
- }
- else if ("SHA-256".equals(alg))
- {
- hashAlg = new SHA256Digest();
- }
-
- init();
- }
-
- public NTRUEncryptionParameters getEncryptionParameters()
- {
- if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE)
- {
- return new NTRUEncryptionParameters(N, q, df, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg);
- }
- else
- {
- return new NTRUEncryptionParameters(N, q, df1, df2, df3, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg);
- }
- }
-
- public NTRUEncryptionKeyGenerationParameters clone()
- {
- if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE)
- {
- return new NTRUEncryptionKeyGenerationParameters(N, q, df, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg);
- }
- else
- {
- return new NTRUEncryptionKeyGenerationParameters(N, q, df1, df2, df3, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg);
- }
- }
-
- /**
- * Returns the maximum length a plaintext message can be with this parameter set.
- *
- * @return the maximum length in bytes
- */
- public int getMaxMessageLength()
- {
- return maxMsgLenBytes;
- }
-
- /**
- * Writes the parameter set to an output stream
- *
- * @param os an output stream
- * @throws java.io.IOException
- */
- public void writeTo(OutputStream os)
- throws IOException
- {
- DataOutputStream dos = new DataOutputStream(os);
- dos.writeInt(N);
- dos.writeInt(q);
- dos.writeInt(df);
- dos.writeInt(df1);
- dos.writeInt(df2);
- dos.writeInt(df3);
- dos.writeInt(db);
- dos.writeInt(dm0);
- dos.writeInt(c);
- dos.writeInt(minCallsR);
- dos.writeInt(minCallsMask);
- dos.writeBoolean(hashSeed);
- dos.write(oid);
- dos.writeBoolean(sparse);
- dos.writeBoolean(fastFp);
- dos.write(polyType);
- dos.writeUTF(hashAlg.getAlgorithmName());
- }
-
-
- public int hashCode()
- {
- final int prime = 31;
- int result = 1;
- result = prime * result + N;
- result = prime * result + bufferLenBits;
- result = prime * result + bufferLenTrits;
- result = prime * result + c;
- result = prime * result + db;
- result = prime * result + df;
- result = prime * result + df1;
- result = prime * result + df2;
- result = prime * result + df3;
- result = prime * result + dg;
- result = prime * result + dm0;
- result = prime * result + dr;
- result = prime * result + dr1;
- result = prime * result + dr2;
- result = prime * result + dr3;
- result = prime * result + (fastFp ? 1231 : 1237);
- result = prime * result + ((hashAlg == null) ? 0 : hashAlg.getAlgorithmName().hashCode());
- result = prime * result + (hashSeed ? 1231 : 1237);
- result = prime * result + llen;
- result = prime * result + maxMsgLenBytes;
- result = prime * result + minCallsMask;
- result = prime * result + minCallsR;
- result = prime * result + Arrays.hashCode(oid);
- result = prime * result + pkLen;
- result = prime * result + polyType;
- result = prime * result + q;
- result = prime * result + (sparse ? 1231 : 1237);
- return result;
- }
-
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- if (obj == null)
- {
- return false;
- }
- if (getClass() != obj.getClass())
- {
- return false;
- }
- NTRUEncryptionKeyGenerationParameters other = (NTRUEncryptionKeyGenerationParameters)obj;
- if (N != other.N)
- {
- return false;
- }
- if (bufferLenBits != other.bufferLenBits)
- {
- return false;
- }
- if (bufferLenTrits != other.bufferLenTrits)
- {
- return false;
- }
- if (c != other.c)
- {
- return false;
- }
- if (db != other.db)
- {
- return false;
- }
- if (df != other.df)
- {
- return false;
- }
- if (df1 != other.df1)
- {
- return false;
- }
- if (df2 != other.df2)
- {
- return false;
- }
- if (df3 != other.df3)
- {
- return false;
- }
- if (dg != other.dg)
- {
- return false;
- }
- if (dm0 != other.dm0)
- {
- return false;
- }
- if (dr != other.dr)
- {
- return false;
- }
- if (dr1 != other.dr1)
- {
- return false;
- }
- if (dr2 != other.dr2)
- {
- return false;
- }
- if (dr3 != other.dr3)
- {
- return false;
- }
- if (fastFp != other.fastFp)
- {
- return false;
- }
- if (hashAlg == null)
- {
- if (other.hashAlg != null)
- {
- return false;
- }
- }
- else if (!hashAlg.getAlgorithmName().equals(other.hashAlg.getAlgorithmName()))
- {
- return false;
- }
- if (hashSeed != other.hashSeed)
- {
- return false;
- }
- if (llen != other.llen)
- {
- return false;
- }
- if (maxMsgLenBytes != other.maxMsgLenBytes)
- {
- return false;
- }
- if (minCallsMask != other.minCallsMask)
- {
- return false;
- }
- if (minCallsR != other.minCallsR)
- {
- return false;
- }
- if (!Arrays.equals(oid, other.oid))
- {
- return false;
- }
- if (pkLen != other.pkLen)
- {
- return false;
- }
- if (polyType != other.polyType)
- {
- return false;
- }
- if (q != other.q)
- {
- return false;
- }
- if (sparse != other.sparse)
- {
- return false;
- }
- return true;
- }
-
- public String toString()
- {
- StringBuilder output = new StringBuilder("EncryptionParameters(N=" + N + " q=" + q);
- if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE)
- {
- output.append(" polyType=SIMPLE df=" + df);
- }
- else
- {
- output.append(" polyType=PRODUCT df1=" + df1 + " df2=" + df2 + " df3=" + df3);
- }
- output.append(" dm0=" + dm0 + " db=" + db + " c=" + c + " minCallsR=" + minCallsR + " minCallsMask=" + minCallsMask +
- " hashSeed=" + hashSeed + " hashAlg=" + hashAlg + " oid=" + Arrays.toString(oid) + " sparse=" + sparse + ")");
- return output.toString();
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyPairGenerator.java
deleted file mode 100644
index f2751ca..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyPairGenerator.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
-import org.bouncycastle.crypto.KeyGenerationParameters;
-import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial;
-import org.bouncycastle.pqc.math.ntru.util.Util;
-
-/**
- * Generates key pairs.<br>
- * The parameter p is hardcoded to 3.
- */
-public class NTRUEncryptionKeyPairGenerator
- implements AsymmetricCipherKeyPairGenerator
-{
- private NTRUEncryptionKeyGenerationParameters params;
-
- /**
- * Constructs a new instance with a set of encryption parameters.
- *
- * @param param encryption parameters
- */
- public void init(KeyGenerationParameters param)
- {
- this.params = (NTRUEncryptionKeyGenerationParameters)param;
- }
-
- /**
- * Generates a new encryption key pair.
- *
- * @return a key pair
- */
- public AsymmetricCipherKeyPair generateKeyPair()
- {
- int N = params.N;
- int q = params.q;
- int df = params.df;
- int df1 = params.df1;
- int df2 = params.df2;
- int df3 = params.df3;
- int dg = params.dg;
- boolean fastFp = params.fastFp;
- boolean sparse = params.sparse;
-
- Polynomial t;
- IntegerPolynomial fq;
- IntegerPolynomial fp = null;
-
- // choose a random f that is invertible mod 3 and q
- while (true)
- {
- IntegerPolynomial f;
-
- // choose random t, calculate f and fp
- if (fastFp)
- {
- // if fastFp=true, f is always invertible mod 3
- t = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? Util.generateRandomTernary(N, df, df, sparse, params.getRandom()) : ProductFormPolynomial.generateRandom(N, df1, df2, df3, df3, params.getRandom());
- f = t.toIntegerPolynomial();
- f.mult(3);
- f.coeffs[0] += 1;
- }
- else
- {
- t = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? Util.generateRandomTernary(N, df, df - 1, sparse, params.getRandom()) : ProductFormPolynomial.generateRandom(N, df1, df2, df3, df3 - 1, params.getRandom());
- f = t.toIntegerPolynomial();
- fp = f.invertF3();
- if (fp == null)
- {
- continue;
- }
- }
-
- fq = f.invertFq(q);
- if (fq == null)
- {
- continue;
- }
- break;
- }
-
- // if fastFp=true, fp=1
- if (fastFp)
- {
- fp = new IntegerPolynomial(N);
- fp.coeffs[0] = 1;
- }
-
- // choose a random g that is invertible mod q
- DenseTernaryPolynomial g;
- while (true)
- {
- g = DenseTernaryPolynomial.generateRandom(N, dg, dg - 1, params.getRandom());
- if (g.invertFq(q) != null)
- {
- break;
- }
- }
-
- IntegerPolynomial h = g.mult(fq, q);
- h.mult3(q);
- h.ensurePositive(q);
- g.clear();
- fq.clear();
-
- NTRUEncryptionPrivateKeyParameters priv = new NTRUEncryptionPrivateKeyParameters(h, t, fp, params.getEncryptionParameters());
- NTRUEncryptionPublicKeyParameters pub = new NTRUEncryptionPublicKeyParameters(h, params.getEncryptionParameters());
- return new AsymmetricCipherKeyPair(pub, priv);
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyParameters.java
deleted file mode 100644
index 27a7987..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionKeyParameters.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-
-public class NTRUEncryptionKeyParameters
- extends AsymmetricKeyParameter
-{
- final protected NTRUEncryptionParameters params;
-
- public NTRUEncryptionKeyParameters(boolean privateKey, NTRUEncryptionParameters params)
- {
- super(privateKey);
- this.params = params;
- }
-
- public NTRUEncryptionParameters getParameters()
- {
- return params;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionParameters.java
deleted file mode 100644
index b387bc2..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionParameters.java
+++ /dev/null
@@ -1,410 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA256Digest;
-import org.bouncycastle.crypto.digests.SHA512Digest;
-
-/**
- * A set of parameters for NtruEncrypt. Several predefined parameter sets are available and new ones can be created as well.
- */
-public class NTRUEncryptionParameters
- implements Cloneable
-{
-
- public int N, q, df, df1, df2, df3;
- public int dr;
- public int dr1;
- public int dr2;
- public int dr3;
- public int dg;
- int llen;
- public int maxMsgLenBytes;
- public int db;
- public int bufferLenBits;
- int bufferLenTrits;
- public int dm0;
- public int pkLen;
- public int c;
- public int minCallsR;
- public int minCallsMask;
- public boolean hashSeed;
- public byte[] oid;
- public boolean sparse;
- public boolean fastFp;
- public int polyType;
- public Digest hashAlg;
-
- /**
- * Constructs a parameter set that uses ternary private keys (i.e. <code>polyType=SIMPLE</code>).
- *
- * @param N number of polynomial coefficients
- * @param q modulus
- * @param df number of ones in the private polynomial <code>f</code>
- * @param dm0 minimum acceptable number of -1's, 0's, and 1's in the polynomial <code>m'</code> in the last encryption step
- * @param db number of random bits to prepend to the message
- * @param c a parameter for the Index Generation Function ({@link org.bouncycastle.pqc.crypto.ntru.IndexGenerator})
- * @param minCallsR minimum number of hash calls for the IGF to make
- * @param minCallsMask minimum number of calls to generate the masking polynomial
- * @param hashSeed whether to hash the seed in the MGF first (true) or use the seed directly (false)
- * @param oid three bytes that uniquely identify the parameter set
- * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial})
- * @param fastFp whether <code>f=1+p*F</code> for a ternary <code>F</code> (true) or <code>f</code> is ternary (false)
- * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>. The <code>MessageDigest</code> must support the <code>getDigestLength()</code> method.
- */
- public NTRUEncryptionParameters(int N, int q, int df, int dm0, int db, int c, int minCallsR, int minCallsMask, boolean hashSeed, byte[] oid, boolean sparse, boolean fastFp, Digest hashAlg)
- {
- this.N = N;
- this.q = q;
- this.df = df;
- this.db = db;
- this.dm0 = dm0;
- this.c = c;
- this.minCallsR = minCallsR;
- this.minCallsMask = minCallsMask;
- this.hashSeed = hashSeed;
- this.oid = oid;
- this.sparse = sparse;
- this.fastFp = fastFp;
- this.polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE;
- this.hashAlg = hashAlg;
- init();
- }
-
- /**
- * Constructs a parameter set that uses product-form private keys (i.e. <code>polyType=PRODUCT</code>).
- *
- * @param N number of polynomial coefficients
- * @param q modulus
- * @param df1 number of ones in the private polynomial <code>f1</code>
- * @param df2 number of ones in the private polynomial <code>f2</code>
- * @param df3 number of ones in the private polynomial <code>f3</code>
- * @param dm0 minimum acceptable number of -1's, 0's, and 1's in the polynomial <code>m'</code> in the last encryption step
- * @param db number of random bits to prepend to the message
- * @param c a parameter for the Index Generation Function ({@link org.bouncycastle.pqc.crypto.ntru.IndexGenerator})
- * @param minCallsR minimum number of hash calls for the IGF to make
- * @param minCallsMask minimum number of calls to generate the masking polynomial
- * @param hashSeed whether to hash the seed in the MGF first (true) or use the seed directly (false)
- * @param oid three bytes that uniquely identify the parameter set
- * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial})
- * @param fastFp whether <code>f=1+p*F</code> for a ternary <code>F</code> (true) or <code>f</code> is ternary (false)
- * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>
- */
- public NTRUEncryptionParameters(int N, int q, int df1, int df2, int df3, int dm0, int db, int c, int minCallsR, int minCallsMask, boolean hashSeed, byte[] oid, boolean sparse, boolean fastFp, Digest hashAlg)
- {
- this.N = N;
- this.q = q;
- this.df1 = df1;
- this.df2 = df2;
- this.df3 = df3;
- this.db = db;
- this.dm0 = dm0;
- this.c = c;
- this.minCallsR = minCallsR;
- this.minCallsMask = minCallsMask;
- this.hashSeed = hashSeed;
- this.oid = oid;
- this.sparse = sparse;
- this.fastFp = fastFp;
- this.polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT;
- this.hashAlg = hashAlg;
- init();
- }
-
- private void init()
- {
- dr = df;
- dr1 = df1;
- dr2 = df2;
- dr3 = df3;
- dg = N / 3;
- llen = 1; // ceil(log2(maxMsgLenBytes))
- maxMsgLenBytes = N * 3 / 2 / 8 - llen - db / 8 - 1;
- bufferLenBits = (N * 3 / 2 + 7) / 8 * 8 + 1;
- bufferLenTrits = N - 1;
- pkLen = db;
- }
-
- /**
- * Reads a parameter set from an input stream.
- *
- * @param is an input stream
- * @throws IOException
- */
- public NTRUEncryptionParameters(InputStream is)
- throws IOException
- {
- DataInputStream dis = new DataInputStream(is);
- N = dis.readInt();
- q = dis.readInt();
- df = dis.readInt();
- df1 = dis.readInt();
- df2 = dis.readInt();
- df3 = dis.readInt();
- db = dis.readInt();
- dm0 = dis.readInt();
- c = dis.readInt();
- minCallsR = dis.readInt();
- minCallsMask = dis.readInt();
- hashSeed = dis.readBoolean();
- oid = new byte[3];
- dis.read(oid);
- sparse = dis.readBoolean();
- fastFp = dis.readBoolean();
- polyType = dis.read();
-
- String alg = dis.readUTF();
-
- if ("SHA-512".equals(alg))
- {
- hashAlg = new SHA512Digest();
- }
- else if ("SHA-256".equals(alg))
- {
- hashAlg = new SHA256Digest();
- }
-
- init();
- }
-
- public NTRUEncryptionParameters clone()
- {
- if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE)
- {
- return new NTRUEncryptionParameters(N, q, df, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg);
- }
- else
- {
- return new NTRUEncryptionParameters(N, q, df1, df2, df3, dm0, db, c, minCallsR, minCallsMask, hashSeed, oid, sparse, fastFp, hashAlg);
- }
- }
-
- /**
- * Returns the maximum length a plaintext message can be with this parameter set.
- *
- * @return the maximum length in bytes
- */
- public int getMaxMessageLength()
- {
- return maxMsgLenBytes;
- }
-
- /**
- * Writes the parameter set to an output stream
- *
- * @param os an output stream
- * @throws IOException
- */
- public void writeTo(OutputStream os)
- throws IOException
- {
- DataOutputStream dos = new DataOutputStream(os);
- dos.writeInt(N);
- dos.writeInt(q);
- dos.writeInt(df);
- dos.writeInt(df1);
- dos.writeInt(df2);
- dos.writeInt(df3);
- dos.writeInt(db);
- dos.writeInt(dm0);
- dos.writeInt(c);
- dos.writeInt(minCallsR);
- dos.writeInt(minCallsMask);
- dos.writeBoolean(hashSeed);
- dos.write(oid);
- dos.writeBoolean(sparse);
- dos.writeBoolean(fastFp);
- dos.write(polyType);
- dos.writeUTF(hashAlg.getAlgorithmName());
- }
-
-
- public int hashCode()
- {
- final int prime = 31;
- int result = 1;
- result = prime * result + N;
- result = prime * result + bufferLenBits;
- result = prime * result + bufferLenTrits;
- result = prime * result + c;
- result = prime * result + db;
- result = prime * result + df;
- result = prime * result + df1;
- result = prime * result + df2;
- result = prime * result + df3;
- result = prime * result + dg;
- result = prime * result + dm0;
- result = prime * result + dr;
- result = prime * result + dr1;
- result = prime * result + dr2;
- result = prime * result + dr3;
- result = prime * result + (fastFp ? 1231 : 1237);
- result = prime * result + ((hashAlg == null) ? 0 : hashAlg.getAlgorithmName().hashCode());
- result = prime * result + (hashSeed ? 1231 : 1237);
- result = prime * result + llen;
- result = prime * result + maxMsgLenBytes;
- result = prime * result + minCallsMask;
- result = prime * result + minCallsR;
- result = prime * result + Arrays.hashCode(oid);
- result = prime * result + pkLen;
- result = prime * result + polyType;
- result = prime * result + q;
- result = prime * result + (sparse ? 1231 : 1237);
- return result;
- }
-
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- if (obj == null)
- {
- return false;
- }
- if (getClass() != obj.getClass())
- {
- return false;
- }
- NTRUEncryptionParameters other = (NTRUEncryptionParameters)obj;
- if (N != other.N)
- {
- return false;
- }
- if (bufferLenBits != other.bufferLenBits)
- {
- return false;
- }
- if (bufferLenTrits != other.bufferLenTrits)
- {
- return false;
- }
- if (c != other.c)
- {
- return false;
- }
- if (db != other.db)
- {
- return false;
- }
- if (df != other.df)
- {
- return false;
- }
- if (df1 != other.df1)
- {
- return false;
- }
- if (df2 != other.df2)
- {
- return false;
- }
- if (df3 != other.df3)
- {
- return false;
- }
- if (dg != other.dg)
- {
- return false;
- }
- if (dm0 != other.dm0)
- {
- return false;
- }
- if (dr != other.dr)
- {
- return false;
- }
- if (dr1 != other.dr1)
- {
- return false;
- }
- if (dr2 != other.dr2)
- {
- return false;
- }
- if (dr3 != other.dr3)
- {
- return false;
- }
- if (fastFp != other.fastFp)
- {
- return false;
- }
- if (hashAlg == null)
- {
- if (other.hashAlg != null)
- {
- return false;
- }
- }
- else if (!hashAlg.getAlgorithmName().equals(other.hashAlg.getAlgorithmName()))
- {
- return false;
- }
- if (hashSeed != other.hashSeed)
- {
- return false;
- }
- if (llen != other.llen)
- {
- return false;
- }
- if (maxMsgLenBytes != other.maxMsgLenBytes)
- {
- return false;
- }
- if (minCallsMask != other.minCallsMask)
- {
- return false;
- }
- if (minCallsR != other.minCallsR)
- {
- return false;
- }
- if (!Arrays.equals(oid, other.oid))
- {
- return false;
- }
- if (pkLen != other.pkLen)
- {
- return false;
- }
- if (polyType != other.polyType)
- {
- return false;
- }
- if (q != other.q)
- {
- return false;
- }
- if (sparse != other.sparse)
- {
- return false;
- }
- return true;
- }
-
- public String toString()
- {
- StringBuilder output = new StringBuilder("EncryptionParameters(N=" + N + " q=" + q);
- if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE)
- {
- output.append(" polyType=SIMPLE df=" + df);
- }
- else
- {
- output.append(" polyType=PRODUCT df1=" + df1 + " df2=" + df2 + " df3=" + df3);
- }
- output.append(" dm0=" + dm0 + " db=" + db + " c=" + c + " minCallsR=" + minCallsR + " minCallsMask=" + minCallsMask +
- " hashSeed=" + hashSeed + " hashAlg=" + hashAlg + " oid=" + Arrays.toString(oid) + " sparse=" + sparse + ")");
- return output.toString();
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionPrivateKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionPrivateKeyParameters.java
deleted file mode 100644
index bcf9418..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionPrivateKeyParameters.java
+++ /dev/null
@@ -1,199 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial;
-
-/**
- * A NtruEncrypt private key is essentially a polynomial named <code>f</code>
- * which takes different forms depending on whether product-form polynomials are used,
- * and on <code>fastP</code><br>
- * The inverse of <code>f</code> modulo <code>p</code> is precomputed on initialization.
- */
-public class NTRUEncryptionPrivateKeyParameters
- extends NTRUEncryptionKeyParameters
-{
- public Polynomial t;
- public IntegerPolynomial fp;
- public IntegerPolynomial h;
-
- /**
- * Constructs a new private key from a polynomial
- *
- * @param h the public polynomial for the key.
- * @param t the polynomial which determines the key: if <code>fastFp=true</code>, <code>f=1+3t</code>; otherwise, <code>f=t</code>
- * @param fp the inverse of <code>f</code>
- * @param params the NtruEncrypt parameters to use
- */
- public NTRUEncryptionPrivateKeyParameters(IntegerPolynomial h, Polynomial t, IntegerPolynomial fp, NTRUEncryptionParameters params)
- {
- super(true, params);
-
- this.h = h;
- this.t = t;
- this.fp = fp;
- }
-
- /**
- * Converts a byte array to a polynomial <code>f</code> and constructs a new private key
- *
- * @param b an encoded polynomial
- * @param params the NtruEncrypt parameters to use
- * @see #getEncoded()
- */
- public NTRUEncryptionPrivateKeyParameters(byte[] b, NTRUEncryptionParameters params)
- throws IOException
- {
- this(new ByteArrayInputStream(b), params);
- }
-
- /**
- * Reads a polynomial <code>f</code> from an input stream and constructs a new private key
- *
- * @param is an input stream
- * @param params the NtruEncrypt parameters to use
- * @see #writeTo(OutputStream)
- */
- public NTRUEncryptionPrivateKeyParameters(InputStream is, NTRUEncryptionParameters params)
- throws IOException
- {
- super(true, params);
-
- if (params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT)
- {
- int N = params.N;
- int df1 = params.df1;
- int df2 = params.df2;
- int df3Ones = params.df3;
- int df3NegOnes = params.fastFp ? params.df3 : params.df3 - 1;
- h = IntegerPolynomial.fromBinary(is, params.N, params.q);
- t = ProductFormPolynomial.fromBinary(is, N, df1, df2, df3Ones, df3NegOnes);
- }
- else
- {
- h = IntegerPolynomial.fromBinary(is, params.N, params.q);
- IntegerPolynomial fInt = IntegerPolynomial.fromBinary3Tight(is, params.N);
- t = params.sparse ? new SparseTernaryPolynomial(fInt) : new DenseTernaryPolynomial(fInt);
- }
-
- init();
- }
-
- /**
- * Initializes <code>fp</code> from t.
- */
- private void init()
- {
- if (params.fastFp)
- {
- fp = new IntegerPolynomial(params.N);
- fp.coeffs[0] = 1;
- }
- else
- {
- fp = t.toIntegerPolynomial().invertF3();
- }
- }
-
- /**
- * Converts the key to a byte array
- *
- * @return the encoded key
- * @see #NTRUEncryptionPrivateKeyParameters(byte[], NTRUEncryptionParameters)
- */
- public byte[] getEncoded()
- {
- byte[] hBytes = h.toBinary(params.q);
- byte[] tBytes;
-
- if (t instanceof ProductFormPolynomial)
- {
- tBytes = ((ProductFormPolynomial)t).toBinary();
- }
- else
- {
- tBytes = t.toIntegerPolynomial().toBinary3Tight();
- }
-
- byte[] res = new byte[hBytes.length + tBytes.length];
-
- System.arraycopy(hBytes, 0, res, 0, hBytes.length);
- System.arraycopy(tBytes, 0, res, hBytes.length, tBytes.length);
-
- return res;
- }
-
- /**
- * Writes the key to an output stream
- *
- * @param os an output stream
- * @throws IOException
- * @see #NTRUEncryptionPrivateKeyParameters(InputStream, NTRUEncryptionParameters)
- */
- public void writeTo(OutputStream os)
- throws IOException
- {
- os.write(getEncoded());
- }
-
- public int hashCode()
- {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((params == null) ? 0 : params.hashCode());
- result = prime * result + ((t == null) ? 0 : t.hashCode());
- result = prime * result + ((h == null) ? 0 : h.hashCode());
- return result;
- }
-
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- if (obj == null)
- {
- return false;
- }
- if (!(obj instanceof NTRUEncryptionPrivateKeyParameters))
- {
- return false;
- }
- NTRUEncryptionPrivateKeyParameters other = (NTRUEncryptionPrivateKeyParameters)obj;
- if (params == null)
- {
- if (other.params != null)
- {
- return false;
- }
- }
- else if (!params.equals(other.params))
- {
- return false;
- }
- if (t == null)
- {
- if (other.t != null)
- {
- return false;
- }
- }
- else if (!t.equals(other.t))
- {
- return false;
- }
- if (!h.equals(other.h))
- {
- return false;
- }
- return true;
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionPublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionPublicKeyParameters.java
deleted file mode 100644
index 0aa0357..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEncryptionPublicKeyParameters.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial;
-
-/**
- * A NtruEncrypt public key is essentially a polynomial named <code>h</code>.
- */
-public class NTRUEncryptionPublicKeyParameters
- extends NTRUEncryptionKeyParameters
-{
- public IntegerPolynomial h;
-
- /**
- * Constructs a new public key from a polynomial
- *
- * @param h the polynomial <code>h</code> which determines the key
- * @param params the NtruEncrypt parameters to use
- */
- public NTRUEncryptionPublicKeyParameters(IntegerPolynomial h, NTRUEncryptionParameters params)
- {
- super(false, params);
-
- this.h = h;
- }
-
- /**
- * Converts a byte array to a polynomial <code>h</code> and constructs a new public key
- *
- * @param b an encoded polynomial
- * @param params the NtruEncrypt parameters to use
- * @see #getEncoded()
- */
- public NTRUEncryptionPublicKeyParameters(byte[] b, NTRUEncryptionParameters params)
- {
- super(false, params);
-
- h = IntegerPolynomial.fromBinary(b, params.N, params.q);
- }
-
- /**
- * Reads a polynomial <code>h</code> from an input stream and constructs a new public key
- *
- * @param is an input stream
- * @param params the NtruEncrypt parameters to use
- * @see #writeTo(OutputStream)
- */
- public NTRUEncryptionPublicKeyParameters(InputStream is, NTRUEncryptionParameters params)
- throws IOException
- {
- super(false, params);
-
- h = IntegerPolynomial.fromBinary(is, params.N, params.q);
- }
-
- /**
- * Converts the key to a byte array
- *
- * @return the encoded key
- * @see #NTRUEncryptionPublicKeyParameters(byte[], NTRUEncryptionParameters)
- */
- public byte[] getEncoded()
- {
- return h.toBinary(params.q);
- }
-
- /**
- * Writes the key to an output stream
- *
- * @param os an output stream
- * @throws IOException
- * @see #NTRUEncryptionPublicKeyParameters(InputStream, NTRUEncryptionParameters)
- */
- public void writeTo(OutputStream os)
- throws IOException
- {
- os.write(getEncoded());
- }
-
- public int hashCode()
- {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((h == null) ? 0 : h.hashCode());
- result = prime * result + ((params == null) ? 0 : params.hashCode());
- return result;
- }
-
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- if (obj == null)
- {
- return false;
- }
- if (!(obj instanceof NTRUEncryptionPublicKeyParameters))
- {
- return false;
- }
- NTRUEncryptionPublicKeyParameters other = (NTRUEncryptionPublicKeyParameters)obj;
- if (h == null)
- {
- if (other.h != null)
- {
- return false;
- }
- }
- else if (!h.equals(other.h))
- {
- return false;
- }
- if (params == null)
- {
- if (other.params != null)
- {
- return false;
- }
- }
- else if (!params.equals(other.params))
- {
- return false;
- }
- return true;
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEngine.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEngine.java
deleted file mode 100644
index 77ff1c3..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUEngine.java
+++ /dev/null
@@ -1,495 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.AsymmetricBlockCipher;
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.DataLengthException;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.InvalidCipherTextException;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.TernaryPolynomial;
-import org.bouncycastle.util.Arrays;
-
-/**
- * Encrypts, decrypts data and generates key pairs.<br>
- * The parameter p is hardcoded to 3.
- */
-public class NTRUEngine
- implements AsymmetricBlockCipher
-{
- private boolean forEncryption;
- private NTRUEncryptionParameters params;
- private NTRUEncryptionPublicKeyParameters pubKey;
- private NTRUEncryptionPrivateKeyParameters privKey;
- private SecureRandom random;
-
- /**
- * Constructs a new instance with a set of encryption parameters.
- *
- */
- public NTRUEngine()
- {
- }
-
- public void init(boolean forEncryption, CipherParameters parameters)
- {
- this.forEncryption = forEncryption;
- if (forEncryption)
- {
- if (parameters instanceof ParametersWithRandom)
- {
- ParametersWithRandom p = (ParametersWithRandom)parameters;
-
- this.random = p.getRandom();
- this.pubKey = (NTRUEncryptionPublicKeyParameters)p.getParameters();
- }
- else
- {
- this.random = new SecureRandom();
- this.pubKey = (NTRUEncryptionPublicKeyParameters)parameters;
- }
-
- this.params = pubKey.getParameters();
- }
- else
- {
- this.privKey = (NTRUEncryptionPrivateKeyParameters)parameters;
- this.params = privKey.getParameters();
- }
- }
-
- public int getInputBlockSize()
- {
- return params.maxMsgLenBytes;
- }
-
- public int getOutputBlockSize()
- {
- return ((params.N * log2(params.q)) + 7) / 8;
- }
-
- public byte[] processBlock(byte[] in, int inOff, int len)
- throws InvalidCipherTextException
- {
- byte[] tmp = new byte[len];
-
- System.arraycopy(in, inOff, tmp, 0, len);
-
- if (forEncryption)
- {
- return encrypt(tmp, pubKey);
- }
- else
- {
- return decrypt(tmp, privKey);
- }
- }
-
- /**
- * Encrypts a message.<br/>
- * See P1363.1 section 9.2.2.
- *
- * @param m The message to encrypt
- * @param pubKey the public key to encrypt the message with
- * @return the encrypted message
- */
- private byte[] encrypt(byte[] m, NTRUEncryptionPublicKeyParameters pubKey)
- {
- IntegerPolynomial pub = pubKey.h;
- int N = params.N;
- int q = params.q;
-
- int maxLenBytes = params.maxMsgLenBytes;
- int db = params.db;
- int bufferLenBits = params.bufferLenBits;
- int dm0 = params.dm0;
- int pkLen = params.pkLen;
- int minCallsMask = params.minCallsMask;
- boolean hashSeed = params.hashSeed;
- byte[] oid = params.oid;
-
- int l = m.length;
- if (maxLenBytes > 255)
- {
- throw new IllegalArgumentException("llen values bigger than 1 are not supported");
- }
- if (l > maxLenBytes)
- {
- throw new DataLengthException("Message too long: " + l + ">" + maxLenBytes);
- }
-
- while (true)
- {
- // M = b|octL|m|p0
- byte[] b = new byte[db / 8];
- random.nextBytes(b);
- byte[] p0 = new byte[maxLenBytes + 1 - l];
- byte[] M = new byte[bufferLenBits / 8];
-
- System.arraycopy(b, 0, M, 0, b.length);
- M[b.length] = (byte)l;
- System.arraycopy(m, 0, M, b.length + 1, m.length);
- System.arraycopy(p0, 0, M, b.length + 1 + m.length, p0.length);
-
- IntegerPolynomial mTrin = IntegerPolynomial.fromBinary3Sves(M, N);
-
- // sData = OID|m|b|hTrunc
- byte[] bh = pub.toBinary(q);
- byte[] hTrunc = copyOf(bh, pkLen / 8);
- byte[] sData = buildSData(oid, m, l, b, hTrunc);
-
- Polynomial r = generateBlindingPoly(sData, M);
- IntegerPolynomial R = r.mult(pub, q);
- IntegerPolynomial R4 = (IntegerPolynomial)R.clone();
- R4.modPositive(4);
- byte[] oR4 = R4.toBinary(4);
- IntegerPolynomial mask = MGF(oR4, N, minCallsMask, hashSeed);
- mTrin.add(mask);
- mTrin.mod3();
-
- if (mTrin.count(-1) < dm0)
- {
- continue;
- }
- if (mTrin.count(0) < dm0)
- {
- continue;
- }
- if (mTrin.count(1) < dm0)
- {
- continue;
- }
-
- R.add(mTrin, q);
- R.ensurePositive(q);
- return R.toBinary(q);
- }
- }
-
- private byte[] buildSData(byte[] oid, byte[] m, int l, byte[] b, byte[] hTrunc)
- {
- byte[] sData = new byte[oid.length + l + b.length + hTrunc.length];
-
- System.arraycopy(oid, 0, sData, 0, oid.length);
- System.arraycopy(m, 0, sData, oid.length, m.length);
- System.arraycopy(b, 0, sData, oid.length + m.length, b.length);
- System.arraycopy(hTrunc, 0, sData, oid.length + m.length + b.length, hTrunc.length);
- return sData;
- }
-
- protected IntegerPolynomial encrypt(IntegerPolynomial m, TernaryPolynomial r, IntegerPolynomial pubKey)
- {
- IntegerPolynomial e = r.mult(pubKey, params.q);
- e.add(m, params.q);
- e.ensurePositive(params.q);
- return e;
- }
-
- /**
- * Deterministically generates a blinding polynomial from a seed and a message representative.
- *
- * @param seed
- * @param M message representative
- * @return a blinding polynomial
- */
- private Polynomial generateBlindingPoly(byte[] seed, byte[] M)
- {
- IndexGenerator ig = new IndexGenerator(seed, params);
-
- if (params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT)
- {
- SparseTernaryPolynomial r1 = new SparseTernaryPolynomial(generateBlindingCoeffs(ig, params.dr1));
- SparseTernaryPolynomial r2 = new SparseTernaryPolynomial(generateBlindingCoeffs(ig, params.dr2));
- SparseTernaryPolynomial r3 = new SparseTernaryPolynomial(generateBlindingCoeffs(ig, params.dr3));
- return new ProductFormPolynomial(r1, r2, r3);
- }
- else
- {
- int dr = params.dr;
- boolean sparse = params.sparse;
- int[] r = generateBlindingCoeffs(ig, dr);
- if (sparse)
- {
- return new SparseTernaryPolynomial(r);
- }
- else
- {
- return new DenseTernaryPolynomial(r);
- }
- }
- }
-
- /**
- * Generates an <code>int</code> array containing <code>dr</code> elements equal to <code>1</code>
- * and <code>dr</code> elements equal to <code>-1</code> using an index generator.
- *
- * @param ig an index generator
- * @param dr number of ones / negative ones
- * @return an array containing numbers between <code>-1</code> and <code>1</code>
- */
- private int[] generateBlindingCoeffs(IndexGenerator ig, int dr)
- {
- int N = params.N;
-
- int[] r = new int[N];
- for (int coeff = -1; coeff <= 1; coeff += 2)
- {
- int t = 0;
- while (t < dr)
- {
- int i = ig.nextIndex();
- if (r[i] == 0)
- {
- r[i] = coeff;
- t++;
- }
- }
- }
-
- return r;
- }
-
- /**
- * An implementation of MGF-TP-1 from P1363.1 section 8.4.1.1.
- *
- * @param seed
- * @param N
- * @param minCallsR
- * @param hashSeed whether to hash the seed
- * @return
- */
- private IntegerPolynomial MGF(byte[] seed, int N, int minCallsR, boolean hashSeed)
- {
- Digest hashAlg = params.hashAlg;
- int hashLen = hashAlg.getDigestSize();
- byte[] buf = new byte[minCallsR * hashLen];
- byte[] Z = hashSeed ? calcHash(hashAlg, seed) : seed;
- int counter = 0;
- while (counter < minCallsR)
- {
- hashAlg.update(Z, 0, Z.length);
- putInt(hashAlg, counter);
-
- byte[] hash = calcHash(hashAlg);
- System.arraycopy(hash, 0, buf, counter * hashLen, hashLen);
- counter++;
- }
-
- IntegerPolynomial i = new IntegerPolynomial(N);
- while (true)
- {
- int cur = 0;
- for (int index = 0; index != buf.length; index++)
- {
- int O = (int)buf[index] & 0xFF;
- if (O >= 243) // 243 = 3^5
- {
- continue;
- }
-
- for (int terIdx = 0; terIdx < 4; terIdx++)
- {
- int rem3 = O % 3;
- i.coeffs[cur] = rem3 - 1;
- cur++;
- if (cur == N)
- {
- return i;
- }
- O = (O - rem3) / 3;
- }
-
- i.coeffs[cur] = O - 1;
- cur++;
- if (cur == N)
- {
- return i;
- }
- }
-
- if (cur >= N)
- {
- return i;
- }
-
- hashAlg.update(Z, 0, Z.length);
- putInt(hashAlg, counter);
-
- byte[] hash = calcHash(hashAlg);
-
- buf = hash;
-
- counter++;
- }
- }
-
- private void putInt(Digest hashAlg, int counter)
- {
- hashAlg.update((byte)(counter >> 24));
- hashAlg.update((byte)(counter >> 16));
- hashAlg.update((byte)(counter >> 8));
- hashAlg.update((byte)counter);
- }
-
- private byte[] calcHash(Digest hashAlg)
- {
- byte[] tmp = new byte[hashAlg.getDigestSize()];
-
- hashAlg.doFinal(tmp, 0);
-
- return tmp;
- }
-
- private byte[] calcHash(Digest hashAlg, byte[] input)
- {
- byte[] tmp = new byte[hashAlg.getDigestSize()];
-
- hashAlg.update(input, 0, input.length);
- hashAlg.doFinal(tmp, 0);
-
- return tmp;
- }
- /**
- * Decrypts a message.<br/>
- * See P1363.1 section 9.2.3.
- *
- * @param data The message to decrypt
- * @param privKey the corresponding private key
- * @return the decrypted message
- * @throws InvalidCipherTextException if the encrypted data is invalid, or <code>maxLenBytes</code> is greater than 255
- */
- private byte[] decrypt(byte[] data, NTRUEncryptionPrivateKeyParameters privKey)
- throws InvalidCipherTextException
- {
- Polynomial priv_t = privKey.t;
- IntegerPolynomial priv_fp = privKey.fp;
- IntegerPolynomial pub = privKey.h;
- int N = params.N;
- int q = params.q;
- int db = params.db;
- int maxMsgLenBytes = params.maxMsgLenBytes;
- int dm0 = params.dm0;
- int pkLen = params.pkLen;
- int minCallsMask = params.minCallsMask;
- boolean hashSeed = params.hashSeed;
- byte[] oid = params.oid;
-
- if (maxMsgLenBytes > 255)
- {
- throw new DataLengthException("maxMsgLenBytes values bigger than 255 are not supported");
- }
-
- int bLen = db / 8;
-
- IntegerPolynomial e = IntegerPolynomial.fromBinary(data, N, q);
- IntegerPolynomial ci = decrypt(e, priv_t, priv_fp);
-
- if (ci.count(-1) < dm0)
- {
- throw new InvalidCipherTextException("Less than dm0 coefficients equal -1");
- }
- if (ci.count(0) < dm0)
- {
- throw new InvalidCipherTextException("Less than dm0 coefficients equal 0");
- }
- if (ci.count(1) < dm0)
- {
- throw new InvalidCipherTextException("Less than dm0 coefficients equal 1");
- }
-
- IntegerPolynomial cR = (IntegerPolynomial)e.clone();
- cR.sub(ci);
- cR.modPositive(q);
- IntegerPolynomial cR4 = (IntegerPolynomial)cR.clone();
- cR4.modPositive(4);
- byte[] coR4 = cR4.toBinary(4);
- IntegerPolynomial mask = MGF(coR4, N, minCallsMask, hashSeed);
- IntegerPolynomial cMTrin = ci;
- cMTrin.sub(mask);
- cMTrin.mod3();
- byte[] cM = cMTrin.toBinary3Sves();
-
- byte[] cb = new byte[bLen];
- System.arraycopy(cM, 0, cb, 0, bLen);
- int cl = cM[bLen] & 0xFF; // llen=1, so read one byte
- if (cl > maxMsgLenBytes)
- {
- throw new InvalidCipherTextException("Message too long: " + cl + ">" + maxMsgLenBytes);
- }
- byte[] cm = new byte[cl];
- System.arraycopy(cM, bLen + 1, cm, 0, cl);
- byte[] p0 = new byte[cM.length - (bLen + 1 + cl)];
- System.arraycopy(cM, bLen + 1 + cl, p0, 0, p0.length);
- if (!Arrays.constantTimeAreEqual(p0, new byte[p0.length]))
- {
- throw new InvalidCipherTextException("The message is not followed by zeroes");
- }
-
- // sData = OID|m|b|hTrunc
- byte[] bh = pub.toBinary(q);
- byte[] hTrunc = copyOf(bh, pkLen / 8);
- byte[] sData = buildSData(oid, cm, cl, cb, hTrunc);
-
- Polynomial cr = generateBlindingPoly(sData, cm);
- IntegerPolynomial cRPrime = cr.mult(pub);
- cRPrime.modPositive(q);
- if (!cRPrime.equals(cR))
- {
- throw new InvalidCipherTextException("Invalid message encoding");
- }
-
- return cm;
- }
-
- /**
- * @param e
- * @param priv_t a polynomial such that if <code>fastFp=true</code>, <code>f=1+3*priv_t</code>; otherwise, <code>f=priv_t</code>
- * @param priv_fp
- * @return
- */
- protected IntegerPolynomial decrypt(IntegerPolynomial e, Polynomial priv_t, IntegerPolynomial priv_fp)
- {
- IntegerPolynomial a;
- if (params.fastFp)
- {
- a = priv_t.mult(e, params.q);
- a.mult(3);
- a.add(e);
- }
- else
- {
- a = priv_t.mult(e, params.q);
- }
- a.center0(params.q);
- a.mod3();
-
- IntegerPolynomial c = params.fastFp ? a : new DenseTernaryPolynomial(a).mult(priv_fp, 3);
- c.center0(3);
- return c;
- }
-
- private byte[] copyOf(byte[] src, int len)
- {
- byte[] tmp = new byte[len];
-
- System.arraycopy(src, 0, tmp, 0, len < src.length ? len : src.length);
-
- return tmp;
- }
-
- private int log2(int value)
- {
- if (value == 2048)
- {
- return 11;
- }
-
- throw new IllegalStateException("log2 not fully implemented");
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java
deleted file mode 100644
index 158c038..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-public class NTRUParameters
-{
- public static final int TERNARY_POLYNOMIAL_TYPE_SIMPLE = 0;
- public static final int TERNARY_POLYNOMIAL_TYPE_PRODUCT = 1;
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigner.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigner.java
deleted file mode 100644
index 19bf802..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigner.java
+++ /dev/null
@@ -1,263 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.nio.ByteBuffer;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial;
-
-/**
-* Signs, verifies data and generates key pairs.
-* @deprecated the NTRUSigner algorithm was broken in 2012 by Ducas and Nguyen. See
-* <a href="http://www.di.ens.fr/~ducas/NTRUSign_Cryptanalysis/DucasNguyen_Learning.pdf">
-* http://www.di.ens.fr/~ducas/NTRUSign_Cryptanalysis/DucasNguyen_Learning.pdf</a>
-* for details.
-*/
-public class NTRUSigner
-{
- private NTRUSigningParameters params;
- private Digest hashAlg;
- private NTRUSigningPrivateKeyParameters signingKeyPair;
- private NTRUSigningPublicKeyParameters verificationKey;
-
- /**
- * Constructs a new instance with a set of signature parameters.
- *
- * @param params signature parameters
- */
- public NTRUSigner(NTRUSigningParameters params)
- {
- this.params = params;
- }
-
- /**
- * Resets the engine for signing a message.
- *
- * @param forSigning
- * @param params
- */
- public void init(boolean forSigning, CipherParameters params)
- {
- if (forSigning)
- {
- this.signingKeyPair = (NTRUSigningPrivateKeyParameters)params;
- }
- else
- {
- this.verificationKey = (NTRUSigningPublicKeyParameters)params;
- }
- hashAlg = this.params.hashAlg;
- hashAlg.reset();
- }
-
- /**
- * Adds data to sign or verify.
- *
- * @param b data
- */
- public void update(byte b)
- {
- if (hashAlg == null)
- {
- throw new IllegalStateException("Call initSign or initVerify first!");
- }
-
- hashAlg.update(b);
- }
-
- /**
- * Adds data to sign or verify.
- *
- * @param m data
- * @param off offset
- * @param length number of bytes
- */
- public void update(byte[] m, int off, int length)
- {
- if (hashAlg == null)
- {
- throw new IllegalStateException("Call initSign or initVerify first!");
- }
-
- hashAlg.update(m, off, length);
- }
-
- /**
- * Adds data to sign and computes a signature over this data and any data previously added via {@link #update(byte[], int, int)}.
- *
- * @return a signature
- * @throws IllegalStateException if <code>initSign</code> was not called
- */
- public byte[] generateSignature()
- {
- if (hashAlg == null || signingKeyPair == null)
- {
- throw new IllegalStateException("Call initSign first!");
- }
-
- byte[] msgHash = new byte[hashAlg.getDigestSize()];
-
- hashAlg.doFinal(msgHash, 0);
- return signHash(msgHash, signingKeyPair);
- }
-
- private byte[] signHash(byte[] msgHash, NTRUSigningPrivateKeyParameters kp)
- {
- int r = 0;
- IntegerPolynomial s;
- IntegerPolynomial i;
-
- NTRUSigningPublicKeyParameters kPub = kp.getPublicKey();
- do
- {
- r++;
- if (r > params.signFailTolerance)
- {
- throw new IllegalStateException("Signing failed: too many retries (max=" + params.signFailTolerance + ")");
- }
- i = createMsgRep(msgHash, r);
- s = sign(i, kp);
- }
- while (!verify(i, s, kPub.h));
-
- byte[] rawSig = s.toBinary(params.q);
- ByteBuffer sbuf = ByteBuffer.allocate(rawSig.length + 4);
- sbuf.put(rawSig);
- sbuf.putInt(r);
- return sbuf.array();
- }
-
- private IntegerPolynomial sign(IntegerPolynomial i, NTRUSigningPrivateKeyParameters kp)
- {
- int N = params.N;
- int q = params.q;
- int perturbationBases = params.B;
-
- NTRUSigningPrivateKeyParameters kPriv = kp;
- NTRUSigningPublicKeyParameters kPub = kp.getPublicKey();
-
- IntegerPolynomial s = new IntegerPolynomial(N);
- int iLoop = perturbationBases;
- while (iLoop >= 1)
- {
- Polynomial f = kPriv.getBasis(iLoop).f;
- Polynomial fPrime = kPriv.getBasis(iLoop).fPrime;
-
- IntegerPolynomial y = f.mult(i);
- y.div(q);
- y = fPrime.mult(y);
-
- IntegerPolynomial x = fPrime.mult(i);
- x.div(q);
- x = f.mult(x);
-
- IntegerPolynomial si = y;
- si.sub(x);
- s.add(si);
-
- IntegerPolynomial hi = (IntegerPolynomial)kPriv.getBasis(iLoop).h.clone();
- if (iLoop > 1)
- {
- hi.sub(kPriv.getBasis(iLoop - 1).h);
- }
- else
- {
- hi.sub(kPub.h);
- }
- i = si.mult(hi, q);
-
- iLoop--;
- }
-
- Polynomial f = kPriv.getBasis(0).f;
- Polynomial fPrime = kPriv.getBasis(0).fPrime;
-
- IntegerPolynomial y = f.mult(i);
- y.div(q);
- y = fPrime.mult(y);
-
- IntegerPolynomial x = fPrime.mult(i);
- x.div(q);
- x = f.mult(x);
-
- y.sub(x);
- s.add(y);
- s.modPositive(q);
- return s;
- }
-
- /**
- * Verifies a signature for any data previously added via {@link #update(byte[], int, int)}.
- *
- * @param sig a signature
- * @return whether the signature is valid
- * @throws IllegalStateException if <code>initVerify</code> was not called
- */
- public boolean verifySignature(byte[] sig)
- {
- if (hashAlg == null || verificationKey == null)
- {
- throw new IllegalStateException("Call initVerify first!");
- }
-
- byte[] msgHash = new byte[hashAlg.getDigestSize()];
-
- hashAlg.doFinal(msgHash, 0);
-
- return verifyHash(msgHash, sig, verificationKey);
- }
-
- private boolean verifyHash(byte[] msgHash, byte[] sig, NTRUSigningPublicKeyParameters pub)
- {
- ByteBuffer sbuf = ByteBuffer.wrap(sig);
- byte[] rawSig = new byte[sig.length - 4];
- sbuf.get(rawSig);
- IntegerPolynomial s = IntegerPolynomial.fromBinary(rawSig, params.N, params.q);
- int r = sbuf.getInt();
- return verify(createMsgRep(msgHash, r), s, pub.h);
- }
-
- private boolean verify(IntegerPolynomial i, IntegerPolynomial s, IntegerPolynomial h)
- {
- int q = params.q;
- double normBoundSq = params.normBoundSq;
- double betaSq = params.betaSq;
-
- IntegerPolynomial t = h.mult(s, q);
- t.sub(i);
- long centeredNormSq = (long)(s.centeredNormSq(q) + betaSq * t.centeredNormSq(q));
- return centeredNormSq <= normBoundSq;
- }
-
- protected IntegerPolynomial createMsgRep(byte[] msgHash, int r)
- {
- int N = params.N;
- int q = params.q;
-
- int c = 31 - Integer.numberOfLeadingZeros(q);
- int B = (c + 7) / 8;
- IntegerPolynomial i = new IntegerPolynomial(N);
-
- ByteBuffer cbuf = ByteBuffer.allocate(msgHash.length + 4);
- cbuf.put(msgHash);
- cbuf.putInt(r);
- NTRUSignerPrng prng = new NTRUSignerPrng(cbuf.array(), params.hashAlg);
-
- for (int t = 0; t < N; t++)
- {
- byte[] o = prng.nextBytes(B);
- int hi = o[o.length - 1];
- hi >>= 8 * B - c;
- hi <<= 8 * B - c;
- o[o.length - 1] = (byte)hi;
-
- ByteBuffer obuf = ByteBuffer.allocate(4);
- obuf.put(o);
- obuf.rewind();
- // reverse byte order so it matches the endianness of java ints
- i.coeffs[t] = Integer.reverseBytes(obuf.getInt());
- }
- return i;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSignerPrng.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSignerPrng.java
deleted file mode 100644
index 77ed63a..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSignerPrng.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.nio.ByteBuffer;
-
-import org.bouncycastle.crypto.Digest;
-
-/**
- * An implementation of the deterministic pseudo-random generator in EESS section 3.7.3.1
- */
-public class NTRUSignerPrng
-{
- private int counter;
- private byte[] seed;
- private Digest hashAlg;
-
- /**
- * Constructs a new PRNG and seeds it with a byte array.
- *
- * @param seed a seed
- * @param hashAlg the hash algorithm to use
- */
- NTRUSignerPrng(byte[] seed, Digest hashAlg)
- {
- counter = 0;
- this.seed = seed;
- this.hashAlg = hashAlg;
- }
-
- /**
- * Returns <code>n</code> random bytes
- *
- * @param n number of bytes to return
- * @return the next <code>n</code> random bytes
- */
- byte[] nextBytes(int n)
- {
- ByteBuffer buf = ByteBuffer.allocate(n);
-
- while (buf.hasRemaining())
- {
- ByteBuffer cbuf = ByteBuffer.allocate(seed.length + 4);
- cbuf.put(seed);
- cbuf.putInt(counter);
- byte[] array = cbuf.array();
- byte[] hash = new byte[hashAlg.getDigestSize()];
-
- hashAlg.update(array, 0, array.length);
-
- hashAlg.doFinal(hash, 0);
-
- if (buf.remaining() < hash.length)
- {
- buf.put(hash, 0, buf.remaining());
- }
- else
- {
- buf.put(hash);
- }
- counter++;
- }
-
- return buf.array();
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningKeyGenerationParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningKeyGenerationParameters.java
deleted file mode 100644
index b6ff8c5..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningKeyGenerationParameters.java
+++ /dev/null
@@ -1,407 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.SecureRandom;
-import java.text.DecimalFormat;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.KeyGenerationParameters;
-import org.bouncycastle.crypto.digests.SHA256Digest;
-import org.bouncycastle.crypto.digests.SHA512Digest;
-
-/**
- * A set of parameters for NtruSign. Several predefined parameter sets are available and new ones can be created as well.
- */
-public class NTRUSigningKeyGenerationParameters
- extends KeyGenerationParameters
- implements Cloneable
-{
- public static final int BASIS_TYPE_STANDARD = 0;
- public static final int BASIS_TYPE_TRANSPOSE = 1;
-
- public static final int KEY_GEN_ALG_RESULTANT = 0;
- public static final int KEY_GEN_ALG_FLOAT = 1;
-
- /**
- * Gives 128 bits of security
- */
- public static final NTRUSigningKeyGenerationParameters APR2011_439 = new NTRUSigningKeyGenerationParameters(439, 2048, 146, 1, BASIS_TYPE_TRANSPOSE, 0.165, 490, 280, false, true, KEY_GEN_ALG_RESULTANT, new SHA256Digest());
-
- /**
- * Like <code>APR2011_439</code>, this parameter set gives 128 bits of security but uses product-form polynomials
- */
- public static final NTRUSigningKeyGenerationParameters APR2011_439_PROD = new NTRUSigningKeyGenerationParameters(439, 2048, 9, 8, 5, 1, BASIS_TYPE_TRANSPOSE, 0.165, 490, 280, false, true, KEY_GEN_ALG_RESULTANT, new SHA256Digest());
-
- /**
- * Gives 256 bits of security
- */
- public static final NTRUSigningKeyGenerationParameters APR2011_743 = new NTRUSigningKeyGenerationParameters(743, 2048, 248, 1, BASIS_TYPE_TRANSPOSE, 0.127, 560, 360, true, false, KEY_GEN_ALG_RESULTANT, new SHA512Digest());
-
- /**
- * Like <code>APR2011_439</code>, this parameter set gives 256 bits of security but uses product-form polynomials
- */
- public static final NTRUSigningKeyGenerationParameters APR2011_743_PROD = new NTRUSigningKeyGenerationParameters(743, 2048, 11, 11, 15, 1, BASIS_TYPE_TRANSPOSE, 0.127, 560, 360, true, false, KEY_GEN_ALG_RESULTANT, new SHA512Digest());
-
- /**
- * Generates key pairs quickly. Use for testing only.
- */
- public static final NTRUSigningKeyGenerationParameters TEST157 = new NTRUSigningKeyGenerationParameters(157, 256, 29, 1, BASIS_TYPE_TRANSPOSE, 0.38, 200, 80, false, false, KEY_GEN_ALG_RESULTANT, new SHA256Digest());
- /**
- * Generates key pairs quickly. Use for testing only.
- */
- public static final NTRUSigningKeyGenerationParameters TEST157_PROD = new NTRUSigningKeyGenerationParameters(157, 256, 5, 5, 8, 1, BASIS_TYPE_TRANSPOSE, 0.38, 200, 80, false, false, KEY_GEN_ALG_RESULTANT, new SHA256Digest());
-
-
- public int N;
- public int q;
- public int d, d1, d2, d3, B;
- double beta;
- public double betaSq;
- double normBound;
- public double normBoundSq;
- public int signFailTolerance = 100;
- double keyNormBound;
- public double keyNormBoundSq;
- public boolean primeCheck; // true if N and 2N+1 are prime
- public int basisType;
- int bitsF = 6; // max #bits needed to encode one coefficient of the polynomial F
- public boolean sparse; // whether to treat ternary polynomials as sparsely populated
- public int keyGenAlg;
- public Digest hashAlg;
- public int polyType;
-
- /**
- * Constructs a parameter set that uses ternary private keys (i.e. <code>polyType=SIMPLE</code>).
- *
- * @param N number of polynomial coefficients
- * @param q modulus
- * @param d number of -1's in the private polynomials <code>f</code> and <code>g</code>
- * @param B number of perturbations
- * @param basisType whether to use the standard or transpose lattice
- * @param beta balancing factor for the transpose lattice
- * @param normBound maximum norm for valid signatures
- * @param keyNormBound maximum norm for the ploynomials <code>F</code> and <code>G</code>
- * @param primeCheck whether <code>2N+1</code> is prime
- * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial})
- * @param keyGenAlg <code>RESULTANT</code> produces better bases, <code>FLOAT</code> is slightly faster. <code>RESULTANT</code> follows the EESS standard while <code>FLOAT</code> is described in Hoffstein et al: An Introduction to Mathematical Cryptography.
- * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>. The <code>MessageDigest</code> must support the <code>getDigestLength()</code> method.
- */
- public NTRUSigningKeyGenerationParameters(int N, int q, int d, int B, int basisType, double beta, double normBound, double keyNormBound, boolean primeCheck, boolean sparse, int keyGenAlg, Digest hashAlg)
- {
- super(new SecureRandom(), N);
- this.N = N;
- this.q = q;
- this.d = d;
- this.B = B;
- this.basisType = basisType;
- this.beta = beta;
- this.normBound = normBound;
- this.keyNormBound = keyNormBound;
- this.primeCheck = primeCheck;
- this.sparse = sparse;
- this.keyGenAlg = keyGenAlg;
- this.hashAlg = hashAlg;
- polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE;
- init();
- }
-
- /**
- * Constructs a parameter set that uses product-form private keys (i.e. <code>polyType=PRODUCT</code>).
- *
- * @param N number of polynomial coefficients
- * @param q modulus
- * @param d1 number of -1's in the private polynomials <code>f</code> and <code>g</code>
- * @param d2 number of -1's in the private polynomials <code>f</code> and <code>g</code>
- * @param d3 number of -1's in the private polynomials <code>f</code> and <code>g</code>
- * @param B number of perturbations
- * @param basisType whether to use the standard or transpose lattice
- * @param beta balancing factor for the transpose lattice
- * @param normBound maximum norm for valid signatures
- * @param keyNormBound maximum norm for the ploynomials <code>F</code> and <code>G</code>
- * @param primeCheck whether <code>2N+1</code> is prime
- * @param sparse whether to treat ternary polynomials as sparsely populated ({@link org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial})
- * @param keyGenAlg <code>RESULTANT</code> produces better bases, <code>FLOAT</code> is slightly faster. <code>RESULTANT</code> follows the EESS standard while <code>FLOAT</code> is described in Hoffstein et al: An Introduction to Mathematical Cryptography.
- * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>. The <code>MessageDigest</code> must support the <code>getDigestLength()</code> method.
- */
- public NTRUSigningKeyGenerationParameters(int N, int q, int d1, int d2, int d3, int B, int basisType, double beta, double normBound, double keyNormBound, boolean primeCheck, boolean sparse, int keyGenAlg, Digest hashAlg)
- {
- super(new SecureRandom(), N);
- this.N = N;
- this.q = q;
- this.d1 = d1;
- this.d2 = d2;
- this.d3 = d3;
- this.B = B;
- this.basisType = basisType;
- this.beta = beta;
- this.normBound = normBound;
- this.keyNormBound = keyNormBound;
- this.primeCheck = primeCheck;
- this.sparse = sparse;
- this.keyGenAlg = keyGenAlg;
- this.hashAlg = hashAlg;
- polyType = NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT;
- init();
- }
-
- private void init()
- {
- betaSq = beta * beta;
- normBoundSq = normBound * normBound;
- keyNormBoundSq = keyNormBound * keyNormBound;
- }
-
- /**
- * Reads a parameter set from an input stream.
- *
- * @param is an input stream
- * @throws java.io.IOException
- */
- public NTRUSigningKeyGenerationParameters(InputStream is)
- throws IOException
- {
- super(new SecureRandom(), 0); // TODO:
- DataInputStream dis = new DataInputStream(is);
- N = dis.readInt();
- q = dis.readInt();
- d = dis.readInt();
- d1 = dis.readInt();
- d2 = dis.readInt();
- d3 = dis.readInt();
- B = dis.readInt();
- basisType = dis.readInt();
- beta = dis.readDouble();
- normBound = dis.readDouble();
- keyNormBound = dis.readDouble();
- signFailTolerance = dis.readInt();
- primeCheck = dis.readBoolean();
- sparse = dis.readBoolean();
- bitsF = dis.readInt();
- keyGenAlg = dis.read();
- String alg = dis.readUTF();
- if ("SHA-512".equals(alg))
- {
- hashAlg = new SHA512Digest();
- }
- else if ("SHA-256".equals(alg))
- {
- hashAlg = new SHA256Digest();
- }
- polyType = dis.read();
- init();
- }
-
- /**
- * Writes the parameter set to an output stream
- *
- * @param os an output stream
- * @throws java.io.IOException
- */
- public void writeTo(OutputStream os)
- throws IOException
- {
- DataOutputStream dos = new DataOutputStream(os);
- dos.writeInt(N);
- dos.writeInt(q);
- dos.writeInt(d);
- dos.writeInt(d1);
- dos.writeInt(d2);
- dos.writeInt(d3);
- dos.writeInt(B);
- dos.writeInt(basisType);
- dos.writeDouble(beta);
- dos.writeDouble(normBound);
- dos.writeDouble(keyNormBound);
- dos.writeInt(signFailTolerance);
- dos.writeBoolean(primeCheck);
- dos.writeBoolean(sparse);
- dos.writeInt(bitsF);
- dos.write(keyGenAlg);
- dos.writeUTF(hashAlg.getAlgorithmName());
- dos.write(polyType);
- }
-
- public NTRUSigningParameters getSigningParameters()
- {
- return new NTRUSigningParameters(N, q, d, B, beta, normBound, hashAlg);
- }
-
- public NTRUSigningKeyGenerationParameters clone()
- {
- if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE)
- {
- return new NTRUSigningKeyGenerationParameters(N, q, d, B, basisType, beta, normBound, keyNormBound, primeCheck, sparse, keyGenAlg, hashAlg);
- }
- else
- {
- return new NTRUSigningKeyGenerationParameters(N, q, d1, d2, d3, B, basisType, beta, normBound, keyNormBound, primeCheck, sparse, keyGenAlg, hashAlg);
- }
- }
-
- public int hashCode()
- {
- final int prime = 31;
- int result = 1;
- result = prime * result + B;
- result = prime * result + N;
- result = prime * result + basisType;
- long temp;
- temp = Double.doubleToLongBits(beta);
- result = prime * result + (int)(temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(betaSq);
- result = prime * result + (int)(temp ^ (temp >>> 32));
- result = prime * result + bitsF;
- result = prime * result + d;
- result = prime * result + d1;
- result = prime * result + d2;
- result = prime * result + d3;
- result = prime * result + ((hashAlg == null) ? 0 : hashAlg.getAlgorithmName().hashCode());
- result = prime * result + keyGenAlg;
- temp = Double.doubleToLongBits(keyNormBound);
- result = prime * result + (int)(temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(keyNormBoundSq);
- result = prime * result + (int)(temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(normBound);
- result = prime * result + (int)(temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(normBoundSq);
- result = prime * result + (int)(temp ^ (temp >>> 32));
- result = prime * result + polyType;
- result = prime * result + (primeCheck ? 1231 : 1237);
- result = prime * result + q;
- result = prime * result + signFailTolerance;
- result = prime * result + (sparse ? 1231 : 1237);
- return result;
- }
-
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- if (obj == null)
- {
- return false;
- }
- if (!(obj instanceof NTRUSigningKeyGenerationParameters))
- {
- return false;
- }
- NTRUSigningKeyGenerationParameters other = (NTRUSigningKeyGenerationParameters)obj;
- if (B != other.B)
- {
- return false;
- }
- if (N != other.N)
- {
- return false;
- }
- if (basisType != other.basisType)
- {
- return false;
- }
- if (Double.doubleToLongBits(beta) != Double.doubleToLongBits(other.beta))
- {
- return false;
- }
- if (Double.doubleToLongBits(betaSq) != Double.doubleToLongBits(other.betaSq))
- {
- return false;
- }
- if (bitsF != other.bitsF)
- {
- return false;
- }
- if (d != other.d)
- {
- return false;
- }
- if (d1 != other.d1)
- {
- return false;
- }
- if (d2 != other.d2)
- {
- return false;
- }
- if (d3 != other.d3)
- {
- return false;
- }
- if (hashAlg == null)
- {
- if (other.hashAlg != null)
- {
- return false;
- }
- }
- else if (!hashAlg.getAlgorithmName().equals(other.hashAlg.getAlgorithmName()))
- {
- return false;
- }
- if (keyGenAlg != other.keyGenAlg)
- {
- return false;
- }
- if (Double.doubleToLongBits(keyNormBound) != Double.doubleToLongBits(other.keyNormBound))
- {
- return false;
- }
- if (Double.doubleToLongBits(keyNormBoundSq) != Double.doubleToLongBits(other.keyNormBoundSq))
- {
- return false;
- }
- if (Double.doubleToLongBits(normBound) != Double.doubleToLongBits(other.normBound))
- {
- return false;
- }
- if (Double.doubleToLongBits(normBoundSq) != Double.doubleToLongBits(other.normBoundSq))
- {
- return false;
- }
- if (polyType != other.polyType)
- {
- return false;
- }
- if (primeCheck != other.primeCheck)
- {
- return false;
- }
- if (q != other.q)
- {
- return false;
- }
- if (signFailTolerance != other.signFailTolerance)
- {
- return false;
- }
- if (sparse != other.sparse)
- {
- return false;
- }
- return true;
- }
-
- public String toString()
- {
- DecimalFormat format = new DecimalFormat("0.00");
-
- StringBuilder output = new StringBuilder("SignatureParameters(N=" + N + " q=" + q);
- if (polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE)
- {
- output.append(" polyType=SIMPLE d=" + d);
- }
- else
- {
- output.append(" polyType=PRODUCT d1=" + d1 + " d2=" + d2 + " d3=" + d3);
- }
- output.append(" B=" + B + " basisType=" + basisType + " beta=" + format.format(beta) +
- " normBound=" + format.format(normBound) + " keyNormBound=" + format.format(keyNormBound) +
- " prime=" + primeCheck + " sparse=" + sparse + " keyGenAlg=" + keyGenAlg + " hashAlg=" + hashAlg + ")");
- return output.toString();
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningKeyPairGenerator.java
deleted file mode 100644
index 1471509..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningKeyPairGenerator.java
+++ /dev/null
@@ -1,357 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
-import org.bouncycastle.crypto.KeyGenerationParameters;
-import org.bouncycastle.pqc.math.ntru.euclid.BigIntEuclidean;
-import org.bouncycastle.pqc.math.ntru.polynomial.BigDecimalPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.BigIntPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.Resultant;
-
-import static java.math.BigInteger.ONE;
-import static java.math.BigInteger.ZERO;
-
-public class NTRUSigningKeyPairGenerator
- implements AsymmetricCipherKeyPairGenerator
-{
- private NTRUSigningKeyGenerationParameters params;
-
- public void init(KeyGenerationParameters param)
- {
- this.params = (NTRUSigningKeyGenerationParameters)param;
- }
-
- /**
- * Generates a new signature key pair. Starts <code>B+1</code> threads.
- *
- * @return a key pair
- */
- public AsymmetricCipherKeyPair generateKeyPair()
- {
- NTRUSigningPublicKeyParameters pub = null;
- ExecutorService executor = Executors.newCachedThreadPool();
- List<Future<NTRUSigningPrivateKeyParameters.Basis>> bases = new ArrayList<Future<NTRUSigningPrivateKeyParameters.Basis>>();
- for (int k = params.B; k >= 0; k--)
- {
- bases.add(executor.submit(new BasisGenerationTask()));
- }
- executor.shutdown();
-
- List<NTRUSigningPrivateKeyParameters.Basis> basises = new ArrayList<NTRUSigningPrivateKeyParameters.Basis>();
-
- for (int k = params.B; k >= 0; k--)
- {
- Future<NTRUSigningPrivateKeyParameters.Basis> basis = bases.get(k);
- try
- {
- basises.add(basis.get());
- if (k == params.B)
- {
- pub = new NTRUSigningPublicKeyParameters(basis.get().h, params.getSigningParameters());
- }
- }
- catch (Exception e)
- {
- throw new IllegalStateException(e);
- }
- }
- NTRUSigningPrivateKeyParameters priv = new NTRUSigningPrivateKeyParameters(basises, pub);
- AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(pub, priv);
- return kp;
- }
-
- /**
- * Generates a new signature key pair. Runs in a single thread.
- *
- * @return a key pair
- */
- public AsymmetricCipherKeyPair generateKeyPairSingleThread()
- {
- List<NTRUSigningPrivateKeyParameters.Basis> basises = new ArrayList<NTRUSigningPrivateKeyParameters.Basis>();
- NTRUSigningPublicKeyParameters pub = null;
- for (int k = params.B; k >= 0; k--)
- {
- NTRUSigningPrivateKeyParameters.Basis basis = generateBoundedBasis();
- basises.add(basis);
- if (k == 0)
- {
- pub = new NTRUSigningPublicKeyParameters(basis.h, params.getSigningParameters());
- }
- }
- NTRUSigningPrivateKeyParameters priv = new NTRUSigningPrivateKeyParameters(basises, pub);
- return new AsymmetricCipherKeyPair(pub, priv);
- }
-
-
- /**
- * Implementation of the optional steps 20 through 26 in EESS1v2.pdf, section 3.5.1.1.
- * This doesn't seem to have much of an effect and sometimes actually increases the
- * norm of F, but on average it slightly reduces the norm.<br/>
- * This method changes <code>F</code> and <code>g</code> but leaves <code>f</code> and
- * <code>g</code> unchanged.
- *
- * @param f
- * @param g
- * @param F
- * @param G
- * @param N
- */
- private void minimizeFG(IntegerPolynomial f, IntegerPolynomial g, IntegerPolynomial F, IntegerPolynomial G, int N)
- {
- int E = 0;
- for (int j = 0; j < N; j++)
- {
- E += 2 * N * (f.coeffs[j] * f.coeffs[j] + g.coeffs[j] * g.coeffs[j]);
- }
-
- // [f(1)+g(1)]^2 = 4
- E -= 4;
-
- IntegerPolynomial u = (IntegerPolynomial)f.clone();
- IntegerPolynomial v = (IntegerPolynomial)g.clone();
- int j = 0;
- int k = 0;
- int maxAdjustment = N;
- while (k < maxAdjustment && j < N)
- {
- int D = 0;
- int i = 0;
- while (i < N)
- {
- int D1 = F.coeffs[i] * f.coeffs[i];
- int D2 = G.coeffs[i] * g.coeffs[i];
- int D3 = 4 * N * (D1 + D2);
- D += D3;
- i++;
- }
- // f(1)+g(1) = 2
- int D1 = 4 * (F.sumCoeffs() + G.sumCoeffs());
- D -= D1;
-
- if (D > E)
- {
- F.sub(u);
- G.sub(v);
- k++;
- j = 0;
- }
- else if (D < -E)
- {
- F.add(u);
- G.add(v);
- k++;
- j = 0;
- }
- j++;
- u.rotate1();
- v.rotate1();
- }
- }
-
- /**
- * Creates a NTRUSigner basis consisting of polynomials <code>f, g, F, G, h</code>.<br/>
- * If <code>KeyGenAlg=FLOAT</code>, the basis may not be valid and this method must be rerun if that is the case.<br/>
- *
- * @see #generateBoundedBasis()
- */
- private FGBasis generateBasis()
- {
- int N = params.N;
- int q = params.q;
- int d = params.d;
- int d1 = params.d1;
- int d2 = params.d2;
- int d3 = params.d3;
- int basisType = params.basisType;
-
- Polynomial f;
- IntegerPolynomial fInt;
- Polynomial g;
- IntegerPolynomial gInt;
- IntegerPolynomial fq;
- Resultant rf;
- Resultant rg;
- BigIntEuclidean r;
-
- int _2n1 = 2 * N + 1;
- boolean primeCheck = params.primeCheck;
-
- do
- {
- do
- {
- f = params.polyType== NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? DenseTernaryPolynomial.generateRandom(N, d + 1, d, new SecureRandom()) : ProductFormPolynomial.generateRandom(N, d1, d2, d3 + 1, d3, new SecureRandom());
- fInt = f.toIntegerPolynomial();
- }
- while (primeCheck && fInt.resultant(_2n1).res.equals(ZERO));
- fq = fInt.invertFq(q);
- }
- while (fq == null);
- rf = fInt.resultant();
-
- do
- {
- do
- {
- do
- {
- g = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? DenseTernaryPolynomial.generateRandom(N, d + 1, d, new SecureRandom()) : ProductFormPolynomial.generateRandom(N, d1, d2, d3 + 1, d3, new SecureRandom());
- gInt = g.toIntegerPolynomial();
- }
- while (primeCheck && gInt.resultant(_2n1).res.equals(ZERO));
- }
- while (gInt.invertFq(q) == null);
- rg = gInt.resultant();
- r = BigIntEuclidean.calculate(rf.res, rg.res);
- }
- while (!r.gcd.equals(ONE));
-
- BigIntPolynomial A = (BigIntPolynomial)rf.rho.clone();
- A.mult(r.x.multiply(BigInteger.valueOf(q)));
- BigIntPolynomial B = (BigIntPolynomial)rg.rho.clone();
- B.mult(r.y.multiply(BigInteger.valueOf(-q)));
-
- BigIntPolynomial C;
- if (params.keyGenAlg == NTRUSigningKeyGenerationParameters.KEY_GEN_ALG_RESULTANT)
- {
- int[] fRevCoeffs = new int[N];
- int[] gRevCoeffs = new int[N];
- fRevCoeffs[0] = fInt.coeffs[0];
- gRevCoeffs[0] = gInt.coeffs[0];
- for (int i = 1; i < N; i++)
- {
- fRevCoeffs[i] = fInt.coeffs[N - i];
- gRevCoeffs[i] = gInt.coeffs[N - i];
- }
- IntegerPolynomial fRev = new IntegerPolynomial(fRevCoeffs);
- IntegerPolynomial gRev = new IntegerPolynomial(gRevCoeffs);
-
- IntegerPolynomial t = f.mult(fRev);
- t.add(g.mult(gRev));
- Resultant rt = t.resultant();
- C = fRev.mult(B); // fRev.mult(B) is actually faster than new SparseTernaryPolynomial(fRev).mult(B), possibly due to cache locality?
- C.add(gRev.mult(A));
- C = C.mult(rt.rho);
- C.div(rt.res);
- }
- else
- { // KeyGenAlg.FLOAT
- // calculate ceil(log10(N))
- int log10N = 0;
- for (int i = 1; i < N; i *= 10)
- {
- log10N++;
- }
-
- // * Cdec needs to be accurate to 1 decimal place so it can be correctly rounded;
- // * fInv loses up to (#digits of longest coeff of B) places in fInv.mult(B);
- // * multiplying fInv by B also multiplies the rounding error by a factor of N;
- // so make #decimal places of fInv the sum of the above.
- BigDecimalPolynomial fInv = rf.rho.div(new BigDecimal(rf.res), B.getMaxCoeffLength() + 1 + log10N);
- BigDecimalPolynomial gInv = rg.rho.div(new BigDecimal(rg.res), A.getMaxCoeffLength() + 1 + log10N);
-
- BigDecimalPolynomial Cdec = fInv.mult(B);
- Cdec.add(gInv.mult(A));
- Cdec.halve();
- C = Cdec.round();
- }
-
- BigIntPolynomial F = (BigIntPolynomial)B.clone();
- F.sub(f.mult(C));
- BigIntPolynomial G = (BigIntPolynomial)A.clone();
- G.sub(g.mult(C));
-
- IntegerPolynomial FInt = new IntegerPolynomial(F);
- IntegerPolynomial GInt = new IntegerPolynomial(G);
- minimizeFG(fInt, gInt, FInt, GInt, N);
-
- Polynomial fPrime;
- IntegerPolynomial h;
- if (basisType == NTRUSigningKeyGenerationParameters.BASIS_TYPE_STANDARD)
- {
- fPrime = FInt;
- h = g.mult(fq, q);
- }
- else
- {
- fPrime = g;
- h = FInt.mult(fq, q);
- }
- h.modPositive(q);
-
- return new FGBasis(f, fPrime, h, FInt, GInt, params);
- }
-
- /**
- * Creates a basis such that <code>|F| &lt; keyNormBound</code> and <code>|G| &lt; keyNormBound</code>
- *
- * @return a NTRUSigner basis
- */
- public NTRUSigningPrivateKeyParameters.Basis generateBoundedBasis()
- {
- while (true)
- {
- FGBasis basis = generateBasis();
- if (basis.isNormOk())
- {
- return basis;
- }
- }
- }
-
- private class BasisGenerationTask
- implements Callable<NTRUSigningPrivateKeyParameters.Basis>
- {
-
-
- public NTRUSigningPrivateKeyParameters.Basis call()
- throws Exception
- {
- return generateBoundedBasis();
- }
- }
-
- /**
- * A subclass of Basis that additionally contains the polynomials <code>F</code> and <code>G</code>.
- */
- public class FGBasis
- extends NTRUSigningPrivateKeyParameters.Basis
- {
- public IntegerPolynomial F;
- public IntegerPolynomial G;
-
- FGBasis(Polynomial f, Polynomial fPrime, IntegerPolynomial h, IntegerPolynomial F, IntegerPolynomial G, NTRUSigningKeyGenerationParameters params)
- {
- super(f, fPrime, h, params);
- this.F = F;
- this.G = G;
- }
-
- /**
- * Returns <code>true</code> if the norms of the polynomials <code>F</code> and <code>G</code>
- * are within {@link NTRUSigningKeyGenerationParameters#keyNormBound}.
- *
- * @return
- */
- boolean isNormOk()
- {
- double keyNormBoundSq = params.keyNormBoundSq;
- int q = params.q;
- return (F.centeredNormSq(q) < keyNormBoundSq && G.centeredNormSq(q) < keyNormBoundSq);
- }
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningParameters.java
deleted file mode 100644
index 2f018b0..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningParameters.java
+++ /dev/null
@@ -1,269 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.text.DecimalFormat;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA256Digest;
-import org.bouncycastle.crypto.digests.SHA512Digest;
-
-/**
- * A set of parameters for NtruSign. Several predefined parameter sets are available and new ones can be created as well.
- */
-public class NTRUSigningParameters
- implements Cloneable
-{
- public int N;
- public int q;
- public int d, d1, d2, d3, B;
- double beta;
- public double betaSq;
- double normBound;
- public double normBoundSq;
- public int signFailTolerance = 100;
- int bitsF = 6; // max #bits needed to encode one coefficient of the polynomial F
- public Digest hashAlg;
-
- /**
- * Constructs a parameter set that uses ternary private keys (i.e. <code>polyType=SIMPLE</code>).
- *
- * @param N number of polynomial coefficients
- * @param q modulus
- * @param d number of -1's in the private polynomials <code>f</code> and <code>g</code>
- * @param B number of perturbations
- * @param beta balancing factor for the transpose lattice
- * @param normBound maximum norm for valid signatures
- * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>. The <code>MessageDigest</code> must support the <code>getDigestLength()</code> method.
- */
- public NTRUSigningParameters(int N, int q, int d, int B, double beta, double normBound, Digest hashAlg)
- {
- this.N = N;
- this.q = q;
- this.d = d;
- this.B = B;
- this.beta = beta;
- this.normBound = normBound;
- this.hashAlg = hashAlg;
- init();
- }
-
- /**
- * Constructs a parameter set that uses product-form private keys (i.e. <code>polyType=PRODUCT</code>).
- *
- * @param N number of polynomial coefficients
- * @param q modulus
- * @param d1 number of -1's in the private polynomials <code>f</code> and <code>g</code>
- * @param d2 number of -1's in the private polynomials <code>f</code> and <code>g</code>
- * @param d3 number of -1's in the private polynomials <code>f</code> and <code>g</code>
- * @param B number of perturbations
- * @param beta balancing factor for the transpose lattice
- * @param normBound maximum norm for valid signatures
- * @param keyNormBound maximum norm for the ploynomials <code>F</code> and <code>G</code>
- * @param hashAlg a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>. The <code>MessageDigest</code> must support the <code>getDigestLength()</code> method.
- */
- public NTRUSigningParameters(int N, int q, int d1, int d2, int d3, int B, double beta, double normBound, double keyNormBound, Digest hashAlg)
- {
- this.N = N;
- this.q = q;
- this.d1 = d1;
- this.d2 = d2;
- this.d3 = d3;
- this.B = B;
- this.beta = beta;
- this.normBound = normBound;
- this.hashAlg = hashAlg;
- init();
- }
-
- private void init()
- {
- betaSq = beta * beta;
- normBoundSq = normBound * normBound;
- }
-
- /**
- * Reads a parameter set from an input stream.
- *
- * @param is an input stream
- * @throws IOException
- */
- public NTRUSigningParameters(InputStream is)
- throws IOException
- {
- DataInputStream dis = new DataInputStream(is);
- N = dis.readInt();
- q = dis.readInt();
- d = dis.readInt();
- d1 = dis.readInt();
- d2 = dis.readInt();
- d3 = dis.readInt();
- B = dis.readInt();
- beta = dis.readDouble();
- normBound = dis.readDouble();
- signFailTolerance = dis.readInt();
- bitsF = dis.readInt();
- String alg = dis.readUTF();
- if ("SHA-512".equals(alg))
- {
- hashAlg = new SHA512Digest();
- }
- else if ("SHA-256".equals(alg))
- {
- hashAlg = new SHA256Digest();
- }
- init();
- }
-
- /**
- * Writes the parameter set to an output stream
- *
- * @param os an output stream
- * @throws IOException
- */
- public void writeTo(OutputStream os)
- throws IOException
- {
- DataOutputStream dos = new DataOutputStream(os);
- dos.writeInt(N);
- dos.writeInt(q);
- dos.writeInt(d);
- dos.writeInt(d1);
- dos.writeInt(d2);
- dos.writeInt(d3);
- dos.writeInt(B);
- dos.writeDouble(beta);
- dos.writeDouble(normBound);
- dos.writeInt(signFailTolerance);
- dos.writeInt(bitsF);
- dos.writeUTF(hashAlg.getAlgorithmName());
- }
-
- public NTRUSigningParameters clone()
- {
- return new NTRUSigningParameters(N, q, d, B, beta, normBound, hashAlg);
- }
-
- public int hashCode()
- {
- final int prime = 31;
- int result = 1;
- result = prime * result + B;
- result = prime * result + N;
- long temp;
- temp = Double.doubleToLongBits(beta);
- result = prime * result + (int)(temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(betaSq);
- result = prime * result + (int)(temp ^ (temp >>> 32));
- result = prime * result + bitsF;
- result = prime * result + d;
- result = prime * result + d1;
- result = prime * result + d2;
- result = prime * result + d3;
- result = prime * result + ((hashAlg == null) ? 0 : hashAlg.getAlgorithmName().hashCode());
- temp = Double.doubleToLongBits(normBound);
- result = prime * result + (int)(temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(normBoundSq);
- result = prime * result + (int)(temp ^ (temp >>> 32));
- result = prime * result + q;
- result = prime * result + signFailTolerance;
- return result;
- }
-
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- if (obj == null)
- {
- return false;
- }
- if (!(obj instanceof NTRUSigningParameters))
- {
- return false;
- }
- NTRUSigningParameters other = (NTRUSigningParameters)obj;
- if (B != other.B)
- {
- return false;
- }
- if (N != other.N)
- {
- return false;
- }
- if (Double.doubleToLongBits(beta) != Double.doubleToLongBits(other.beta))
- {
- return false;
- }
- if (Double.doubleToLongBits(betaSq) != Double.doubleToLongBits(other.betaSq))
- {
- return false;
- }
- if (bitsF != other.bitsF)
- {
- return false;
- }
- if (d != other.d)
- {
- return false;
- }
- if (d1 != other.d1)
- {
- return false;
- }
- if (d2 != other.d2)
- {
- return false;
- }
- if (d3 != other.d3)
- {
- return false;
- }
- if (hashAlg == null)
- {
- if (other.hashAlg != null)
- {
- return false;
- }
- }
- else if (!hashAlg.getAlgorithmName().equals(other.hashAlg.getAlgorithmName()))
- {
- return false;
- }
- if (Double.doubleToLongBits(normBound) != Double.doubleToLongBits(other.normBound))
- {
- return false;
- }
- if (Double.doubleToLongBits(normBoundSq) != Double.doubleToLongBits(other.normBoundSq))
- {
- return false;
- }
- if (q != other.q)
- {
- return false;
- }
- if (signFailTolerance != other.signFailTolerance)
- {
- return false;
- }
-
- return true;
- }
-
- public String toString()
- {
- DecimalFormat format = new DecimalFormat("0.00");
-
- StringBuilder output = new StringBuilder("SignatureParameters(N=" + N + " q=" + q);
-
- output.append(" B=" + B + " beta=" + format.format(beta) +
- " normBound=" + format.format(normBound) +
- " hashAlg=" + hashAlg + ")");
- return output.toString();
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningPrivateKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningPrivateKeyParameters.java
deleted file mode 100644
index 451422e..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningPrivateKeyParameters.java
+++ /dev/null
@@ -1,388 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.ProductFormPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial;
-
-/**
- * A NtruSign private key comprises one or more {@link NTRUSigningPrivateKeyParameters.Basis} of three polynomials each,
- * except the zeroth basis for which <code>h</code> is undefined.
- */
-public class NTRUSigningPrivateKeyParameters
- extends AsymmetricKeyParameter
-{
- private List<Basis> bases;
- private NTRUSigningPublicKeyParameters publicKey;
-
- /**
- * Constructs a new private key from a byte array
- *
- * @param b an encoded private key
- * @param params the NtruSign parameters to use
- */
- public NTRUSigningPrivateKeyParameters(byte[] b, NTRUSigningKeyGenerationParameters params)
- throws IOException
- {
- this(new ByteArrayInputStream(b), params);
- }
-
- /**
- * Constructs a new private key from an input stream
- *
- * @param is an input stream
- * @param params the NtruSign parameters to use
- */
- public NTRUSigningPrivateKeyParameters(InputStream is, NTRUSigningKeyGenerationParameters params)
- throws IOException
- {
- super(true);
- bases = new ArrayList<Basis>();
- for (int i = 0; i <= params.B; i++)
- // include a public key h[i] in all bases except for the first one
- {
- add(new Basis(is, params, i != 0));
- }
- publicKey = new NTRUSigningPublicKeyParameters(is, params.getSigningParameters());
- }
-
- public NTRUSigningPrivateKeyParameters(List<Basis> bases, NTRUSigningPublicKeyParameters publicKey)
- {
- super(true);
- this.bases = new ArrayList<Basis>(bases);
- this.publicKey = publicKey;
- }
-
- /**
- * Adds a basis to the key.
- *
- * @param b a NtruSign basis
- */
- private void add(Basis b)
- {
- bases.add(b);
- }
-
- /**
- * Returns the <code>i</code>-th basis
- *
- * @param i the index
- * @return the basis at index <code>i</code>
- */
- public Basis getBasis(int i)
- {
- return bases.get(i);
- }
-
- public NTRUSigningPublicKeyParameters getPublicKey()
- {
- return publicKey;
- }
-
- /**
- * Converts the key to a byte array
- *
- * @return the encoded key
- */
- public byte[] getEncoded()
- throws IOException
- {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- for (int i = 0; i < bases.size(); i++)
- {
- // all bases except for the first one contain a public key
- bases.get(i).encode(os, i != 0);
- }
-
- os.write(publicKey.getEncoded());
-
- return os.toByteArray();
- }
-
- /**
- * Writes the key to an output stream
- *
- * @param os an output stream
- * @throws IOException
- */
- public void writeTo(OutputStream os)
- throws IOException
- {
- os.write(getEncoded());
- }
-
- @Override
- public int hashCode()
- {
- final int prime = 31;
- int result = 1;
- result = prime * result;
- if (bases==null) return result;
- result += bases.hashCode();
- for (Basis basis : bases)
- {
- result += basis.hashCode();
- }
- return result;
- }
-
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- if (obj == null)
- {
- return false;
- }
- if (getClass() != obj.getClass())
- {
- return false;
- }
- NTRUSigningPrivateKeyParameters other = (NTRUSigningPrivateKeyParameters)obj;
- if ((bases == null) != (other.bases == null))
- {
- return false;
- }
- if (bases == null)
- {
- return true;
- }
- if (bases.size() != other.bases.size())
- {
- return false;
- }
- for (int i = 0; i < bases.size(); i++)
- {
- Basis basis1 = bases.get(i);
- Basis basis2 = other.bases.get(i);
- if (!basis1.f.equals(basis2.f))
- {
- return false;
- }
- if (!basis1.fPrime.equals(basis2.fPrime))
- {
- return false;
- }
- if (i != 0 && !basis1.h.equals(basis2.h)) // don't compare h for the 0th basis
- {
- return false;
- }
- if (!basis1.params.equals(basis2.params))
- {
- return false;
- }
- }
- return true;
- }
-
- /**
- * A NtruSign basis. Contains three polynomials <code>f, f', h</code>.
- */
- public static class Basis
- {
- public Polynomial f;
- public Polynomial fPrime;
- public IntegerPolynomial h;
- NTRUSigningKeyGenerationParameters params;
-
- /**
- * Constructs a new basis from polynomials <code>f, f', h</code>.
- *
- * @param f
- * @param fPrime
- * @param h
- * @param params NtruSign parameters
- */
- protected Basis(Polynomial f, Polynomial fPrime, IntegerPolynomial h, NTRUSigningKeyGenerationParameters params)
- {
- this.f = f;
- this.fPrime = fPrime;
- this.h = h;
- this.params = params;
- }
-
- /**
- * Reads a basis from an input stream and constructs a new basis.
- *
- * @param is an input stream
- * @param params NtruSign parameters
- * @param include_h whether to read the polynomial <code>h</code> (<code>true</code>) or only <code>f</code> and <code>f'</code> (<code>false</code>)
- */
- Basis(InputStream is, NTRUSigningKeyGenerationParameters params, boolean include_h)
- throws IOException
- {
- int N = params.N;
- int q = params.q;
- int d1 = params.d1;
- int d2 = params.d2;
- int d3 = params.d3;
- boolean sparse = params.sparse;
- this.params = params;
-
- if (params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT)
- {
- f = ProductFormPolynomial.fromBinary(is, N, d1, d2, d3 + 1, d3);
- }
- else
- {
- IntegerPolynomial fInt = IntegerPolynomial.fromBinary3Tight(is, N);
- f = sparse ? new SparseTernaryPolynomial(fInt) : new DenseTernaryPolynomial(fInt);
- }
-
- if (params.basisType == NTRUSigningKeyGenerationParameters.BASIS_TYPE_STANDARD)
- {
- IntegerPolynomial fPrimeInt = IntegerPolynomial.fromBinary(is, N, q);
- for (int i = 0; i < fPrimeInt.coeffs.length; i++)
- {
- fPrimeInt.coeffs[i] -= q / 2;
- }
- fPrime = fPrimeInt;
- }
- else if (params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT)
- {
- fPrime = ProductFormPolynomial.fromBinary(is, N, d1, d2, d3 + 1, d3);
- }
- else
- {
- fPrime = IntegerPolynomial.fromBinary3Tight(is, N);
- }
-
- if (include_h)
- {
- h = IntegerPolynomial.fromBinary(is, N, q);
- }
- }
-
- /**
- * Writes the basis to an output stream
- *
- * @param os an output stream
- * @param include_h whether to write the polynomial <code>h</code> (<code>true</code>) or only <code>f</code> and <code>f'</code> (<code>false</code>)
- * @throws IOException
- */
- void encode(OutputStream os, boolean include_h)
- throws IOException
- {
- int q = params.q;
-
- os.write(getEncoded(f));
- if (params.basisType == NTRUSigningKeyGenerationParameters.BASIS_TYPE_STANDARD)
- {
- IntegerPolynomial fPrimeInt = fPrime.toIntegerPolynomial();
- for (int i = 0; i < fPrimeInt.coeffs.length; i++)
- {
- fPrimeInt.coeffs[i] += q / 2;
- }
- os.write(fPrimeInt.toBinary(q));
- }
- else
- {
- os.write(getEncoded(fPrime));
- }
- if (include_h)
- {
- os.write(h.toBinary(q));
- }
- }
-
- private byte[] getEncoded(Polynomial p)
- {
- if (p instanceof ProductFormPolynomial)
- {
- return ((ProductFormPolynomial)p).toBinary();
- }
- else
- {
- return p.toIntegerPolynomial().toBinary3Tight();
- }
- }
-
- @Override
- public int hashCode()
- {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((f == null) ? 0 : f.hashCode());
- result = prime * result + ((fPrime == null) ? 0 : fPrime.hashCode());
- result = prime * result + ((h == null) ? 0 : h.hashCode());
- result = prime * result + ((params == null) ? 0 : params.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- if (obj == null)
- {
- return false;
- }
- if (!(obj instanceof Basis))
- {
- return false;
- }
- Basis other = (Basis)obj;
- if (f == null)
- {
- if (other.f != null)
- {
- return false;
- }
- }
- else if (!f.equals(other.f))
- {
- return false;
- }
- if (fPrime == null)
- {
- if (other.fPrime != null)
- {
- return false;
- }
- }
- else if (!fPrime.equals(other.fPrime))
- {
- return false;
- }
- if (h == null)
- {
- if (other.h != null)
- {
- return false;
- }
- }
- else if (!h.equals(other.h))
- {
- return false;
- }
- if (params == null)
- {
- if (other.params != null)
- {
- return false;
- }
- }
- else if (!params.equals(other.params))
- {
- return false;
- }
- return true;
- }
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningPublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningPublicKeyParameters.java
deleted file mode 100644
index be51d0a..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUSigningPublicKeyParameters.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.bouncycastle.pqc.crypto.ntru;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial;
-
-/**
- * A NtruSign public key is essentially a polynomial named <code>h</code>.
- */
-public class NTRUSigningPublicKeyParameters
- extends AsymmetricKeyParameter
-{
- private NTRUSigningParameters params;
- public IntegerPolynomial h;
-
- /**
- * Constructs a new public key from a polynomial
- *
- * @param h the polynomial <code>h</code> which determines the key
- * @param params the NtruSign parameters to use
- */
- public NTRUSigningPublicKeyParameters(IntegerPolynomial h, NTRUSigningParameters params)
- {
- super(false);
- this.h = h;
- this.params = params;
- }
-
- /**
- * Converts a byte array to a polynomial <code>h</code> and constructs a new public key
- *
- * @param b an encoded polynomial
- * @param params the NtruSign parameters to use
- */
- public NTRUSigningPublicKeyParameters(byte[] b, NTRUSigningParameters params)
- {
- super(false);
- h = IntegerPolynomial.fromBinary(b, params.N, params.q);
- this.params = params;
- }
-
- /**
- * Reads a polynomial <code>h</code> from an input stream and constructs a new public key
- *
- * @param is an input stream
- * @param params the NtruSign parameters to use
- */
- public NTRUSigningPublicKeyParameters(InputStream is, NTRUSigningParameters params)
- throws IOException
- {
- super(false);
- h = IntegerPolynomial.fromBinary(is, params.N, params.q);
- this.params = params;
- }
-
-
- /**
- * Converts the key to a byte array
- *
- * @return the encoded key
- */
- public byte[] getEncoded()
- {
- return h.toBinary(params.q);
- }
-
- /**
- * Writes the key to an output stream
- *
- * @param os an output stream
- * @throws IOException
- */
- public void writeTo(OutputStream os)
- throws IOException
- {
- os.write(getEncoded());
- }
-
- @Override
- public int hashCode()
- {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((h == null) ? 0 : h.hashCode());
- result = prime * result + ((params == null) ? 0 : params.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- if (obj == null)
- {
- return false;
- }
- if (getClass() != obj.getClass())
- {
- return false;
- }
- NTRUSigningPublicKeyParameters other = (NTRUSigningPublicKeyParameters)obj;
- if (h == null)
- {
- if (other.h != null)
- {
- return false;
- }
- }
- else if (!h.equals(other.h))
- {
- return false;
- }
- if (params == null)
- {
- if (other.params != null)
- {
- return false;
- }
- }
- else if (!params.equals(other.params))
- {
- return false;
- }
- return true;
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/Layer.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/Layer.java
deleted file mode 100644
index ae76922..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/Layer.java
+++ /dev/null
@@ -1,322 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.pqc.crypto.rainbow.util.GF2Field;
-import org.bouncycastle.pqc.crypto.rainbow.util.RainbowUtil;
-import org.bouncycastle.util.Arrays;
-
-
-/**
- * This class represents a layer of the Rainbow Oil- and Vinegar Map. Each Layer
- * consists of oi polynomials with their coefficients, generated at random.
- * <p>
- * To sign a document, we solve a LES (linear equation system) for each layer in
- * order to find the oil variables of that layer and to be able to use the
- * variables to compute the signature. This functionality is implemented in the
- * RainbowSignature-class, by the aid of the private key.
- * <p>
- * Each layer is a part of the private key.
- * <p>
- * More information about the layer can be found in the paper of Jintai Ding,
- * Dieter Schmidt: Rainbow, a New Multivariable Polynomial Signature Scheme.
- * ACNS 2005: 164-175 (http://dx.doi.org/10.1007/11496137_12)
- */
-public class Layer
-{
- private int vi; // number of vinegars in this layer
- private int viNext; // number of vinegars in next layer
- private int oi; // number of oils in this layer
-
- /*
- * k : index of polynomial
- *
- * i,j : indices of oil and vinegar variables
- */
- private short[/* k */][/* i */][/* j */] coeff_alpha;
- private short[/* k */][/* i */][/* j */] coeff_beta;
- private short[/* k */][/* i */] coeff_gamma;
- private short[/* k */] coeff_eta;
-
- /**
- * Constructor
- *
- * @param vi number of vinegar variables of this layer
- * @param viNext number of vinegar variables of next layer. It's the same as
- * (num of oils) + (num of vinegars) of this layer.
- * @param coeffAlpha alpha-coefficients in the polynomials of this layer
- * @param coeffBeta beta-coefficients in the polynomials of this layer
- * @param coeffGamma gamma-coefficients in the polynomials of this layer
- * @param coeffEta eta-coefficients in the polynomials of this layer
- */
- public Layer(byte vi, byte viNext, short[][][] coeffAlpha,
- short[][][] coeffBeta, short[][] coeffGamma, short[] coeffEta)
- {
- this.vi = vi & 0xff;
- this.viNext = viNext & 0xff;
- this.oi = this.viNext - this.vi;
-
- // the secret coefficients of all polynomials in this layer
- this.coeff_alpha = coeffAlpha;
- this.coeff_beta = coeffBeta;
- this.coeff_gamma = coeffGamma;
- this.coeff_eta = coeffEta;
- }
-
- /**
- * This function generates the coefficients of all polynomials in this layer
- * at random using random generator.
- *
- * @param sr the random generator which is to be used
- */
- public Layer(int vi, int viNext, SecureRandom sr)
- {
- this.vi = vi;
- this.viNext = viNext;
- this.oi = viNext - vi;
-
- // the coefficients of all polynomials in this layer
- this.coeff_alpha = new short[this.oi][this.oi][this.vi];
- this.coeff_beta = new short[this.oi][this.vi][this.vi];
- this.coeff_gamma = new short[this.oi][this.viNext];
- this.coeff_eta = new short[this.oi];
-
- int numOfPoly = this.oi; // number of polynomials per layer
-
- // Alpha coeffs
- for (int k = 0; k < numOfPoly; k++)
- {
- for (int i = 0; i < this.oi; i++)
- {
- for (int j = 0; j < this.vi; j++)
- {
- coeff_alpha[k][i][j] = (short)(sr.nextInt() & GF2Field.MASK);
- }
- }
- }
- // Beta coeffs
- for (int k = 0; k < numOfPoly; k++)
- {
- for (int i = 0; i < this.vi; i++)
- {
- for (int j = 0; j < this.vi; j++)
- {
- coeff_beta[k][i][j] = (short)(sr.nextInt() & GF2Field.MASK);
- }
- }
- }
- // Gamma coeffs
- for (int k = 0; k < numOfPoly; k++)
- {
- for (int i = 0; i < this.viNext; i++)
- {
- coeff_gamma[k][i] = (short)(sr.nextInt() & GF2Field.MASK);
- }
- }
- // Eta
- for (int k = 0; k < numOfPoly; k++)
- {
- coeff_eta[k] = (short)(sr.nextInt() & GF2Field.MASK);
- }
- }
-
- /**
- * This method plugs in the vinegar variables into the polynomials of this
- * layer and computes the coefficients of the Oil-variables as well as the
- * free coefficient in each polynomial.
- * <p>
- * It is needed for computing the Oil variables while signing.
- *
- * @param x vinegar variables of this layer that should be plugged into
- * the polynomials.
- * @return coeff the coefficients of Oil variables and the free coeff in the
- * polynomials of this layer.
- */
- public short[][] plugInVinegars(short[] x)
- {
- // temporary variable needed for the multiplication
- short tmpMult = 0;
- // coeff: 1st index = which polynomial, 2nd index=which variable
- short[][] coeff = new short[oi][oi + 1]; // gets returned
- // free coefficient per polynomial
- short[] sum = new short[oi];
-
- /*
- * evaluate the beta-part of the polynomials (it contains no oil
- * variables)
- */
- for (int k = 0; k < oi; k++)
- {
- for (int i = 0; i < vi; i++)
- {
- for (int j = 0; j < vi; j++)
- {
- // tmp = beta * xi (plug in)
- tmpMult = GF2Field.multElem(coeff_beta[k][i][j], x[i]);
- // tmp = tmp * xj
- tmpMult = GF2Field.multElem(tmpMult, x[j]);
- // accumulate into the array for the free coefficients.
- sum[k] = GF2Field.addElem(sum[k], tmpMult);
- }
- }
- }
-
- /* evaluate the alpha-part (it contains oils) */
- for (int k = 0; k < oi; k++)
- {
- for (int i = 0; i < oi; i++)
- {
- for (int j = 0; j < vi; j++)
- {
- // alpha * xj (plug in)
- tmpMult = GF2Field.multElem(coeff_alpha[k][i][j], x[j]);
- // accumulate
- coeff[k][i] = GF2Field.addElem(coeff[k][i], tmpMult);
- }
- }
- }
- /* evaluate the gama-part of the polynomial (containing no oils) */
- for (int k = 0; k < oi; k++)
- {
- for (int i = 0; i < vi; i++)
- {
- // gamma * xi (plug in)
- tmpMult = GF2Field.multElem(coeff_gamma[k][i], x[i]);
- // accumulate in the array for the free coefficients (per
- // polynomial).
- sum[k] = GF2Field.addElem(sum[k], tmpMult);
- }
- }
- /* evaluate the gama-part of the polynomial (but containing oils) */
- for (int k = 0; k < oi; k++)
- {
- for (int i = vi; i < viNext; i++)
- { // oils
- // accumulate the coefficients of the oil variables (per
- // polynomial).
- coeff[k][i - vi] = GF2Field.addElem(coeff_gamma[k][i],
- coeff[k][i - vi]);
- }
- }
- /* evaluate the eta-part of the polynomial */
- for (int k = 0; k < oi; k++)
- {
- // accumulate in the array for the free coefficients per polynomial.
- sum[k] = GF2Field.addElem(sum[k], coeff_eta[k]);
- }
-
- /* put the free coefficients (sum) into the coeff-array as last column */
- for (int k = 0; k < oi; k++)
- {
- coeff[k][oi] = sum[k];
- }
- return coeff;
- }
-
- /**
- * Getter for the number of vinegar variables of this layer.
- *
- * @return the number of vinegar variables of this layer.
- */
- public int getVi()
- {
- return vi;
- }
-
- /**
- * Getter for the number of vinegar variables of the next layer.
- *
- * @return the number of vinegar variables of the next layer.
- */
- public int getViNext()
- {
- return viNext;
- }
-
- /**
- * Getter for the number of Oil variables of this layer.
- *
- * @return the number of oil variables of this layer.
- */
- public int getOi()
- {
- return oi;
- }
-
- /**
- * Getter for the alpha-coefficients of the polynomials in this layer.
- *
- * @return the coefficients of alpha-terms of this layer.
- */
- public short[][][] getCoeffAlpha()
- {
- return coeff_alpha;
- }
-
- /**
- * Getter for the beta-coefficients of the polynomials in this layer.
- *
- * @return the coefficients of beta-terms of this layer.
- */
-
- public short[][][] getCoeffBeta()
- {
- return coeff_beta;
- }
-
- /**
- * Getter for the gamma-coefficients of the polynomials in this layer.
- *
- * @return the coefficients of gamma-terms of this layer
- */
- public short[][] getCoeffGamma()
- {
- return coeff_gamma;
- }
-
- /**
- * Getter for the eta-coefficients of the polynomials in this layer.
- *
- * @return the coefficients eta of this layer
- */
- public short[] getCoeffEta()
- {
- return coeff_eta;
- }
-
- /**
- * This function compares this Layer with another object.
- *
- * @param other the other object
- * @return the result of the comparison
- */
- public boolean equals(Object other)
- {
- if (other == null || !(other instanceof Layer))
- {
- return false;
- }
- Layer otherLayer = (Layer)other;
-
- return vi == otherLayer.getVi()
- && viNext == otherLayer.getViNext()
- && oi == otherLayer.getOi()
- && RainbowUtil.equals(coeff_alpha, otherLayer.getCoeffAlpha())
- && RainbowUtil.equals(coeff_beta, otherLayer.getCoeffBeta())
- && RainbowUtil.equals(coeff_gamma, otherLayer.getCoeffGamma())
- && RainbowUtil.equals(coeff_eta, otherLayer.getCoeffEta());
- }
-
- public int hashCode()
- {
- int hash = vi;
- hash = hash * 37 + viNext;
- hash = hash * 37 + oi;
- hash = hash * 37 + Arrays.hashCode(coeff_alpha);
- hash = hash * 37 + Arrays.hashCode(coeff_beta);
- hash = hash * 37 + Arrays.hashCode(coeff_gamma);
- hash = hash * 37 + Arrays.hashCode(coeff_eta);
-
- return hash;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyGenerationParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyGenerationParameters.java
deleted file mode 100644
index b634f9c..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyGenerationParameters.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.KeyGenerationParameters;
-
-public class RainbowKeyGenerationParameters
- extends KeyGenerationParameters
-{
- private RainbowParameters params;
-
- public RainbowKeyGenerationParameters(
- SecureRandom random,
- RainbowParameters params)
- {
- // TODO: key size?
- super(random, params.getVi()[params.getVi().length - 1] - params.getVi()[0]);
- this.params = params;
- }
-
- public RainbowParameters getParameters()
- {
- return params;
- }
-}
-
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyPairGenerator.java
deleted file mode 100644
index 6b041cf..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyPairGenerator.java
+++ /dev/null
@@ -1,417 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
-import org.bouncycastle.crypto.KeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.rainbow.util.ComputeInField;
-import org.bouncycastle.pqc.crypto.rainbow.util.GF2Field;
-
-/**
- * This class implements AsymmetricCipherKeyPairGenerator. It is used
- * as a generator for the private and public key of the Rainbow Signature
- * Scheme.
- * <p>
- * Detailed information about the key generation is to be found in the paper of
- * Jintai Ding, Dieter Schmidt: Rainbow, a New Multivariable Polynomial
- * Signature Scheme. ACNS 2005: 164-175 (http://dx.doi.org/10.1007/11496137_12)
- */
-public class RainbowKeyPairGenerator
- implements AsymmetricCipherKeyPairGenerator
-{
- private boolean initialized = false;
- private SecureRandom sr;
- private RainbowKeyGenerationParameters rainbowParams;
-
- /* linear affine map L1: */
- private short[][] A1; // matrix of the lin. affine map L1(n-v1 x n-v1 matrix)
- private short[][] A1inv; // inverted A1
- private short[] b1; // translation element of the lin.affine map L1
-
- /* linear affine map L2: */
- private short[][] A2; // matrix of the lin. affine map (n x n matrix)
- private short[][] A2inv; // inverted A2
- private short[] b2; // translation elemt of the lin.affine map L2
-
- /* components of F: */
- private int numOfLayers; // u (number of sets S)
- private Layer layers[]; // layers of polynomials of F
- private int[] vi; // set of vinegar vars per layer.
-
- /* components of Public Key */
- private short[][] pub_quadratic; // quadratic(mixed) coefficients
- private short[][] pub_singular; // singular coefficients
- private short[] pub_scalar; // scalars
-
- // TODO
-
- /**
- * The standard constructor tries to generate the Rainbow algorithm identifier
- * with the corresponding OID.
- */
- public RainbowKeyPairGenerator()
- {
- }
-
-
- /**
- * This function generates a Rainbow key pair.
- *
- * @return the generated key pair
- */
- public AsymmetricCipherKeyPair genKeyPair()
- {
- RainbowPrivateKeyParameters privKey;
- RainbowPublicKeyParameters pubKey;
-
- if (!initialized)
- {
- initializeDefault();
- }
-
- /* choose all coefficients at random */
- keygen();
-
- /* now marshall them to PrivateKey */
- privKey = new RainbowPrivateKeyParameters(A1inv, b1, A2inv, b2, vi, layers);
-
-
- /* marshall to PublicKey */
- pubKey = new RainbowPublicKeyParameters(vi[vi.length - 1] - vi[0], pub_quadratic, pub_singular, pub_scalar);
-
- return new AsymmetricCipherKeyPair(pubKey, privKey);
- }
-
- // TODO
- public void initialize(
- KeyGenerationParameters param)
- {
- this.rainbowParams = (RainbowKeyGenerationParameters)param;
-
- // set source of randomness
- this.sr = new SecureRandom();
-
- // unmarshalling:
- this.vi = this.rainbowParams.getParameters().getVi();
- this.numOfLayers = this.rainbowParams.getParameters().getNumOfLayers();
-
- this.initialized = true;
- }
-
- private void initializeDefault()
- {
- RainbowKeyGenerationParameters rbKGParams = new RainbowKeyGenerationParameters(new SecureRandom(), new RainbowParameters());
- initialize(rbKGParams);
- }
-
- /**
- * This function calls the functions for the random generation of the coefficients
- * and the matrices needed for the private key and the method for computing the public key.
- */
- private void keygen()
- {
- generateL1();
- generateL2();
- generateF();
- computePublicKey();
- }
-
- /**
- * This function generates the invertible affine linear map L1 = A1*x + b1
- * <p>
- * The translation part b1, is stored in a separate array. The inverse of
- * the matrix-part of L1 A1inv is also computed here.
- * </p><p>
- * This linear map hides the output of the map F. It is on k^(n-v1).
- * </p>
- */
- private void generateL1()
- {
-
- // dimension = n-v1 = vi[last] - vi[first]
- int dim = vi[vi.length - 1] - vi[0];
- this.A1 = new short[dim][dim];
- this.A1inv = null;
- ComputeInField c = new ComputeInField();
-
- /* generation of A1 at random */
- while (A1inv == null)
- {
- for (int i = 0; i < dim; i++)
- {
- for (int j = 0; j < dim; j++)
- {
- A1[i][j] = (short)(sr.nextInt() & GF2Field.MASK);
- }
- }
- A1inv = c.inverse(A1);
- }
-
- /* generation of the translation vector at random */
- b1 = new short[dim];
- for (int i = 0; i < dim; i++)
- {
- b1[i] = (short)(sr.nextInt() & GF2Field.MASK);
- }
- }
-
- /**
- * This function generates the invertible affine linear map L2 = A2*x + b2
- * <p>
- * The translation part b2, is stored in a separate array. The inverse of
- * the matrix-part of L2 A2inv is also computed here.
- * </p><p>
- * This linear map hides the output of the map F. It is on k^(n).
- * </p>
- */
- private void generateL2()
- {
-
- // dimension = n = vi[last]
- int dim = vi[vi.length - 1];
- this.A2 = new short[dim][dim];
- this.A2inv = null;
- ComputeInField c = new ComputeInField();
-
- /* generation of A2 at random */
- while (this.A2inv == null)
- {
- for (int i = 0; i < dim; i++)
- {
- for (int j = 0; j < dim; j++)
- { // one col extra for b
- A2[i][j] = (short)(sr.nextInt() & GF2Field.MASK);
- }
- }
- this.A2inv = c.inverse(A2);
- }
- /* generation of the translation vector at random */
- b2 = new short[dim];
- for (int i = 0; i < dim; i++)
- {
- b2[i] = (short)(sr.nextInt() & GF2Field.MASK);
- }
-
- }
-
- /**
- * This function generates the private map F, which consists of u-1 layers.
- * Each layer consists of oi polynomials where oi = vi[i+1]-vi[i].
- * <p>
- * The methods for the generation of the coefficients of these polynomials
- * are called here.
- * </p>
- */
- private void generateF()
- {
-
- this.layers = new Layer[this.numOfLayers];
- for (int i = 0; i < this.numOfLayers; i++)
- {
- layers[i] = new Layer(this.vi[i], this.vi[i + 1], sr);
- }
- }
-
- /**
- * This function computes the public key from the private key.
- * <p>
- * The composition of F with L2 is computed, followed by applying L1 to the
- * composition's result. The singular and scalar values constitute to the
- * public key as is, the quadratic terms are compacted in
- * <tt>compactPublicKey()</tt>
- * </p>
- */
- private void computePublicKey()
- {
-
- ComputeInField c = new ComputeInField();
- int rows = this.vi[this.vi.length - 1] - this.vi[0];
- int vars = this.vi[this.vi.length - 1];
- // Fpub
- short[][][] coeff_quadratic_3dim = new short[rows][vars][vars];
- this.pub_singular = new short[rows][vars];
- this.pub_scalar = new short[rows];
-
- // Coefficients of layers of Private Key F
- short[][][] coeff_alpha;
- short[][][] coeff_beta;
- short[][] coeff_gamma;
- short[] coeff_eta;
-
- // Needed for counters;
- int oils = 0;
- int vins = 0;
- int crnt_row = 0; // current row (polynomial)
-
- short vect_tmp[] = new short[vars]; // vector tmp;
- short sclr_tmp = 0;
-
- // Composition of F and L2: Insert L2 = A2*x+b2 in F
- for (int l = 0; l < this.layers.length; l++)
- {
- // get coefficients of current layer
- coeff_alpha = this.layers[l].getCoeffAlpha();
- coeff_beta = this.layers[l].getCoeffBeta();
- coeff_gamma = this.layers[l].getCoeffGamma();
- coeff_eta = this.layers[l].getCoeffEta();
- oils = coeff_alpha[0].length;// this.layers[l].getOi();
- vins = coeff_beta[0].length;// this.layers[l].getVi();
- // compute polynomials of layer
- for (int p = 0; p < oils; p++)
- {
- // multiply alphas
- for (int x1 = 0; x1 < oils; x1++)
- {
- for (int x2 = 0; x2 < vins; x2++)
- {
- // multiply polynomial1 with polynomial2
- vect_tmp = c.multVect(coeff_alpha[p][x1][x2],
- this.A2[x1 + vins]);
- coeff_quadratic_3dim[crnt_row + p] = c.addSquareMatrix(
- coeff_quadratic_3dim[crnt_row + p], c
- .multVects(vect_tmp, this.A2[x2]));
- // mul poly1 with scalar2
- vect_tmp = c.multVect(this.b2[x2], vect_tmp);
- this.pub_singular[crnt_row + p] = c.addVect(vect_tmp,
- this.pub_singular[crnt_row + p]);
- // mul scalar1 with poly2
- vect_tmp = c.multVect(coeff_alpha[p][x1][x2],
- this.A2[x2]);
- vect_tmp = c.multVect(b2[x1 + vins], vect_tmp);
- this.pub_singular[crnt_row + p] = c.addVect(vect_tmp,
- this.pub_singular[crnt_row + p]);
- // mul scalar1 with scalar2
- sclr_tmp = GF2Field.multElem(coeff_alpha[p][x1][x2],
- this.b2[x1 + vins]);
- this.pub_scalar[crnt_row + p] = GF2Field.addElem(
- this.pub_scalar[crnt_row + p], GF2Field
- .multElem(sclr_tmp, this.b2[x2]));
- }
- }
- // multiply betas
- for (int x1 = 0; x1 < vins; x1++)
- {
- for (int x2 = 0; x2 < vins; x2++)
- {
- // multiply polynomial1 with polynomial2
- vect_tmp = c.multVect(coeff_beta[p][x1][x2],
- this.A2[x1]);
- coeff_quadratic_3dim[crnt_row + p] = c.addSquareMatrix(
- coeff_quadratic_3dim[crnt_row + p], c
- .multVects(vect_tmp, this.A2[x2]));
- // mul poly1 with scalar2
- vect_tmp = c.multVect(this.b2[x2], vect_tmp);
- this.pub_singular[crnt_row + p] = c.addVect(vect_tmp,
- this.pub_singular[crnt_row + p]);
- // mul scalar1 with poly2
- vect_tmp = c.multVect(coeff_beta[p][x1][x2],
- this.A2[x2]);
- vect_tmp = c.multVect(this.b2[x1], vect_tmp);
- this.pub_singular[crnt_row + p] = c.addVect(vect_tmp,
- this.pub_singular[crnt_row + p]);
- // mul scalar1 with scalar2
- sclr_tmp = GF2Field.multElem(coeff_beta[p][x1][x2],
- this.b2[x1]);
- this.pub_scalar[crnt_row + p] = GF2Field.addElem(
- this.pub_scalar[crnt_row + p], GF2Field
- .multElem(sclr_tmp, this.b2[x2]));
- }
- }
- // multiply gammas
- for (int n = 0; n < vins + oils; n++)
- {
- // mul poly with scalar
- vect_tmp = c.multVect(coeff_gamma[p][n], this.A2[n]);
- this.pub_singular[crnt_row + p] = c.addVect(vect_tmp,
- this.pub_singular[crnt_row + p]);
- // mul scalar with scalar
- this.pub_scalar[crnt_row + p] = GF2Field.addElem(
- this.pub_scalar[crnt_row + p], GF2Field.multElem(
- coeff_gamma[p][n], this.b2[n]));
- }
- // add eta
- this.pub_scalar[crnt_row + p] = GF2Field.addElem(
- this.pub_scalar[crnt_row + p], coeff_eta[p]);
- }
- crnt_row = crnt_row + oils;
- }
-
- // Apply L1 = A1*x+b1 to composition of F and L2
- {
- // temporary coefficient arrays
- short[][][] tmp_c_quad = new short[rows][vars][vars];
- short[][] tmp_c_sing = new short[rows][vars];
- short[] tmp_c_scal = new short[rows];
- for (int r = 0; r < rows; r++)
- {
- for (int q = 0; q < A1.length; q++)
- {
- tmp_c_quad[r] = c.addSquareMatrix(tmp_c_quad[r], c
- .multMatrix(A1[r][q], coeff_quadratic_3dim[q]));
- tmp_c_sing[r] = c.addVect(tmp_c_sing[r], c.multVect(
- A1[r][q], this.pub_singular[q]));
- tmp_c_scal[r] = GF2Field.addElem(tmp_c_scal[r], GF2Field
- .multElem(A1[r][q], this.pub_scalar[q]));
- }
- tmp_c_scal[r] = GF2Field.addElem(tmp_c_scal[r], b1[r]);
- }
- // set public key
- coeff_quadratic_3dim = tmp_c_quad;
- this.pub_singular = tmp_c_sing;
- this.pub_scalar = tmp_c_scal;
- }
- compactPublicKey(coeff_quadratic_3dim);
- }
-
- /**
- * The quadratic (or mixed) terms of the public key are compacted from a n x
- * n matrix per polynomial to an upper diagonal matrix stored in one integer
- * array of n (n + 1) / 2 elements per polynomial. The ordering of elements
- * is lexicographic and the result is updating <tt>this.pub_quadratic</tt>,
- * which stores the quadratic elements of the public key.
- *
- * @param coeff_quadratic_to_compact 3-dimensional array containing a n x n Matrix for each of the
- * n - v1 polynomials
- */
- private void compactPublicKey(short[][][] coeff_quadratic_to_compact)
- {
- int polynomials = coeff_quadratic_to_compact.length;
- int n = coeff_quadratic_to_compact[0].length;
- int entries = n * (n + 1) / 2;// the small gauss
- this.pub_quadratic = new short[polynomials][entries];
- int offset = 0;
-
- for (int p = 0; p < polynomials; p++)
- {
- offset = 0;
- for (int x = 0; x < n; x++)
- {
- for (int y = x; y < n; y++)
- {
- if (y == x)
- {
- this.pub_quadratic[p][offset] = coeff_quadratic_to_compact[p][x][y];
- }
- else
- {
- this.pub_quadratic[p][offset] = GF2Field.addElem(
- coeff_quadratic_to_compact[p][x][y],
- coeff_quadratic_to_compact[p][y][x]);
- }
- offset++;
- }
- }
- }
- }
-
- public void init(KeyGenerationParameters param)
- {
- this.initialize(param);
- }
-
- public AsymmetricCipherKeyPair generateKeyPair()
- {
- return genKeyPair();
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyParameters.java
deleted file mode 100644
index 9dec685..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowKeyParameters.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow;
-
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-
-public class RainbowKeyParameters
- extends AsymmetricKeyParameter
-{
- private int docLength;
-
- public RainbowKeyParameters(
- boolean isPrivate,
- int docLength)
- {
- super(isPrivate);
- this.docLength = docLength;
- }
-
- /**
- * @return the docLength
- */
- public int getDocLength()
- {
- return this.docLength;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowParameters.java
deleted file mode 100644
index 147c55e..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowParameters.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow;
-
-import org.bouncycastle.crypto.CipherParameters;
-
-public class RainbowParameters
- implements CipherParameters
-{
-
- /**
- * DEFAULT PARAMS
- */
- /*
- * Vi = vinegars per layer whereas n is vu (vu = 33 = n) such that
- *
- * v1 = 6; o1 = 12-6 = 6
- *
- * v2 = 12; o2 = 17-12 = 5
- *
- * v3 = 17; o3 = 22-17 = 5
- *
- * v4 = 22; o4 = 33-22 = 11
- *
- * v5 = 33; (o5 = 0)
- */
- private final int[] DEFAULT_VI = {6, 12, 17, 22, 33};
-
- private int[] vi;// set of vinegar vars per layer.
-
- /**
- * Default Constructor The elements of the array containing the number of
- * Vinegar variables in each layer are set to the default values here.
- */
- public RainbowParameters()
- {
- this.vi = this.DEFAULT_VI;
- }
-
- /**
- * Constructor with parameters
- *
- * @param vi The elements of the array containing the number of Vinegar
- * variables per layer are set to the values of the input array.
- */
- public RainbowParameters(int[] vi)
- {
- this.vi = vi;
- try
- {
- checkParams();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- private void checkParams()
- throws Exception
- {
- if (vi == null)
- {
- throw new Exception("no layers defined.");
- }
- if (vi.length > 1)
- {
- for (int i = 0; i < vi.length - 1; i++)
- {
- if (vi[i] >= vi[i + 1])
- {
- throw new Exception(
- "v[i] has to be smaller than v[i+1]");
- }
- }
- }
- else
- {
- throw new Exception(
- "Rainbow needs at least 1 layer, such that v1 < v2.");
- }
- }
-
- /**
- * Getter for the number of layers
- *
- * @return the number of layers
- */
- public int getNumOfLayers()
- {
- return this.vi.length - 1;
- }
-
- /**
- * Getter for the number of all the polynomials in Rainbow
- *
- * @return the number of the polynomials
- */
- public int getDocLength()
- {
- return vi[vi.length - 1] - vi[0];
- }
-
- /**
- * Getter for the array containing the number of Vinegar-variables per layer
- *
- * @return the numbers of vinegars per layer
- */
- public int[] getVi()
- {
- return this.vi;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowPrivateKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowPrivateKeyParameters.java
deleted file mode 100644
index 9876882..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowPrivateKeyParameters.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow;
-
-public class RainbowPrivateKeyParameters
- extends RainbowKeyParameters
-{
- /**
- * Constructor
- *
- * @param A1inv the inverse of A1(the matrix part of the affine linear map L1)
- * (n-v1 x n-v1 matrix)
- * @param b1 translation vector, part of the linear affine map L1
- * @param A2inv the inverse of A2(the matrix part of the affine linear map L2)
- * (n x n matrix)
- * @param b2 translation vector, part of the linear affine map L2
- * @param vi the number of Vinegar-variables per layer
- * @param layers the polynomials with their coefficients of private map F
- */
- public RainbowPrivateKeyParameters(short[][] A1inv, short[] b1,
- short[][] A2inv, short[] b2, int[] vi, Layer[] layers)
- {
- super(true, vi[vi.length - 1] - vi[0]);
-
- this.A1inv = A1inv;
- this.b1 = b1;
- this.A2inv = A2inv;
- this.b2 = b2;
- this.vi = vi;
- this.layers = layers;
- }
-
- /*
- * invertible affine linear map L1
- */
- // the inverse of A1, (n-v1 x n-v1 matrix)
- private short[][] A1inv;
-
- // translation vector of L1
- private short[] b1;
-
- /*
- * invertible affine linear map L2
- */
- // the inverse of A2, (n x n matrix)
- private short[][] A2inv;
-
- // translation vector of L2
- private short[] b2;
-
- /*
- * components of F
- */
- // the number of Vinegar-variables per layer.
- private int[] vi;
-
- // contains the polynomials with their coefficients of private map F
- private Layer[] layers;
-
- /**
- * Getter for the translation part of the private quadratic map L1.
- *
- * @return b1 the translation part of L1
- */
- public short[] getB1()
- {
- return this.b1;
- }
-
- /**
- * Getter for the inverse matrix of A1.
- *
- * @return the A1inv inverse
- */
- public short[][] getInvA1()
- {
- return this.A1inv;
- }
-
- /**
- * Getter for the translation part of the private quadratic map L2.
- *
- * @return b2 the translation part of L2
- */
- public short[] getB2()
- {
- return this.b2;
- }
-
- /**
- * Getter for the inverse matrix of A2
- *
- * @return the A2inv
- */
- public short[][] getInvA2()
- {
- return this.A2inv;
- }
-
- /**
- * Returns the layers contained in the private key
- *
- * @return layers
- */
- public Layer[] getLayers()
- {
- return this.layers;
- }
-
- /**
- * /** Returns the array of vi-s
- *
- * @return the vi
- */
- public int[] getVi()
- {
- return vi;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowPublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowPublicKeyParameters.java
deleted file mode 100644
index 6f3e46f..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowPublicKeyParameters.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow;
-
-public class RainbowPublicKeyParameters
- extends RainbowKeyParameters
-{
- private short[][] coeffquadratic;
- private short[][] coeffsingular;
- private short[] coeffscalar;
-
- /**
- * Constructor
- *
- * @param docLength
- * @param coeffQuadratic
- * @param coeffSingular
- * @param coeffScalar
- */
- public RainbowPublicKeyParameters(int docLength,
- short[][] coeffQuadratic, short[][] coeffSingular,
- short[] coeffScalar)
- {
- super(false, docLength);
-
- this.coeffquadratic = coeffQuadratic;
- this.coeffsingular = coeffSingular;
- this.coeffscalar = coeffScalar;
-
- }
-
- /**
- * @return the coeffquadratic
- */
- public short[][] getCoeffQuadratic()
- {
- return coeffquadratic;
- }
-
- /**
- * @return the coeffsingular
- */
- public short[][] getCoeffSingular()
- {
- return coeffsingular;
- }
-
- /**
- * @return the coeffscalar
- */
- public short[] getCoeffScalar()
- {
- return coeffscalar;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowSigner.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowSigner.java
deleted file mode 100644
index 979e759..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowSigner.java
+++ /dev/null
@@ -1,301 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.MessageSigner;
-import org.bouncycastle.pqc.crypto.rainbow.util.ComputeInField;
-import org.bouncycastle.pqc.crypto.rainbow.util.GF2Field;
-
-/**
- * It implements the sign and verify functions for the Rainbow Signature Scheme.
- * Here the message, which has to be signed, is updated. The use of
- * different hash functions is possible.
- * <p>
- * Detailed information about the signature and the verify-method is to be found
- * in the paper of Jintai Ding, Dieter Schmidt: Rainbow, a New Multivariable
- * Polynomial Signature Scheme. ACNS 2005: 164-175
- * (http://dx.doi.org/10.1007/11496137_12)
- */
-public class RainbowSigner
- implements MessageSigner
-{
- // Source of randomness
- private SecureRandom random;
-
- // The length of a document that can be signed with the privKey
- int signableDocumentLength;
-
- // Container for the oil and vinegar variables of all the layers
- private short[] x;
-
- private ComputeInField cf = new ComputeInField();
-
- RainbowKeyParameters key;
-
- public void init(boolean forSigning,
- CipherParameters param)
- {
- if (forSigning)
- {
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)param;
-
- this.random = rParam.getRandom();
- this.key = (RainbowPrivateKeyParameters)rParam.getParameters();
-
- }
- else
- {
-
- this.random = new SecureRandom();
- this.key = (RainbowPrivateKeyParameters)param;
- }
- }
- else
- {
- this.key = (RainbowPublicKeyParameters)param;
- }
-
- this.signableDocumentLength = this.key.getDocLength();
- }
-
-
- /**
- * initial operations before solving the Linear equation system.
- *
- * @param layer the current layer for which a LES is to be solved.
- * @param msg the message that should be signed.
- * @return Y_ the modified document needed for solving LES, (Y_ =
- * A1^{-1}*(Y-b1)) linear map L1 = A1 x + b1.
- */
- private short[] initSign(Layer[] layer, short[] msg)
- {
-
- /* preparation: Modifies the document with the inverse of L1 */
- // tmp = Y - b1:
- short[] tmpVec = new short[msg.length];
-
- tmpVec = cf.addVect(((RainbowPrivateKeyParameters)this.key).getB1(), msg);
-
- // Y_ = A1^{-1} * (Y - b1) :
- short[] Y_ = cf.multiplyMatrix(((RainbowPrivateKeyParameters)this.key).getInvA1(), tmpVec);
-
- /* generates the vinegar vars of the first layer at random */
- for (int i = 0; i < layer[0].getVi(); i++)
- {
- x[i] = (short)random.nextInt();
- x[i] = (short)(x[i] & GF2Field.MASK);
- }
-
- return Y_;
- }
-
- /**
- * This function signs the message that has been updated, making use of the
- * private key.
- * <p>
- * For computing the signature, L1 and L2 are needed, as well as LES should
- * be solved for each layer in order to find the Oil-variables in the layer.
- * <p>
- * The Vinegar-variables of the first layer are random generated.
- *
- * @param message the message
- * @return the signature of the message.
- */
- public byte[] generateSignature(byte[] message)
- {
- Layer[] layer = ((RainbowPrivateKeyParameters)this.key).getLayers();
- int numberOfLayers = layer.length;
-
- x = new short[((RainbowPrivateKeyParameters)this.key).getInvA2().length]; // all variables
-
- short[] Y_; // modified document
- short[] y_i; // part of Y_ each polynomial
- int counter; // index of the current part of the doc
-
- short[] solVec; // the solution of LES pro layer
- short[] tmpVec;
-
- // the signature as an array of shorts:
- short[] signature;
- // the signature as a byte-array:
- byte[] S = new byte[layer[numberOfLayers - 1].getViNext()];
-
- short[] msgHashVals = makeMessageRepresentative(message);
-
- // shows if an exception is caught
- boolean ok;
- do
- {
- ok = true;
- counter = 0;
- try
- {
- Y_ = initSign(layer, msgHashVals);
-
- for (int i = 0; i < numberOfLayers; i++)
- {
-
- y_i = new short[layer[i].getOi()];
- solVec = new short[layer[i].getOi()]; // solution of LES
-
- /* copy oi elements of Y_ into y_i */
- for (int k = 0; k < layer[i].getOi(); k++)
- {
- y_i[k] = Y_[counter];
- counter++; // current index of Y_
- }
-
- /*
- * plug in the vars of the previous layer in order to get
- * the vars of the current layer
- */
- solVec = cf.solveEquation(layer[i].plugInVinegars(x), y_i);
-
- if (solVec == null)
- { // LES is not solveable
- throw new Exception("LES is not solveable!");
- }
-
- /* copy the new vars into the x-array */
- for (int j = 0; j < solVec.length; j++)
- {
- x[layer[i].getVi() + j] = solVec[j];
- }
- }
-
- /* apply the inverse of L2: (signature = A2^{-1}*(b2+x)) */
- tmpVec = cf.addVect(((RainbowPrivateKeyParameters)this.key).getB2(), x);
- signature = cf.multiplyMatrix(((RainbowPrivateKeyParameters)this.key).getInvA2(), tmpVec);
-
- /* cast signature from short[] to byte[] */
- for (int i = 0; i < S.length; i++)
- {
- S[i] = ((byte)signature[i]);
- }
- }
- catch (Exception se)
- {
- // if one of the LESs was not solveable - sign again
- ok = false;
- }
- }
- while (!ok);
- /* return the signature in bytes */
- return S;
- }
-
- /**
- * This function verifies the signature of the message that has been
- * updated, with the aid of the public key.
- *
- * @param message the message
- * @param signature the signature of the message
- * @return true if the signature has been verified, false otherwise.
- */
- public boolean verifySignature(byte[] message, byte[] signature)
- {
- short[] sigInt = new short[signature.length];
- short tmp;
-
- for (int i = 0; i < signature.length; i++)
- {
- tmp = (short)signature[i];
- tmp &= (short)0xff;
- sigInt[i] = tmp;
- }
-
- short[] msgHashVal = makeMessageRepresentative(message);
-
- // verify
- short[] verificationResult = verifySignatureIntern(sigInt);
-
- // compare
- boolean verified = true;
- if (msgHashVal.length != verificationResult.length)
- {
- return false;
- }
- for (int i = 0; i < msgHashVal.length; i++)
- {
- verified = verified && msgHashVal[i] == verificationResult[i];
- }
-
- return verified;
- }
-
- /**
- * Signature verification using public key
- *
- * @param signature vector of dimension n
- * @return document hash of length n - v1
- */
- private short[] verifySignatureIntern(short[] signature)
- {
-
- short[][] coeff_quadratic = ((RainbowPublicKeyParameters)this.key).getCoeffQuadratic();
- short[][] coeff_singular = ((RainbowPublicKeyParameters)this.key).getCoeffSingular();
- short[] coeff_scalar = ((RainbowPublicKeyParameters)this.key).getCoeffScalar();
-
- short[] rslt = new short[coeff_quadratic.length];// n - v1
- int n = coeff_singular[0].length;
- int offset = 0; // array position
- short tmp = 0; // for scalar
-
- for (int p = 0; p < coeff_quadratic.length; p++)
- { // no of polynomials
- offset = 0;
- for (int x = 0; x < n; x++)
- {
- // calculate quadratic terms
- for (int y = x; y < n; y++)
- {
- tmp = GF2Field.multElem(coeff_quadratic[p][offset],
- GF2Field.multElem(signature[x], signature[y]));
- rslt[p] = GF2Field.addElem(rslt[p], tmp);
- offset++;
- }
- // calculate singular terms
- tmp = GF2Field.multElem(coeff_singular[p][x], signature[x]);
- rslt[p] = GF2Field.addElem(rslt[p], tmp);
- }
- // add scalar
- rslt[p] = GF2Field.addElem(rslt[p], coeff_scalar[p]);
- }
-
- return rslt;
- }
-
- /**
- * This function creates the representative of the message which gets signed
- * or verified.
- *
- * @param message the message
- * @return message representative
- */
- private short[] makeMessageRepresentative(byte[] message)
- {
- // the message representative
- short[] output = new short[this.signableDocumentLength];
-
- int h = 0;
- int i = 0;
- do
- {
- if (i >= message.length)
- {
- break;
- }
- output[i] = (short)message[h];
- output[i] &= (short)0xff;
- h++;
- i++;
- }
- while (i < output.length);
-
- return output;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/ComputeInField.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/ComputeInField.java
deleted file mode 100644
index 5bf2573..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/ComputeInField.java
+++ /dev/null
@@ -1,490 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow.util;
-
-/**
- * This class offers different operations on matrices in field GF2^8.
- * <p>
- * Implemented are functions:
- * - finding inverse of a matrix
- * - solving linear equation systems using the Gauss-Elimination method
- * - basic operations like matrix multiplication, addition and so on.
- */
-
-public class ComputeInField
-{
-
- private short[][] A; // used by solveEquation and inverse
- short[] x;
-
- /**
- * Constructor with no parameters
- */
- public ComputeInField()
- {
- }
-
-
- /**
- * This function finds a solution of the equation Bx = b.
- * Exception is thrown if the linear equation system has no solution
- *
- * @param B this matrix is the left part of the
- * equation (B in the equation above)
- * @param b the right part of the equation
- * (b in the equation above)
- * @return x the solution of the equation if it is solvable
- * null otherwise
- * @throws RuntimeException if LES is not solvable
- */
- public short[] solveEquation(short[][] B, short[] b)
- {
- try
- {
-
- if (B.length != b.length)
- {
- throw new RuntimeException(
- "The equation system is not solvable");
- }
-
- /** initialize **/
- // this matrix stores B and b from the equation B*x = b
- // b is stored as the last column.
- // B contains one column more than rows.
- // In this column we store a free coefficient that should be later subtracted from b
- A = new short[B.length][B.length + 1];
- // stores the solution of the LES
- x = new short[B.length];
-
- /** copy B into the global matrix A **/
- for (int i = 0; i < B.length; i++)
- { // rows
- for (int j = 0; j < B[0].length; j++)
- { // cols
- A[i][j] = B[i][j];
- }
- }
-
- /** copy the vector b into the global A **/
- //the free coefficient, stored in the last column of A( A[i][b.length]
- // is to be subtracted from b
- for (int i = 0; i < b.length; i++)
- {
- A[i][b.length] = GF2Field.addElem(b[i], A[i][b.length]);
- }
-
- /** call the methods for gauss elimination and backward substitution **/
- computeZerosUnder(false); // obtain zeros under the diagonal
- substitute();
-
- return x;
-
- }
- catch (RuntimeException rte)
- {
- return null; // the LES is not solvable!
- }
- }
-
- /**
- * This function computes the inverse of a given matrix using the Gauss-
- * Elimination method.
- * <p>
- * An exception is thrown if the matrix has no inverse
- *
- * @param coef the matrix which inverse matrix is needed
- * @return inverse matrix of the input matrix.
- * If the matrix is singular, null is returned.
- * @throws RuntimeException if the given matrix is not invertible
- */
- public short[][] inverse(short[][] coef)
- {
- try
- {
- /** Initialization: **/
- short factor;
- short[][] inverse;
- A = new short[coef.length][2 * coef.length];
- if (coef.length != coef[0].length)
- {
- throw new RuntimeException(
- "The matrix is not invertible. Please choose another one!");
- }
-
- /** prepare: Copy coef and the identity matrix into the global A. **/
- for (int i = 0; i < coef.length; i++)
- {
- for (int j = 0; j < coef.length; j++)
- {
- //copy the input matrix coef into A
- A[i][j] = coef[i][j];
- }
- // copy the identity matrix into A.
- for (int j = coef.length; j < 2 * coef.length; j++)
- {
- A[i][j] = 0;
- }
- A[i][i + A.length] = 1;
- }
-
- /** Elimination operations to get the identity matrix from the left side of A. **/
- // modify A to get 0s under the diagonal.
- computeZerosUnder(true);
-
- // modify A to get only 1s on the diagonal: A[i][j] =A[i][j]/A[i][i].
- for (int i = 0; i < A.length; i++)
- {
- factor = GF2Field.invElem(A[i][i]);
- for (int j = i; j < 2 * A.length; j++)
- {
- A[i][j] = GF2Field.multElem(A[i][j], factor);
- }
- }
-
- //modify A to get only 0s above the diagonal.
- computeZerosAbove();
-
- // copy the result (the second half of A) in the matrix inverse.
- inverse = new short[A.length][A.length];
- for (int i = 0; i < A.length; i++)
- {
- for (int j = A.length; j < 2 * A.length; j++)
- {
- inverse[i][j - A.length] = A[i][j];
- }
- }
- return inverse;
-
- }
- catch (RuntimeException rte)
- {
- // The matrix is not invertible! A new one should be generated!
- return null;
- }
- }
-
- /**
- * Elimination under the diagonal.
- * This function changes a matrix so that it contains only zeros under the
- * diagonal(Ai,i) using only Gauss-Elimination operations.
- * <p>
- * It is used in solveEquaton as well as in the function for
- * finding an inverse of a matrix: {@link}inverse. Both of them use the
- * Gauss-Elimination Method.
- * </p><p>
- * The result is stored in the global matrix A
- * </p>
- * @param usedForInverse This parameter shows if the function is used by the
- * solveEquation-function or by the inverse-function and according
- * to this creates matrices of different sizes.
- * @throws RuntimeException in case a multiplicative inverse of 0 is needed
- */
- private void computeZerosUnder(boolean usedForInverse)
- throws RuntimeException
- {
-
- //the number of columns in the global A where the tmp results are stored
- int length;
- short tmp = 0;
-
- //the function is used in inverse() - A should have 2 times more columns than rows
- if (usedForInverse)
- {
- length = 2 * A.length;
- }
- //the function is used in solveEquation - A has 1 column more than rows
- else
- {
- length = A.length + 1;
- }
-
- //elimination operations to modify A so that that it contains only 0s under the diagonal
- for (int k = 0; k < A.length - 1; k++)
- { // the fixed row
- for (int i = k + 1; i < A.length; i++)
- { // rows
- short factor1 = A[i][k];
- short factor2 = GF2Field.invElem(A[k][k]);
-
- //The element which multiplicative inverse is needed, is 0
- //in this case is the input matrix not invertible
- if (factor2 == 0)
- {
- throw new RuntimeException("Matrix not invertible! We have to choose another one!");
- }
-
- for (int j = k; j < length; j++)
- {// columns
- // tmp=A[k,j] / A[k,k]
- tmp = GF2Field.multElem(A[k][j], factor2);
- // tmp = A[i,k] * A[k,j] / A[k,k]
- tmp = GF2Field.multElem(factor1, tmp);
- // A[i,j]=A[i,j]-A[i,k]/A[k,k]*A[k,j];
- A[i][j] = GF2Field.addElem(A[i][j], tmp);
- }
- }
- }
- }
-
- /**
- * Elimination above the diagonal.
- * This function changes a matrix so that it contains only zeros above the
- * diagonal(Ai,i) using only Gauss-Elimination operations.
- * <p>
- * It is used in the inverse-function
- * The result is stored in the global matrix A
- * </p>
- * @throws RuntimeException in case a multiplicative inverse of 0 is needed
- */
- private void computeZerosAbove()
- throws RuntimeException
- {
- short tmp = 0;
- for (int k = A.length - 1; k > 0; k--)
- { // the fixed row
- for (int i = k - 1; i >= 0; i--)
- { // rows
- short factor1 = A[i][k];
- short factor2 = GF2Field.invElem(A[k][k]);
- if (factor2 == 0)
- {
- throw new RuntimeException("The matrix is not invertible");
- }
- for (int j = k; j < 2 * A.length; j++)
- { // columns
- // tmp = A[k,j] / A[k,k]
- tmp = GF2Field.multElem(A[k][j], factor2);
- // tmp = A[i,k] * A[k,j] / A[k,k]
- tmp = GF2Field.multElem(factor1, tmp);
- // A[i,j] = A[i,j] - A[i,k] / A[k,k] * A[k,j];
- A[i][j] = GF2Field.addElem(A[i][j], tmp);
- }
- }
- }
- }
-
-
- /**
- * This function uses backward substitution to find x
- * of the linear equation system (LES) B*x = b,
- * where A a triangle-matrix is (contains only zeros under the diagonal)
- * and b is a vector
- * <p>
- * If the multiplicative inverse of 0 is needed, an exception is thrown.
- * In this case is the LES not solvable
- * </p>
- * @throws RuntimeException in case a multiplicative inverse of 0 is needed
- */
- private void substitute()
- throws RuntimeException
- {
-
- // for the temporary results of the operations in field
- short tmp, temp;
-
- temp = GF2Field.invElem(A[A.length - 1][A.length - 1]);
- if (temp == 0)
- {
- throw new RuntimeException("The equation system is not solvable");
- }
-
- /** backward substitution **/
- x[A.length - 1] = GF2Field.multElem(A[A.length - 1][A.length], temp);
- for (int i = A.length - 2; i >= 0; i--)
- {
- tmp = A[i][A.length];
- for (int j = A.length - 1; j > i; j--)
- {
- temp = GF2Field.multElem(A[i][j], x[j]);
- tmp = GF2Field.addElem(tmp, temp);
- }
-
- temp = GF2Field.invElem(A[i][i]);
- if (temp == 0)
- {
- throw new RuntimeException("Not solvable equation system");
- }
- x[i] = GF2Field.multElem(tmp, temp);
- }
- }
-
-
- /**
- * This function multiplies two given matrices.
- * If the given matrices cannot be multiplied due
- * to different sizes, an exception is thrown.
- *
- * @param M1 -the 1st matrix
- * @param M2 -the 2nd matrix
- * @return A = M1*M2
- * @throws RuntimeException in case the given matrices cannot be multiplied
- * due to different dimensions.
- */
- public short[][] multiplyMatrix(short[][] M1, short[][] M2)
- throws RuntimeException
- {
-
- if (M1[0].length != M2.length)
- {
- throw new RuntimeException("Multiplication is not possible!");
- }
- short tmp = 0;
- A = new short[M1.length][M2[0].length];
- for (int i = 0; i < M1.length; i++)
- {
- for (int j = 0; j < M2.length; j++)
- {
- for (int k = 0; k < M2[0].length; k++)
- {
- tmp = GF2Field.multElem(M1[i][j], M2[j][k]);
- A[i][k] = GF2Field.addElem(A[i][k], tmp);
- }
- }
- }
- return A;
- }
-
- /**
- * This function multiplies a given matrix with a one-dimensional array.
- * <p>
- * An exception is thrown, if the number of columns in the matrix and
- * the number of rows in the one-dim. array differ.
- *
- * @param M1 the matrix to be multiplied
- * @param m the one-dimensional array to be multiplied
- * @return M1*m
- * @throws RuntimeException in case of dimension inconsistency
- */
- public short[] multiplyMatrix(short[][] M1, short[] m)
- throws RuntimeException
- {
- if (M1[0].length != m.length)
- {
- throw new RuntimeException("Multiplication is not possible!");
- }
- short tmp = 0;
- short[] B = new short[M1.length];
- for (int i = 0; i < M1.length; i++)
- {
- for (int j = 0; j < m.length; j++)
- {
- tmp = GF2Field.multElem(M1[i][j], m[j]);
- B[i] = GF2Field.addElem(B[i], tmp);
- }
- }
- return B;
- }
-
- /**
- * Addition of two vectors
- *
- * @param vector1 first summand, always of dim n
- * @param vector2 second summand, always of dim n
- * @return addition of vector1 and vector2
- * @throws RuntimeException in case the addition is impossible
- * due to inconsistency in the dimensions
- */
- public short[] addVect(short[] vector1, short[] vector2)
- {
- if (vector1.length != vector2.length)
- {
- throw new RuntimeException("Multiplication is not possible!");
- }
- short rslt[] = new short[vector1.length];
- for (int n = 0; n < rslt.length; n++)
- {
- rslt[n] = GF2Field.addElem(vector1[n], vector2[n]);
- }
- return rslt;
- }
-
- /**
- * Multiplication of column vector with row vector
- *
- * @param vector1 column vector, always n x 1
- * @param vector2 row vector, always 1 x n
- * @return resulting n x n matrix of multiplication
- * @throws RuntimeException in case the multiplication is impossible due to
- * inconsistency in the dimensions
- */
- public short[][] multVects(short[] vector1, short[] vector2)
- {
- if (vector1.length != vector2.length)
- {
- throw new RuntimeException("Multiplication is not possible!");
- }
- short rslt[][] = new short[vector1.length][vector2.length];
- for (int i = 0; i < vector1.length; i++)
- {
- for (int j = 0; j < vector2.length; j++)
- {
- rslt[i][j] = GF2Field.multElem(vector1[i], vector2[j]);
- }
- }
- return rslt;
- }
-
- /**
- * Multiplies vector with scalar
- *
- * @param scalar galois element to multiply vector with
- * @param vector vector to be multiplied
- * @return vector multiplied with scalar
- */
- public short[] multVect(short scalar, short[] vector)
- {
- short rslt[] = new short[vector.length];
- for (int n = 0; n < rslt.length; n++)
- {
- rslt[n] = GF2Field.multElem(scalar, vector[n]);
- }
- return rslt;
- }
-
- /**
- * Multiplies matrix with scalar
- *
- * @param scalar galois element to multiply matrix with
- * @param matrix 2-dim n x n matrix to be multiplied
- * @return matrix multiplied with scalar
- */
- public short[][] multMatrix(short scalar, short[][] matrix)
- {
- short[][] rslt = new short[matrix.length][matrix[0].length];
- for (int i = 0; i < matrix.length; i++)
- {
- for (int j = 0; j < matrix[0].length; j++)
- {
- rslt[i][j] = GF2Field.multElem(scalar, matrix[i][j]);
- }
- }
- return rslt;
- }
-
- /**
- * Adds the n x n matrices matrix1 and matrix2
- *
- * @param matrix1 first summand
- * @param matrix2 second summand
- * @return addition of matrix1 and matrix2; both having the dimensions n x n
- * @throws RuntimeException in case the addition is not possible because of
- * different dimensions of the matrices
- */
- public short[][] addSquareMatrix(short[][] matrix1, short[][] matrix2)
- {
- if (matrix1.length != matrix2.length || matrix1[0].length != matrix2[0].length)
- {
- throw new RuntimeException("Addition is not possible!");
- }
-
- short[][] rslt = new short[matrix1.length][matrix1.length];//
- for (int i = 0; i < matrix1.length; i++)
- {
- for (int j = 0; j < matrix2.length; j++)
- {
- rslt[i][j] = GF2Field.addElem(matrix1[i][j], matrix2[i][j]);
- }
- }
- return rslt;
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/GF2Field.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/GF2Field.java
deleted file mode 100644
index 8d54279..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/GF2Field.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow.util;
-
-/**
- * This class provides the basic operations like addition, multiplication and
- * finding the multiplicative inverse of an element in GF2^8.
- * <p>
- * The operations are implemented using the irreducible polynomial
- * 1+x^2+x^3+x^6+x^8 ( 1 0100 1101 = 0x14d )
- * <p>
- * This class makes use of lookup tables(exps and logs) for implementing the
- * operations in order to increase the efficiency of Rainbow.
- */
-public class GF2Field
-{
-
- public static final int MASK = 0xff;
-
- /*
- * this lookup table is needed for multiplication and computing the
- * multiplicative inverse
- */
- static final short exps[] = {1, 2, 4, 8, 16, 32, 64, 128, 77, 154, 121, 242,
- 169, 31, 62, 124, 248, 189, 55, 110, 220, 245, 167, 3, 6, 12, 24,
- 48, 96, 192, 205, 215, 227, 139, 91, 182, 33, 66, 132, 69, 138, 89,
- 178, 41, 82, 164, 5, 10, 20, 40, 80, 160, 13, 26, 52, 104, 208,
- 237, 151, 99, 198, 193, 207, 211, 235, 155, 123, 246, 161, 15, 30,
- 60, 120, 240, 173, 23, 46, 92, 184, 61, 122, 244, 165, 7, 14, 28,
- 56, 112, 224, 141, 87, 174, 17, 34, 68, 136, 93, 186, 57, 114, 228,
- 133, 71, 142, 81, 162, 9, 18, 36, 72, 144, 109, 218, 249, 191, 51,
- 102, 204, 213, 231, 131, 75, 150, 97, 194, 201, 223, 243, 171, 27,
- 54, 108, 216, 253, 183, 35, 70, 140, 85, 170, 25, 50, 100, 200,
- 221, 247, 163, 11, 22, 44, 88, 176, 45, 90, 180, 37, 74, 148, 101,
- 202, 217, 255, 179, 43, 86, 172, 21, 42, 84, 168, 29, 58, 116, 232,
- 157, 119, 238, 145, 111, 222, 241, 175, 19, 38, 76, 152, 125, 250,
- 185, 63, 126, 252, 181, 39, 78, 156, 117, 234, 153, 127, 254, 177,
- 47, 94, 188, 53, 106, 212, 229, 135, 67, 134, 65, 130, 73, 146,
- 105, 210, 233, 159, 115, 230, 129, 79, 158, 113, 226, 137, 95, 190,
- 49, 98, 196, 197, 199, 195, 203, 219, 251, 187, 59, 118, 236, 149,
- 103, 206, 209, 239, 147, 107, 214, 225, 143, 83, 166, 1};
-
- /*
- * this lookup table is needed for multiplication and computing the
- * multiplicative inverse
- */
- static final short logs[] = {0, 0, 1, 23, 2, 46, 24, 83, 3, 106, 47, 147,
- 25, 52, 84, 69, 4, 92, 107, 182, 48, 166, 148, 75, 26, 140, 53,
- 129, 85, 170, 70, 13, 5, 36, 93, 135, 108, 155, 183, 193, 49, 43,
- 167, 163, 149, 152, 76, 202, 27, 230, 141, 115, 54, 205, 130, 18,
- 86, 98, 171, 240, 71, 79, 14, 189, 6, 212, 37, 210, 94, 39, 136,
- 102, 109, 214, 156, 121, 184, 8, 194, 223, 50, 104, 44, 253, 168,
- 138, 164, 90, 150, 41, 153, 34, 77, 96, 203, 228, 28, 123, 231, 59,
- 142, 158, 116, 244, 55, 216, 206, 249, 131, 111, 19, 178, 87, 225,
- 99, 220, 172, 196, 241, 175, 72, 10, 80, 66, 15, 186, 190, 199, 7,
- 222, 213, 120, 38, 101, 211, 209, 95, 227, 40, 33, 137, 89, 103,
- 252, 110, 177, 215, 248, 157, 243, 122, 58, 185, 198, 9, 65, 195,
- 174, 224, 219, 51, 68, 105, 146, 45, 82, 254, 22, 169, 12, 139,
- 128, 165, 74, 91, 181, 151, 201, 42, 162, 154, 192, 35, 134, 78,
- 188, 97, 239, 204, 17, 229, 114, 29, 61, 124, 235, 232, 233, 60,
- 234, 143, 125, 159, 236, 117, 30, 245, 62, 56, 246, 217, 63, 207,
- 118, 250, 31, 132, 160, 112, 237, 20, 144, 179, 126, 88, 251, 226,
- 32, 100, 208, 221, 119, 173, 218, 197, 64, 242, 57, 176, 247, 73,
- 180, 11, 127, 81, 21, 67, 145, 16, 113, 187, 238, 191, 133, 200,
- 161};
-
- /**
- * This function calculates the sum of two elements as an operation in GF2^8
- *
- * @param x the first element that is to be added
- * @param y the second element that should be add
- * @return the sum of the two elements x and y in GF2^8
- */
- public static short addElem(short x, short y)
- {
- return (short)(x ^ y);
- }
-
- /**
- * This function computes the multiplicative inverse of a given element in
- * GF2^8 The 0 has no multiplicative inverse and in this case 0 is returned.
- *
- * @param x the element which multiplicative inverse is to be computed
- * @return the multiplicative inverse of the given element, in case it
- * exists or 0, otherwise
- */
- public static short invElem(short x)
- {
- if (x == 0)
- {
- return 0;
- }
- return (exps[255 - logs[x]]);
- }
-
- /**
- * This function multiplies two elements in GF2^8. If one of the two
- * elements is 0, 0 is returned.
- *
- * @param x the first element to be multiplied.
- * @param y the second element to be multiplied.
- * @return the product of the two input elements in GF2^8.
- */
- public static short multElem(short x, short y)
- {
- if (x == 0 || y == 0)
- {
- return 0;
- }
- else
- {
- return (exps[(logs[x] + logs[y]) % 255]);
- }
- }
-
- /**
- * This function returns the values of exps-lookup table which correspond to
- * the input
- *
- * @param x the index in the lookup table exps
- * @return exps-value, corresponding to the input
- */
- public static short getExp(short x)
- {
- return exps[x];
- }
-
- /**
- * This function returns the values of logs-lookup table which correspond to
- * the input
- *
- * @param x the index in the lookup table logs
- * @return logs-value, corresponding to the input
- */
- public static short getLog(short x)
- {
- return logs[x];
- }
-
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/RainbowUtil.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/RainbowUtil.java
deleted file mode 100644
index 2b073b1..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/rainbow/util/RainbowUtil.java
+++ /dev/null
@@ -1,230 +0,0 @@
-package org.bouncycastle.pqc.crypto.rainbow.util;
-
-/**
- * This class is needed for the conversions while encoding and decoding, as well as for
- * comparison between arrays of some dimensions
- */
-public class RainbowUtil
-{
-
- /**
- * This function converts an one-dimensional array of bytes into a
- * one-dimensional array of int
- *
- * @param in the array to be converted
- * @return out
- * the one-dimensional int-array that corresponds the input
- */
- public static int[] convertArraytoInt(byte[] in)
- {
- int[] out = new int[in.length];
- for (int i = 0; i < in.length; i++)
- {
- out[i] = in[i] & GF2Field.MASK;
- }
- return out;
- }
-
- /**
- * This function converts an one-dimensional array of bytes into a
- * one-dimensional array of type short
- *
- * @param in the array to be converted
- * @return out
- * one-dimensional short-array that corresponds the input
- */
- public static short[] convertArray(byte[] in)
- {
- short[] out = new short[in.length];
- for (int i = 0; i < in.length; i++)
- {
- out[i] = (short)(in[i] & GF2Field.MASK);
- }
- return out;
- }
-
- /**
- * This function converts a matrix of bytes into a matrix of type short
- *
- * @param in the matrix to be converted
- * @return out
- * short-matrix that corresponds the input
- */
- public static short[][] convertArray(byte[][] in)
- {
- short[][] out = new short[in.length][in[0].length];
- for (int i = 0; i < in.length; i++)
- {
- for (int j = 0; j < in[0].length; j++)
- {
- out[i][j] = (short)(in[i][j] & GF2Field.MASK);
- }
- }
- return out;
- }
-
- /**
- * This function converts a 3-dimensional array of bytes into a 3-dimensional array of type short
- *
- * @param in the array to be converted
- * @return out
- * short-array that corresponds the input
- */
- public static short[][][] convertArray(byte[][][] in)
- {
- short[][][] out = new short[in.length][in[0].length][in[0][0].length];
- for (int i = 0; i < in.length; i++)
- {
- for (int j = 0; j < in[0].length; j++)
- {
- for (int k = 0; k < in[0][0].length; k++)
- {
- out[i][j][k] = (short)(in[i][j][k] & GF2Field.MASK);
- }
- }
- }
- return out;
- }
-
- /**
- * This function converts an array of type int into an array of type byte
- *
- * @param in the array to be converted
- * @return out
- * the byte-array that corresponds the input
- */
- public static byte[] convertIntArray(int[] in)
- {
- byte[] out = new byte[in.length];
- for (int i = 0; i < in.length; i++)
- {
- out[i] = (byte)in[i];
- }
- return out;
- }
-
-
- /**
- * This function converts an array of type short into an array of type byte
- *
- * @param in the array to be converted
- * @return out
- * the byte-array that corresponds the input
- */
- public static byte[] convertArray(short[] in)
- {
- byte[] out = new byte[in.length];
- for (int i = 0; i < in.length; i++)
- {
- out[i] = (byte)in[i];
- }
- return out;
- }
-
- /**
- * This function converts a matrix of type short into a matrix of type byte
- *
- * @param in the matrix to be converted
- * @return out
- * the byte-matrix that corresponds the input
- */
- public static byte[][] convertArray(short[][] in)
- {
- byte[][] out = new byte[in.length][in[0].length];
- for (int i = 0; i < in.length; i++)
- {
- for (int j = 0; j < in[0].length; j++)
- {
- out[i][j] = (byte)in[i][j];
- }
- }
- return out;
- }
-
- /**
- * This function converts a 3-dimensional array of type short into a 3-dimensional array of type byte
- *
- * @param in the array to be converted
- * @return out
- * the byte-array that corresponds the input
- */
- public static byte[][][] convertArray(short[][][] in)
- {
- byte[][][] out = new byte[in.length][in[0].length][in[0][0].length];
- for (int i = 0; i < in.length; i++)
- {
- for (int j = 0; j < in[0].length; j++)
- {
- for (int k = 0; k < in[0][0].length; k++)
- {
- out[i][j][k] = (byte)in[i][j][k];
- }
- }
- }
- return out;
- }
-
- /**
- * Compare two short arrays. No null checks are performed.
- *
- * @param left the first short array
- * @param right the second short array
- * @return the result of the comparison
- */
- public static boolean equals(short[] left, short[] right)
- {
- if (left.length != right.length)
- {
- return false;
- }
- boolean result = true;
- for (int i = left.length - 1; i >= 0; i--)
- {
- result &= left[i] == right[i];
- }
- return result;
- }
-
- /**
- * Compare two two-dimensional short arrays. No null checks are performed.
- *
- * @param left the first short array
- * @param right the second short array
- * @return the result of the comparison
- */
- public static boolean equals(short[][] left, short[][] right)
- {
- if (left.length != right.length)
- {
- return false;
- }
- boolean result = true;
- for (int i = left.length - 1; i >= 0; i--)
- {
- result &= equals(left[i], right[i]);
- }
- return result;
- }
-
- /**
- * Compare two three-dimensional short arrays. No null checks are performed.
- *
- * @param left the first short array
- * @param right the second short array
- * @return the result of the comparison
- */
- public static boolean equals(short[][][] left, short[][][] right)
- {
- if (left.length != right.length)
- {
- return false;
- }
- boolean result = true;
- for (int i = left.length - 1; i >= 0; i--)
- {
- result &= equals(left[i], right[i]);
- }
- return result;
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/AllTests.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/AllTests.java
deleted file mode 100644
index 4559fdb..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/AllTests.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-import org.bouncycastle.util.test.SimpleTestResult;
-
-public class AllTests
- extends TestCase
-{
- public void testCrypto()
- {
- org.bouncycastle.util.test.Test[] tests = RegressionTest.tests;
-
- for (int i = 0; i != tests.length; i++)
- {
- SimpleTestResult result = (SimpleTestResult)tests[i].perform();
-
- if (!result.isSuccessful())
- {
- fail(result.toString());
- }
- }
- }
-
- public static void main (String[] args)
- {
- junit.textui.TestRunner.run(suite());
- }
-
- public static Test suite()
- {
- TestSuite suite = new TestSuite("Lightweight PQ Crypto Tests");
-
- suite.addTestSuite(AllTests.class);
- suite.addTestSuite(BitStringTest.class);
- suite.addTestSuite(EncryptionKeyTest.class);
- suite.addTestSuite(NTRUEncryptionParametersTest.class);
- suite.addTestSuite(NTRUEncryptTest.class);
- suite.addTestSuite(NTRUSignatureParametersTest.class);
- suite.addTestSuite(NTRUSignatureKeyTest.class);
- suite.addTestSuite(NTRUSignerTest.class);
- suite.addTestSuite(NTRUSigningParametersTest.class);
-
- return suite;
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/BitStringTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/BitStringTest.java
deleted file mode 100644
index 85e1ffa..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/BitStringTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import junit.framework.TestCase;
-import org.bouncycastle.pqc.crypto.ntru.IndexGenerator.BitString;
-import org.bouncycastle.util.Arrays;
-
-public class BitStringTest
- extends TestCase
-{
- public void testAppendBitsByteArray()
- {
- BitString bs = new BitString();
- bs.appendBits((byte)78);
- assertBitStringEquals(bs, new byte[]{78});
- bs.appendBits((byte)-5);
- assertBitStringEquals(bs, new byte[]{78, -5});
- bs.appendBits((byte)127);
- assertBitStringEquals(bs, new byte[]{78, -5, 127});
- bs.appendBits((byte)0);
- assertBitStringEquals(bs, new byte[]{78, -5, 127, 0});
- bs.appendBits((byte)100);
- assertBitStringEquals(bs, new byte[]{78, -5, 127, 0, 100});
- }
-
- private void assertBitStringEquals(BitString bs, byte[] arr)
- {
- byte[] bsBytes = bs.getBytes();
-
- assertTrue(bsBytes.length >= arr.length);
- arr = copyOf(arr, bsBytes.length);
- assertTrue(Arrays.areEqual(arr, bsBytes));
- }
-
- public void testGetTrailing()
- {
- BitString bs = new BitString();
- bs.appendBits((byte)78);
- BitString bs2 = bs.getTrailing(3);
- assertBitStringEquals(bs2, new byte[]{6});
-
- bs = new BitString();
- bs.appendBits((byte)78);
- bs.appendBits((byte)-5);
- bs2 = bs.getTrailing(9);
- assertBitStringEquals(bs2, new byte[]{78, 1});
-
- bs2.appendBits((byte)100);
- assertBitStringEquals(bs2, new byte[]{78, -55});
- bs = bs2.getTrailing(13);
- assertBitStringEquals(bs, new byte[]{78, 9});
- bs2 = bs2.getTrailing(11);
- assertBitStringEquals(bs2, new byte[]{78, 1});
-
- bs2.appendBits((byte)100);
- assertBitStringEquals(bs2, new byte[]{78, 33, 3});
- bs2 = bs2.getTrailing(16);
- assertBitStringEquals(bs2, new byte[]{78, 33});
- }
-
- public void testGetLeadingAsInt()
- {
- BitString bs = new BitString();
- bs.appendBits((byte)78);
- bs.appendBits((byte)42);
- assertEquals(1, bs.getLeadingAsInt(3));
- assertEquals(84, bs.getLeadingAsInt(9));
- assertEquals(338, bs.getLeadingAsInt(11));
-
- BitString bs2 = bs.getTrailing(11);
- assertBitStringEquals(bs2, new byte[]{78, 2});
- assertEquals(590, bs2.getLeadingAsInt(11));
- assertEquals(9, bs2.getLeadingAsInt(5));
-
- bs2.appendBits((byte)115);
- assertEquals(230, bs2.getLeadingAsInt(9));
- assertEquals(922, bs2.getLeadingAsInt(11));
-
- bs2.appendBits((byte)-36);
- assertEquals(55, bs2.getLeadingAsInt(6));
- }
-
- private byte[] copyOf(byte[] src, int length)
- {
- byte[] tmp = new byte[length];
- System.arraycopy(src, 0, tmp, 0, tmp.length > src.length ? src.length : tmp.length);
- return tmp;
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/EncryptionKeyTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/EncryptionKeyTest.java
deleted file mode 100644
index f023406..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/EncryptionKeyTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import junit.framework.TestCase;
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyPairGenerator;
-import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionPrivateKeyParameters;
-import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionPublicKeyParameters;
-
-public class EncryptionKeyTest
- extends TestCase
-{
- public void testEncode()
- throws IOException
- {
- for (NTRUEncryptionKeyGenerationParameters params : new NTRUEncryptionKeyGenerationParameters[]{NTRUEncryptionKeyGenerationParameters.APR2011_743, NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST, NTRUEncryptionKeyGenerationParameters.EES1499EP1})
- {
- testEncode(params);
- }
- }
-
- private void testEncode(NTRUEncryptionKeyGenerationParameters params)
- throws IOException
- {
- NTRUEncryptionKeyPairGenerator kpGen = new NTRUEncryptionKeyPairGenerator();
-
- kpGen.init(params);
-
- AsymmetricCipherKeyPair kp = kpGen.generateKeyPair();
- byte[] priv = ((NTRUEncryptionPrivateKeyParameters)kp.getPrivate()).getEncoded();
- byte[] pub = ((NTRUEncryptionPublicKeyParameters)kp.getPublic()).getEncoded();
-
- AsymmetricCipherKeyPair kp2 = new AsymmetricCipherKeyPair(new NTRUEncryptionPublicKeyParameters(pub, params.getEncryptionParameters()), new NTRUEncryptionPrivateKeyParameters(priv, params.getEncryptionParameters()));
- assertEquals(kp.getPublic(), kp2.getPublic());
- assertEquals(kp.getPrivate(), kp2.getPrivate());
-
- ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
- ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
- ((NTRUEncryptionPrivateKeyParameters)kp.getPrivate()).writeTo(bos1);
- ((NTRUEncryptionPublicKeyParameters)kp.getPublic()).writeTo(bos2);
- ByteArrayInputStream bis1 = new ByteArrayInputStream(bos1.toByteArray());
- ByteArrayInputStream bis2 = new ByteArrayInputStream(bos2.toByteArray());
- AsymmetricCipherKeyPair kp3 = new AsymmetricCipherKeyPair(new NTRUEncryptionPublicKeyParameters(bis2, params.getEncryptionParameters()), new NTRUEncryptionPrivateKeyParameters(bis1, params.getEncryptionParameters()));
- assertEquals(kp.getPublic(), kp3.getPublic());
- assertEquals(kp.getPrivate(), kp3.getPrivate());
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/GMSSSignerTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/GMSSSignerTest.java
deleted file mode 100644
index 69b2842..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/GMSSSignerTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.Signer;
-import org.bouncycastle.crypto.digests.SHA224Digest;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.DigestingMessageSigner;
-import org.bouncycastle.pqc.crypto.gmss.GMSSDigestProvider;
-import org.bouncycastle.pqc.crypto.gmss.GMSSKeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.gmss.GMSSKeyPairGenerator;
-import org.bouncycastle.pqc.crypto.gmss.GMSSParameters;
-import org.bouncycastle.pqc.crypto.gmss.GMSSPrivateKeyParameters;
-import org.bouncycastle.pqc.crypto.gmss.GMSSSigner;
-import org.bouncycastle.util.BigIntegers;
-import org.bouncycastle.util.encoders.Hex;
-import org.bouncycastle.util.test.FixedSecureRandom;
-import org.bouncycastle.util.test.SimpleTest;
-
-
-public class GMSSSignerTest
- extends SimpleTest
-{
- byte[] keyData = Hex.decode("b5014e4b60ef2ba8b6211b4062ba3224e0427dd3");
-
- SecureRandom keyRandom = new FixedSecureRandom(new byte[][]{keyData, keyData});
-
- public String getName()
- {
- return "GMSS";
- }
-
- public void performTest()
- throws Exception
- {
-
- GMSSParameters params = new GMSSParameters(3,
- new int[]{15, 15, 10}, new int[]{5, 5, 4}, new int[]{3, 3, 2});
-
- GMSSDigestProvider digProvider = new GMSSDigestProvider()
- {
- public Digest get()
- {
- return new SHA224Digest();
- }
- };
-
- GMSSKeyPairGenerator gmssKeyGen = new GMSSKeyPairGenerator(digProvider);
-
- GMSSKeyGenerationParameters genParam = new GMSSKeyGenerationParameters(keyRandom, params);
-
- gmssKeyGen.init(genParam);
-
- AsymmetricCipherKeyPair pair = gmssKeyGen.generateKeyPair();
-
- ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), keyRandom);
-
- // TODO
- Signer gmssSigner = new DigestingMessageSigner(new GMSSSigner(digProvider), new SHA224Digest());
- gmssSigner.init(true, param);
-
- byte[] message = BigIntegers.asUnsignedByteArray(new BigInteger("968236873715988614170569073515315707566766479517"));
- gmssSigner.update(message, 0, message.length);
- byte[] sig = gmssSigner.generateSignature();
-
-
- gmssSigner.init(false, pair.getPublic());
- gmssSigner.update(message, 0, message.length);
- if (!gmssSigner.verifySignature(sig))
- {
- fail("verification fails");
- }
-
- if (!((GMSSPrivateKeyParameters)pair.getPrivate()).isUsed())
- {
- fail("private key not marked as used");
- }
- }
-
- public static void main(
- String[] args)
- {
- runTest(new GMSSSignerTest());
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McElieceFujisakiCipherTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McElieceFujisakiCipherTest.java
deleted file mode 100644
index dfc44b6..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McElieceFujisakiCipherTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.security.SecureRandom;
-import java.util.Random;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA256Digest;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyPairGenerator;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2Parameters;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceFujisakiCipher;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceFujisakiDigestCipher;
-import org.bouncycastle.util.test.SimpleTest;
-
-public class McElieceFujisakiCipherTest
- extends SimpleTest
-{
-
- SecureRandom keyRandom = new SecureRandom();
-
- public String getName()
- {
- return "McElieceFujisaki";
-
- }
-
-
- public void performTest()
- {
- int numPassesKPG = 1;
- int numPassesEncDec = 10;
- Random rand = new Random();
- byte[] mBytes;
- for (int j = 0; j < numPassesKPG; j++)
- {
-
- McElieceCCA2Parameters params = new McElieceCCA2Parameters();
- McElieceCCA2KeyPairGenerator mcElieceCCA2KeyGen = new McElieceCCA2KeyPairGenerator();
- McElieceCCA2KeyGenerationParameters genParam = new McElieceCCA2KeyGenerationParameters(keyRandom, params);
-
- mcElieceCCA2KeyGen.init(genParam);
- AsymmetricCipherKeyPair pair = mcElieceCCA2KeyGen.generateKeyPair();
-
- ParametersWithRandom param = new ParametersWithRandom(pair.getPublic(), keyRandom);
- Digest msgDigest = new SHA256Digest();
- McElieceFujisakiDigestCipher mcElieceFujisakiDigestCipher = new McElieceFujisakiDigestCipher(new McElieceFujisakiCipher(), msgDigest);
-
-
- for (int k = 1; k <= numPassesEncDec; k++)
- {
- System.out.println("############### test: " + k);
- // initialize for encryption
- mcElieceFujisakiDigestCipher.init(true, param);
-
- // generate random message
- int mLength = (rand.nextInt() & 0x1f) + 1;;
- mBytes = new byte[mLength];
- rand.nextBytes(mBytes);
-
- // encrypt
- mcElieceFujisakiDigestCipher.update(mBytes, 0, mBytes.length);
- byte[] enc = mcElieceFujisakiDigestCipher.messageEncrypt();
-
- // initialize for decryption
- mcElieceFujisakiDigestCipher.init(false, pair.getPrivate());
- byte[] constructedmessage = mcElieceFujisakiDigestCipher.messageDecrypt(enc);
-
- // XXX write in McElieceFujisakiDigestCipher?
- msgDigest.update(mBytes, 0, mBytes.length);
- byte[] hash = new byte[msgDigest.getDigestSize()];
- msgDigest.doFinal(hash, 0);
-
- boolean verified = true;
- for (int i = 0; i < hash.length; i++)
- {
- verified = verified && hash[i] == constructedmessage[i];
- }
-
- if (!verified)
- {
- fail("en/decryption fails");
- }
- else
- {
- System.out.println("test okay");
- System.out.println();
- }
-
- }
- }
-
- }
-
- public static void main(
- String[] args)
- {
- runTest(new McElieceFujisakiCipherTest());
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McElieceKobaraImaiCipherTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McElieceKobaraImaiCipherTest.java
deleted file mode 100644
index 849e656..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McElieceKobaraImaiCipherTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.security.SecureRandom;
-import java.util.Random;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA256Digest;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyPairGenerator;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2Parameters;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceKobaraImaiCipher;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceKobaraImaiDigestCipher;
-import org.bouncycastle.util.test.SimpleTest;
-
-public class McElieceKobaraImaiCipherTest
- extends SimpleTest
-{
-
- SecureRandom keyRandom = new SecureRandom();
-
- public String getName()
- {
- return "McElieceKobaraImai";
-
- }
-
-
- public void performTest()
- {
- int numPassesKPG = 1;
- int numPassesEncDec = 10;
- Random rand = new Random();
- byte[] mBytes;
- for (int j = 0; j < numPassesKPG; j++)
- {
-
- McElieceCCA2Parameters params = new McElieceCCA2Parameters();
- McElieceCCA2KeyPairGenerator mcElieceCCA2KeyGen = new McElieceCCA2KeyPairGenerator();
- McElieceCCA2KeyGenerationParameters genParam = new McElieceCCA2KeyGenerationParameters(keyRandom, params);
-
- mcElieceCCA2KeyGen.init(genParam);
- AsymmetricCipherKeyPair pair = mcElieceCCA2KeyGen.generateKeyPair();
-
- ParametersWithRandom param = new ParametersWithRandom(pair.getPublic(), keyRandom);
- Digest msgDigest = new SHA256Digest();
- McElieceKobaraImaiDigestCipher mcElieceKobaraImaiDigestCipher = new McElieceKobaraImaiDigestCipher(new McElieceKobaraImaiCipher(), msgDigest);
-
-
- for (int k = 1; k <= numPassesEncDec; k++)
- {
- System.out.println("############### test: " + k);
- // initialize for encryption
- mcElieceKobaraImaiDigestCipher.init(true, param);
-
- // generate random message
- int mLength = (rand.nextInt() & 0x1f) + 1;
- mBytes = new byte[mLength];
- rand.nextBytes(mBytes);
-
- // encrypt
- mcElieceKobaraImaiDigestCipher.update(mBytes, 0, mBytes.length);
- byte[] enc = mcElieceKobaraImaiDigestCipher.messageEncrypt();
-
- // initialize for decryption
- mcElieceKobaraImaiDigestCipher.init(false, pair.getPrivate());
- byte[] constructedmessage = mcElieceKobaraImaiDigestCipher.messageDecrypt(enc);
-
- // XXX write in McElieceFujisakiDigestCipher?
- msgDigest.update(mBytes, 0, mBytes.length);
- byte[] hash = new byte[msgDigest.getDigestSize()];
- msgDigest.doFinal(hash, 0);
-
- boolean verified = true;
- for (int i = 0; i < hash.length; i++)
- {
- verified = verified && hash[i] == constructedmessage[i];
- }
-
- if (!verified)
- {
- fail("en/decryption fails");
- }
- else
- {
- System.out.println("test okay");
- System.out.println();
- }
-
- }
- }
-
- }
-
- public static void main(
- String[] args)
- {
- runTest(new McElieceKobaraImaiCipherTest());
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McEliecePKCSCipherTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McEliecePKCSCipherTest.java
deleted file mode 100644
index edb1d60..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McEliecePKCSCipherTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.security.SecureRandom;
-import java.util.Random;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA256Digest;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceKeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceKeyPairGenerator;
-import org.bouncycastle.pqc.crypto.mceliece.McEliecePKCSCipher;
-import org.bouncycastle.pqc.crypto.mceliece.McEliecePKCSDigestCipher;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceParameters;
-import org.bouncycastle.util.test.SimpleTest;
-
-public class McEliecePKCSCipherTest
- extends SimpleTest
-{
-
- SecureRandom keyRandom = new SecureRandom();
-
- public String getName()
- {
- return "McEliecePKCS";
-
- }
-
-
- public void performTest()
- {
- int numPassesKPG = 1;
- int numPassesEncDec = 10;
- Random rand = new Random();
- byte[] mBytes;
- for (int j = 0; j < numPassesKPG; j++)
- {
-
- McElieceParameters params = new McElieceParameters();
- McElieceKeyPairGenerator mcElieceKeyGen = new McElieceKeyPairGenerator();
- McElieceKeyGenerationParameters genParam = new McElieceKeyGenerationParameters(keyRandom, params);
-
- mcElieceKeyGen.init(genParam);
- AsymmetricCipherKeyPair pair = mcElieceKeyGen.generateKeyPair();
-
- ParametersWithRandom param = new ParametersWithRandom(pair.getPublic(), keyRandom);
- Digest msgDigest = new SHA256Digest();
- McEliecePKCSDigestCipher mcEliecePKCSDigestCipher = new McEliecePKCSDigestCipher(new McEliecePKCSCipher(), msgDigest);
-
-
- for (int k = 1; k <= numPassesEncDec; k++)
- {
- System.out.println("############### test: " + k);
- // initialize for encryption
- mcEliecePKCSDigestCipher.init(true, param);
-
- // generate random message
- int mLength = (rand.nextInt() & 0x1f) + 1;
- mBytes = new byte[mLength];
- rand.nextBytes(mBytes);
-
- // encrypt
- mcEliecePKCSDigestCipher.update(mBytes, 0, mBytes.length);
- byte[] enc = mcEliecePKCSDigestCipher.messageEncrypt();
-
- // initialize for decryption
- mcEliecePKCSDigestCipher.init(false, pair.getPrivate());
- byte[] constructedmessage = mcEliecePKCSDigestCipher.messageDecrypt(enc);
-
- // XXX write in McElieceFujisakiDigestCipher?
- msgDigest.update(mBytes, 0, mBytes.length);
- byte[] hash = new byte[msgDigest.getDigestSize()];
- msgDigest.doFinal(hash, 0);
-
- boolean verified = true;
- for (int i = 0; i < hash.length; i++)
- {
- verified = verified && hash[i] == constructedmessage[i];
- }
-
- if (!verified)
- {
- fail("en/decryption fails");
- }
- else
- {
- System.out.println("test okay");
- System.out.println();
- }
-
- }
- }
-
- }
-
- public static void main(
- String[] args)
- {
- runTest(new McEliecePKCSCipherTest());
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McEliecePointchevalCipherTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McEliecePointchevalCipherTest.java
deleted file mode 100644
index 23ba3f9..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/McEliecePointchevalCipherTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.security.SecureRandom;
-import java.util.Random;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA256Digest;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2KeyPairGenerator;
-import org.bouncycastle.pqc.crypto.mceliece.McElieceCCA2Parameters;
-import org.bouncycastle.pqc.crypto.mceliece.McEliecePointchevalCipher;
-import org.bouncycastle.pqc.crypto.mceliece.McEliecePointchevalDigestCipher;
-import org.bouncycastle.util.test.SimpleTest;
-
-public class McEliecePointchevalCipherTest
- extends SimpleTest
-{
-
- SecureRandom keyRandom = new SecureRandom();
-
- public String getName()
- {
- return "McElieceFujisaki";
-
- }
-
-
- public void performTest()
- {
- int numPassesKPG = 1;
- int numPassesEncDec = 10;
- Random rand = new Random();
- byte[] mBytes;
- for (int j = 0; j < numPassesKPG; j++)
- {
-
- McElieceCCA2Parameters params = new McElieceCCA2Parameters();
- McElieceCCA2KeyPairGenerator mcElieceCCA2KeyGen = new McElieceCCA2KeyPairGenerator();
- McElieceCCA2KeyGenerationParameters genParam = new McElieceCCA2KeyGenerationParameters(keyRandom, params);
-
- mcElieceCCA2KeyGen.init(genParam);
- AsymmetricCipherKeyPair pair = mcElieceCCA2KeyGen.generateKeyPair();
-
- ParametersWithRandom param = new ParametersWithRandom(pair.getPublic(), keyRandom);
- Digest msgDigest = new SHA256Digest();
- McEliecePointchevalDigestCipher mcEliecePointchevalDigestCipher = new McEliecePointchevalDigestCipher(new McEliecePointchevalCipher(), msgDigest);
-
-
- for (int k = 1; k <= numPassesEncDec; k++)
- {
- System.out.println("############### test: " + k);
- // initialize for encryption
- mcEliecePointchevalDigestCipher.init(true, param);
-
- // generate random message
- int mLength = (rand.nextInt() & 0x1f) + 1;
- mBytes = new byte[mLength];
- rand.nextBytes(mBytes);
-
- // encrypt
- mcEliecePointchevalDigestCipher.update(mBytes, 0, mBytes.length);
- byte[] enc = mcEliecePointchevalDigestCipher.messageEncrypt();
-
- // initialize for decryption
- mcEliecePointchevalDigestCipher.init(false, pair.getPrivate());
- byte[] constructedmessage = mcEliecePointchevalDigestCipher.messageDecrypt(enc);
-
- // XXX write in McElieceFujisakiDigestCipher?
- msgDigest.update(mBytes, 0, mBytes.length);
- byte[] hash = new byte[msgDigest.getDigestSize()];
- msgDigest.doFinal(hash, 0);
-
- boolean verified = true;
- for (int i = 0; i < hash.length; i++)
- {
- verified = verified && hash[i] == constructedmessage[i];
- }
-
- if (!verified)
- {
- fail("en/decryption fails");
- }
- else
- {
- System.out.println("test okay");
- System.out.println();
- }
-
- }
- }
-
- }
-
- public static void main(
- String[] args)
- {
- runTest(new McEliecePointchevalCipherTest());
- }
-
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUEncryptTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUEncryptTest.java
deleted file mode 100644
index df63a10..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUEncryptTest.java
+++ /dev/null
@@ -1,298 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.io.IOException;
-import java.security.SecureRandom;
-
-import junit.framework.TestCase;
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.DataLengthException;
-import org.bouncycastle.crypto.InvalidCipherTextException;
-import org.bouncycastle.pqc.crypto.ntru.NTRUEngine;
-import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyPairGenerator;
-import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionPrivateKeyParameters;
-import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionPublicKeyParameters;
-import org.bouncycastle.pqc.crypto.ntru.NTRUParameters;
-import org.bouncycastle.pqc.math.ntru.polynomial.DenseTernaryPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.IntegerPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.Polynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial;
-import org.bouncycastle.pqc.math.ntru.polynomial.TernaryPolynomial;
-import org.bouncycastle.util.Arrays;
-
-public class NTRUEncryptTest
- extends TestCase
-{
- public void testEncryptDecrypt()
- throws InvalidCipherTextException
- {
- NTRUEncryptionKeyGenerationParameters params = NTRUEncryptionKeyGenerationParameters.APR2011_743.clone();
- // set df1..df3 and dr1..dr3 so params can be used for SIMPLE as well as PRODUCT
- params.df1 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.df1;
- params.df2 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.df2;
- params.df3 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.df3;
- params.dr1 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.dr1;
- params.dr2 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.dr2;
- params.dr3 = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST.dr3;
-
- int[] values = new int[] { NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE, NTRUParameters.TERNARY_POLYNOMIAL_TYPE_PRODUCT };
-
- for (int i = 0; i != values.length; i++)
- {
- int polyType = values[i];
-
- boolean[] booleans = {true, false};
- for (int j = 0; j != booleans.length; j++)
- {
- params.polyType = polyType;
- params.fastFp = booleans[j];
-
- VisibleNTRUEngine ntru = new VisibleNTRUEngine();
- NTRUEncryptionKeyPairGenerator ntruGen = new NTRUEncryptionKeyPairGenerator();
-
- ntruGen.init(params);
-
- AsymmetricCipherKeyPair kp = ntruGen.generateKeyPair();
-
- testPolynomial(ntru, kp, params);
-
- testText(ntru, kp, params);
- // sparse/dense
- params.sparse = !params.sparse;
- testText(ntru, kp, params);
- params.sparse = !params.sparse;
-
- testEmpty(ntru, kp, params);
- testMaxLength(ntru, kp, params);
- testTooLong(ntru, kp, params);
- testInvalidEncoding(ntru, kp, params);
- }
- }
- }
-
- // encrypts and decrypts a polynomial
- private void testPolynomial(VisibleNTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params)
- {
- SecureRandom random = new SecureRandom();
- IntegerPolynomial m = DenseTernaryPolynomial.generateRandom(params.N, random);
- SparseTernaryPolynomial r = SparseTernaryPolynomial.generateRandom(params.N, params.dr, params.dr, random);
-
- ntru.init(true, kp.getPublic()); // just to set params
-
- IntegerPolynomial e = ntru.encrypt(m, r, ((NTRUEncryptionPublicKeyParameters)kp.getPublic()).h);
- IntegerPolynomial c = ntru.decrypt(e, ((NTRUEncryptionPrivateKeyParameters)kp.getPrivate()).t, ((NTRUEncryptionPrivateKeyParameters)kp.getPrivate()).fp);
-
- assertTrue(Arrays.areEqual(m.coeffs, c.coeffs));
- }
-
- // encrypts and decrypts text
- private void testText(NTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params)
- throws InvalidCipherTextException
- {
- byte[] plainText = "text to encrypt".getBytes();
-
- ntru.init(true, kp.getPublic());
-
- byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length);
-
- ntru.init(false, kp.getPrivate());
-
- byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length);
-
- assertTrue(Arrays.areEqual(plainText, decrypted));
- }
-
- // tests an empty message
- private void testEmpty(NTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params)
- throws InvalidCipherTextException
- {
- byte[] plainText = "".getBytes();
-
- ntru.init(true, kp.getPublic());
-
- byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length);
-
- ntru.init(false, kp.getPrivate());
-
- byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length);
-
- assertTrue(Arrays.areEqual(plainText, decrypted));
- }
-
- // tests a message of the maximum allowed length
- private void testMaxLength(NTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params)
- throws InvalidCipherTextException
- {
- byte[] plainText = new byte[params.maxMsgLenBytes];
- System.arraycopy("secret encrypted text".getBytes(), 0, plainText, 0, 21);
- ntru.init(true, kp.getPublic());
-
- byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length);
-
- ntru.init(false, kp.getPrivate());
-
- byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length);
-
- assertTrue(Arrays.areEqual(plainText, decrypted));
- }
-
- // tests a message that is too long
- private void testTooLong(NTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params)
- {
- byte[] plainText = new byte[params.maxMsgLenBytes + 1];
- try
- {
- System.arraycopy("secret encrypted text".getBytes(), 0, plainText, 0, 21);
-
- ntru.init(true, kp.getPublic());
-
- byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length);
-
- ntru.init(false, kp.getPrivate());
-
- byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length);
-
- assertTrue(Arrays.areEqual(plainText, decrypted));
- fail("An exception should have been thrown!");
- }
- catch (DataLengthException ex)
- {
- assertEquals("Message too long: " + plainText.length + ">" + params.maxMsgLenBytes, ex.getMessage());
- }
- catch (InvalidCipherTextException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
-
- // tests that altering the public key *AFTER* encryption causes the decrypted message to be rejected
- private void testInvalidEncoding(NTRUEngine ntru, AsymmetricCipherKeyPair kp, NTRUEncryptionKeyGenerationParameters params)
- {
- try
- {
- byte[] plainText = "secret encrypted text".getBytes();
- ntru.init(true, kp.getPublic());
-
- byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length);
-
- NTRUEncryptionPrivateKeyParameters orig = (NTRUEncryptionPrivateKeyParameters)kp.getPrivate();
- IntegerPolynomial h = (IntegerPolynomial)((NTRUEncryptionPublicKeyParameters)kp.getPublic()).h.clone();
- h.coeffs[0] = (h.coeffs[0] + 111) % params.q; // alter h
- NTRUEncryptionPrivateKeyParameters privKey = new NTRUEncryptionPrivateKeyParameters(h, orig.t, orig.fp, params.getEncryptionParameters());
-
- ntru.init(false, privKey);
-
- ntru.processBlock(encrypted, 0, encrypted.length);
-
- fail("An exception should have been thrown!");
- }
- catch (InvalidCipherTextException ex)
- {
- assertEquals("Invalid message encoding", ex.getMessage());
- }
- }
-
- // encrypts and decrypts text using an encoded key pair (fastFp=false, simple ternary polynomials)
- public void testEncodedKeysSlow()
- throws IOException, InvalidCipherTextException
- {
- byte[] plainText = "secret encrypted text".getBytes();
-
- // dense polynomials
- NTRUEncryptionKeyGenerationParameters params = NTRUEncryptionKeyGenerationParameters.APR2011_743;
- NTRUEngine ntru = new NTRUEngine();
-
- byte[] privBytes = {2, -94, 95, 65, -107, 27, 98, 62, -15, -62, 21, -4, 119, -117, 7, 68, 100, 113, -36, -82, 87, -87, -82, 24, -45, -75, -74, -108, 105, 24, 123, 117, 124, 74, -27, 42, -106, -78, 114, 27, 18, 77, -41, 105, -113, 39, 49, 46, 109, -69, 61, 77, 49, 117, 14, -29, 42, 3, 120, -121, -120, -37, 95, 84, 60, -9, -31, -64, 31, 72, 115, -15, 21, -6, 27, -60, -73, -29, -33, -81, -43, 106, 65, 114, 102, -14, -115, -96, 9, 54, 23, -18, -24, -76, 84, -41, -79, 35, 88, 11, 41, 67, 44, -63, -28, 76, 84, -41, -103, 106, -22, 35, -2, -40, -48, -121, -128, 76, 63, 123, -11, 103, -35, -32, 21, -51, -99, -40, -103, -12, 64, -80, 57, -56, 1, -51, 103, 83, 50, 111, -87, -98, 7, -109, 25, -51, 23, -92};
- byte[] pubBytes = {91, -66, -25, -81, -66, -33, 25, -31, 48, 23, -38, 20, -30, -120, -17, 1, 21, 51, -11, 102, -50, 62, 71, 79, 32, -49, -57, 105, 21, -34, -45, -67, 113, -46, -103, 57, 28, -54, -21, 94, -112, -63, 105, -100, -95, 21, -52, 50, 11, -22, -63, -35, -42, 50, 93, -40, 23, 0, 121, 23, -93, 111, -98, -14, 92, -24, -117, -8, -109, -118, -4, -107, -60, 100, -128, -47, -92, -117, -108, 39, -113, 43, 48, 68, 95, 123, -112, 41, -27, -99, 59, 33, -57, -120, -44, 72, -98, -105, -91, -52, -89, 107, 119, 87, -36, -102, -83, 67, -8, 30, -54, 74, 93, 119, -3, 126, 69, -104, -44, -24, 124, 108, -125, 73, 98, 121, -49, -37, -24, 87, -71, 91, 8, -31, -50, 95, 112, 27, 97, -93, 3, -73, -54, -16, -92, -108, -74, 88, -5, 23, 70, 69, -49, -46, -50, 65, 69, -54, -41, 109, 8, -80, -23, -84, 120, -77, 26, 99, -104, -33, 82, 91, 22, -17, 113, -29, 66, -7, -114, -101, -111, -47, -1, -3, -57, 62, 79, -70, -58, 45, 76, 28, -117, 59, -117, 113, 84, -55, 48, 119, 58, -105, -20, 80, 102, 14, -69, -69, 5, 11, -87, 107, 15, 105, -69, -27, -24, 47, -18, -54, -45, -67, 27, -52, -20, -94, 64, -26, -58, 98, 33, -61, 71, -101, 120, 28, 113, 72, 127, 50, 123, 36, -97, 78, 32, -74, 105, 62, 92, 84, -17, 21, -75, 24, -90, -78, -4, -121, 47, -82, 119, 27, -61, 17, -66, 43, 96, -49, -6, 66, -13, -75, -95, 64, -12, -39, 111, 46, -3, -123, 82, 12, -26, -30, -29, 71, -108, -79, -112, 13, 16, -70, 7, 100, 84, 89, -100, 114, 47, 56, 71, 83, 63, -61, -39, -53, -100, 23, -31, -52, -46, 36, -13, 62, 107, 28, -28, 92, 116, -59, 28, -111, -23, -44, 21, -2, 127, -112, 54, -126, 13, -104, 47, -43, -109, -19, 107, -94, -126, 50, 92, -69, 1, 115, -121, -52, -100, 25, 126, -7, 86, 77, 72, -2, -104, -42, 98, -16, 54, -67, 117, 14, -73, 4, 58, 121, 35, 1, 99, -127, -9, -60, 32, -37, -106, 6, -108, -13, -62, 23, -20, -9, 21, 15, 4, 126, -112, 123, 34, -67, -51, 43, -30, -75, 119, -112, -58, -55, -90, 2, -5, -46, -12, 119, 87, 24, -52, 2, -29, 113, 61, -82, -101, 57, -11, -107, -11, 67, -42, -43, -13, 112, -49, 82, 60, 13, -50, 108, 64, -64, 53, -107, -9, 102, -33, 75, -100, -115, 102, -113, -48, 19, -119, -72, -65, 22, -65, -93, 34, -71, 75, 101, 54, 126, 75, 34, -21, -53, -36, 127, -21, 70, 24, 89, -88, 63, -43, -4, 68, 97, -45, -101, -125, -38, 98, -118, -34, -63, 23, 78, 15, 17, 101, -107, 119, -41, 107, 117, 17, 108, 43, -93, -6, -23, -30, 49, -61, 27, 61, -125, -68, 51, 40, -106, -61, 51, 127, 2, 123, 7, -50, -115, -32, -95, -96, 67, 4, 5, 59, -45, 61, 95, 14, 2, -76, -121, 8, 125, 16, -126, 58, 118, -32, 19, -113, -113, 120, -101, 86, 76, -90, 50, -92, 51, -92, 1, 121, -74, -101, -33, 53, -53, -83, 46, 20, -87, -112, -61, -87, 106, -126, 64, 99, -60, 70, 120, 47, -53, 36, 20, -90, 110, 61, -93, 55, -10, 85, 45, 52, 79, 87, 100, -81, -85, 34, 55, -91, 27, 116, -18, -71, -11, 87, -11, 76, 48, 97, -78, 64, -100, -59, -12, 19, -90, 121, 48, -19, 64, 113, -70, -14, -70, 92, 124, 42, 95, 7, -115, 36, 127, 73, 33, 30, 121, 88, 16, -90, 99, 120, -68, 64, -125, -78, 76, 112, 68, 8, 105, 10, -47, -124, 39, -107, -101, 46, -61, 118, -74, 102, -62, -6, -128, 17, -45, 61, 76, 63, -10, -41, 50, -113, 75, -83, -59, -51, -23, -61, 47, 7, -80, 126, -2, 79, -53, 110, -93, -38, -91, -22, 20, -84, -113, -124, -73, 124, 0, 33, -58, 63, -26, 52, 7, 74, 65, 38, -33, 21, -9, -1, 120, -16, 47, -96, 59, -64, 74, 6, 48, -67, -32, -26, 35, 68, 47, 82, 36, 52, 41, 112, -28, -22, -51, -6, -49, 105, 16, -34, 99, -41, 75, 7, 79, -22, -125, -30, -126, 35, 119, -43, -30, 32, 8, 44, -42, -98, 78, -92, -95, -10, -94, -1, -91, -122, 77, 0, 40, -23, 36, 85, 123, -57, -74, -69, -90, 89, 111, -120, 22, 5, -48, 114, 59, 31, 31, -25, -3, 24, 110, -110, 73, -40, 92, -26, -12, 52, 83, -98, -119, -6, -117, -89, 95, 83, -25, 122, -26, 114, 81, 25, 110, 79, -49, -39, 10, -78, -65, 57, -90, -46, -126, 15, -124, -104, -89, -66, -87, 24, -45, 39, -34, -40, -13, 106, 12, -25, -116, -47, 79, -81, 64, -17, -31, -70, 87, 36, 46, 102, 107, 48, 88, 34, 46, 24, 63, -100, 106, 27, 58, -71, 38, 60, -66, 45, -89, 39, -60, -116, -14, -119, 118, 0, -24, -9, 38, -71, -79, 124, -119, -64, -9, 71, -56, -82, -73, -69, 127, -1, -20, 123, 32, -43, 49, 5, 49, 105, -5, -2, 5, -105, -111, 89, -30, -41, -49, 61, 80, 69, 44, -33, -116, -45, -96, 63, 28, -17, -106, -94, 90, -40, -88, 122, 116, 116, 113, -65, 104, 119, -3, 96, -45, 18, -120, -111, 83, 43, -5, 101, 71, 48, 104, -112, -95, -46, 53, -96, -93, -126, 96, 56, 104, -111, 114, -1, -44, -120, -112, -19, 100, 41, -122, 23, -78, 33, -35, 11, 57, -18, 106, -40, 74, 61, 66, 54, -77, 96, 70, 108, -128, 91, -97, -36, -23, -86, -91, 44, 58, 117, 2, 26, 44, 95, 79, -101, -81, -92, 110, -81, -12, -88, -21, -83, 60, 93, -121, -114, -48, -34, -119, -1, 127, -121, 54, -128, -106, -39, -108, 81, 17, -3, -13, -57, 74, 41, -122, -65, -107, -118, -65, -61, 103, -69, 19};
-
- byte[] fullBytes = new byte[pubBytes.length + privBytes.length];
-
- System.arraycopy(pubBytes, 0, fullBytes, 0, pubBytes.length);
- System.arraycopy(privBytes, 0, fullBytes, pubBytes.length, privBytes.length);
-
- NTRUEncryptionPrivateKeyParameters priv = new NTRUEncryptionPrivateKeyParameters(fullBytes, params.getEncryptionParameters());
- NTRUEncryptionPublicKeyParameters pub = new NTRUEncryptionPublicKeyParameters(pubBytes, params.getEncryptionParameters());
- AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(pub, priv);
-
- ntru.init(true, kp.getPublic());
-
- byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length);
-
- ntru.init(false, kp.getPrivate());
-
- byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length);
- assertTrue(Arrays.areEqual(plainText, decrypted));
-
- // sparse polynomials
- params = NTRUEncryptionKeyGenerationParameters.EES1499EP1;
- ntru = new NTRUEngine();
- privBytes = new byte[] {116, 7, 118, 121, 6, 77, -36, 60, 65, 108, 10, -106, 12, 9, -22, -113, 122, -31, -31, 18, 120, 81, -33, 5, 122, -76, 109, -30, -101, -45, 21, 13, -11, -49, -111, 46, 91, 4, -28, -109, 121, -119, -121, -58, -113, -9, -10, -25, -53, 40, -86, -22, -50, 42, 52, 107, 119, 17, 33, 125, -26, 33, 55, 25, -77, -65, -106, 116, -67, 91, 105, -7, 42, -107, -54, 101, 12, -12, 57, -116, 45, -107, -17, 110, 35, -64, 19, -38, -122, 115, -93, 53, 69, 66, -106, 17, 20, -71, 121, 23, -21, -45, 108, 97, 23, -98, -12, -41, -31, -53, 30, -42, 15, 85, -21, -89, 118, 42, -117, -39, 69, 0, -63, 83, 48, -80, -14, -123, -4, -116, -90, -107, -89, 119, 29, -30, 69, 22, -84, 47, 117, -123, 102, -116, 35, 93, -13, 84, -9, -122, 58, 101, 93, -106, -119, -35, -75, 76, 27, -125, -22, 68, 101, 49, 103, -13, -98, 93, -56, -110, -19, -12, 74, 104, 7, 6, -11, 47, 57, 90, 75, -30, 47, 66, -58, 14, 14, 70, 11, -119, -36, -118, -55, -53, 101, -73, -77, 33, -29, 96, -86, 38, 47, 103, 19, -37, -17, -50, -82, -87, -119, 37, -54, 77, -69, -16, -48, -52, 110, -26, 111, 35, 26, -53, -10, 9, -108, -34, 102, 7, -18, -72, -26, 24, -50, -43, 92, 56, -94, 23, -36, 60, 28, -121, 27, 127, -93, -79, -45, -60, 105, -6, -88, 72, -41, 47, -51, 3, 91, 116, 75, 122, -94, -113, 28, -96, -62, -29, -74, -85, -93, 51, 58, 72, 44, 9, 18, -48, -24, 73, 122, 60, -23, 83, -110, -7, -111, -69, 106, 51, 118, -83, -18, 109, -32, 40, 22};
-
- pubBytes = new byte[] {-62, 56, 59, -46, 30, -19, 22, -115, -20, 117, -14, 3, 2, -57, 85, -24, 27, 57, 49, -93, -52, 87, 49, 96, 15, 95, -95, -86, -61, 50, -18, 3, 109, -55, -110, -57, 82, 124, -5, -57, 68, -18, 126, 114, 6, -22, 8, 121, 125, 29, -16, 112, -81, 27, -7, 109, -44, -123, -15, -14, 74, -126, 95, -94, -91, 119, 80, -48, 41, 49, 6, 104, 93, -97, -108, -82, 93, 70, -127, -113, -22, -103, 35, -115, 20, -115, 63, 57, -84, -18, -107, 81, 44, -16, 83, 71, -27, -2, -125, 87, 26, 100, -116, 110, 94, -46, -56, -82, 119, -110, -127, -99, -8, -118, 90, 64, -29, 102, 99, 92, 86, -117, 26, -89, 32, 17, 55, -65, -10, -5, -74, 19, 13, 113, -15, -103, 17, 10, -127, -95, -79, 19, 11, -24, 59, 28, -70, -55, -69, -105, -20, -117, 66, 4, 77, 116, -124, -62, 19, 109, 49, -120, 10, -15, 108, 84, 126, 122, -46, -37, 114, -78, -72, 34, -12, 25, -104, -3, 114, -94, 16, 31, 31, -124, -109, -64, 57, -47, -113, -26, 97, -58, 112, -40, 49, 80, -54, -115, -98, -60, -123, 91, 14, 75, -86, 77, -93, 68, 112, 82, 79, 28, -25, 49, -27, -112, 103, 60, -128, 95, -63, 2, -51, 2, -107, 80, 113, 18, 123, 24, 70, 77, -56, -48, 33, 89, 88, 29, 112, -102, -15, 52, -96, 17, -9, 6, -11, -119, 29, -107, -84, -19, 84, 124, 19, 90, -60, -41, 123, -81, 96, -119, 17, -61, 62, 55, 95, -73, -13, -60, 56, 77, 24, -39, -107, -78, 47, -91, 88, 90, 34, 112, -80, 83, -58, 127, 76, -97, -40, 78, -20, -1, -62, 19, 6, -43, -46, -36, -53, -22, -28, -119, 8, 19, 79, -9, -54, -126, -3, -20, -110, -82, 51, 3, 1, -123, -41, -40, -11, 91, -52, 48, 104, -11, -2, 49, 45, 52, -33, 109, -44, -30, -44, -83, -108, -10, 77, 106, 82, 3, 14, -48, -18, -79, -64, -34, -63, -18, 122, 33, 25, 44, 82, -112, 111, 68, 97, -58, -38, 25, 62, 78, 97, -36, 57, -19, 122, -18, -74, 67, -127, -24, 32, -45, 67, -106, 90, 0, 1, 91, 30, -80, 95, 9, 78, -4, -14, 16, 111, -56, -102, -90, 52, -1, 116, 19, -127, -23, -87, 103, -94, -111, 118, 53, -69, 77, 17, -3, 31, -53, -21, -78, 124, -88, 52, 117, 34, -52, -77, -107, -38, -102, 23, 73, -76, -88, 95, 64, -85, 12, 36, -86, 86, -17, 77, 121, 90, 24, -49, -107, 33, -116, 65, 13, 91, 118, -107, -21, 65, -59, 18, 125, 61, -65, -68, -19, 23, 88, 60, -6, 78, -8, 69, -62, -118, -93, 97, -64, -67, 28, 28, -87, -97, 72, -125, -119, 4, -43, 7, 22, -15, 52, 52, -82, -5, -51, 99, 20, -59, -2, -54, -67, 40, -128, -20, -37, 50, 123, 32, 8, -39, -105, 93, 73, 77, 84, 43, 89, 88, -6, 7, -108, 81, 27, 1, 50, 16, -101, 67, 95, 119, 105, 70, 99, -127, 22, 127, -33, -19, -113, -55, -100, 122, -86, 98, 53, 27, -95, 4, -121, -96, 87, 67, -98, -37, -10, 92, 29, -3, -115, -23, 37, 8, -30, 99, -117, 62, 101, 83, 49, 60, -83, -47, -33, 41, -118, 76, -7, 111, -15, 123, -59, 53, 2, -20, -57, 24, 57, 62, 84, -26, -11, 93, -118, 54, -13, 56, 77, -66, 18, -62, -76, 80, 98, 26, 120, -93, 55, 103, -1, 78, -92, 120, -23, -60, -75, 11, 53, -62, -94, -80, 120, 113, 33, -24, -64, -5, 23, 120, -14, 61, 26, -1, 56, 79, 34, 116, -16, -95, -71, 40, -89, -50, 71, -117, -109, 2, -2, -34, 94, -78, -88, -27, 70, 94, -86, 123, -49, 107, -65, -67, 84, 90, 123, -61, -2, 43, -119, -93, 75, -4, -81, 98, -36, 125, -23, -37, 81, 104, 90, -63, -52, 88, -96, -44, 25, 3, -37, -123, -48, 113, -76, -94, -109, -115, 37, -39, 104, -124, 82, -73, 100, 48, -54, -40, -65, 81, 16, -85, -41, 60, 42, 117, 65, 77, 14, -8, -56, 52, -118, -109, 125, 13, 64, -20, 125, -37, -74, -28, 118, 112, -126, 18, -101, 11, 75, 30, -4, -121, -13, -65, -13, -122, -53, -52, 20, -2, 67, 18, -106, 67, 83, -111, 15, 106, 10, 113, 53, -112, -3, 118, 8, -56, 40, 53, 23, -123, 96, 87, -118, -97, -116, -47, 85, -73, -85, -82, 124, -55, 55, 61, 46, 12, -6, 34, 22, -22, 3, 115, -49, 102, 23, 46, 39, 0, 118, 3, -45, 48, -73, -38, 29, -36, 11, -127, -86, 30, 29, -2, -108, -114, 64, 110, 86, -46, -91, -64, 95, -40, -65, 49, -79, -126, -37, -103, -71, 53, -85, 45, -51, 33, -28, -126, 36, -77, -120, 55, -54, 72, -21, 58, -87, -73, 18, -12, 20, -100, 30, 118, -83, -22, -90, 71, -64, 108, 101, -46, 36, 105, -46, -91, 60, -113, 72, 100, 82, -90, 106, -127, 65, -94, 17, 77, -10, -112, 46, 118, 72, -84, 57, -86, -114, 88, 91, 79, 30, 107, -35, 61, 81, 71, 40, -29, -6, -107, 61, -62, -6, 65, -68, 118, 61, 110, -115, -119, -73, 104, 59, -66, -89, -127, -8, -67, 122, -38, 79, -13, 93, 1, -32, -47, -3, 62, 88, -112, 105, 73, 96, 73, -104, -126, -69, 21, -22, 16, -85, 116, 9, 82, 54, -15, -55, -67, 68, -23, 16, -89, 48, -17, -107, 60, -43, -34, 66, -114, 63, -3, -26, 68, 68, -86, 120, -111, 99, 61, 101, 27, 93, 31, 90, -33, -94, 29, -89, 41, -80, 26, -23, -80, 27, 107, 69, -45, -123, 62, 63, 80, 1, -28, 52, -8, 35, -86, -127, 76, 102, 83, -104, -79, -98, 77, -28, 118, 18, -15, -98, -39, 2, -58, 95, 64, 105, -82, -7, 96, 110, 104, 127, 126, -124, 26, 36, 33, -42, 59, 82, 127, 42, -24, -61, -50, -18, -87, 22, -32, -125, -70, 103, -121, -112, -94, 58, -95, -97, 53, 95, -61, -83, 42, 37, 80, 51, -118, 125, 15, 67, 41, -97, 41, -121, 29, -88, 100, -113, 39, 101, 47, 91, -36, 48, -56, -13, 12, 37, 0, 81, 3, -40, 8, 36, -65, -11, -32, 108, 62, 79, 70, 91, -83, 2, -47, 0, 91, 10, 87, -19, -40, 96, 106, 41, 120, -53, 40, -114, 90, 64, 59, -115, 39, 2, 53, -49, -72, -114, 94, 5, 49, 74, 13, 50, -14, 76, -123, -11, -81, 100, 120, 16, -41, -72, -118, 28, 41, 98, 122, 27, 18, -108, -43, 51, -71, 93, -13, -42, -64, -118, -106, 45, 108, 72, -128, 58, -123, -29, -114, 15, 52, -72, 108, -62, 75, -15, 105, -89, 25, 37, 13, -21, -109, 68, 5, -89, 69, 10, -46, 18, -57, 77, -103, -74, 57, -43, -110, 1, -80, 82, 5, -9, -49, -53, 83, 4, 44, 64, -117, -67, -11, 1, -65, -81, 34, -23, -71, 14, 105, -93, 2, -120, 90, 92, -6, -128, -16, -51, 27, 123, 71, -117, -72, -81, 26, 28, 5, -117, -30, 22, -72, -76, -32, -14, 82, 90, 69, 74, -94, -72, -30, -17, 12, -37, -3, -80, 72, 2, -40, 41, 0, -53, 48, -37, -117, -128, -120, -80, 28, 49, -52, 114, -119, 92, -42, -105, 125, -95, 78, 76, 123, -56, 32, -66, 69, -58, 57, -77, -100, -70, 125, 53, -115, 8, 116, 88, -34, 86, -75, 55, 64, 79, -113, -124, -91, 50, -82, -119, 50, 11, 87, -14, -25, 15, -1, -49, -127, -5, -50, 72, -29, -78, 101, -119, -21, -15, 97, -63, 57, -123, -94, -24, -8, 104, 86, 79, 49, 102, -8, -76, 8, 69, 99, -64, -108, 70, 36, 71, -127, 56, 39, 78, 109, 42, -42, -2, 126, 17, -88, -65, -23, -64, 78, 87, 7, 6, -82, -98, 41, -46, -10, -25, 90, -73, 24, 127, -27, 118, -9, 81, -3, 115, -4, 47, 86, -30, -9, -50, 32, 86, 114, 58, -5, 78, 74, 36, 29, -126, 116, 117, -114, -92, -121, -36, -86, -18, 55, 49, 112, 43, 111, -99, -116, 70, 60, -63, 87, -4, -35, 15, 28, -27, -65, 66, 115, -33, 112, 94, 74, -22, 104, -56, -27, 39, -8, -53, -120, 8, -109, 73, -68, 67, 40, -59, 59, 121, -76, -41, -80, -54, -88, -120, -121, -118, -58, 74, -120, 82, -88, -113, 30, -8, 54, -126, -106, 37, -43, -74, -56, 40, -76, 93, 91, 28, -59, -30, -2, 107, 6, -89, -69, -121, -125, -109, 5, -94, -7, -2, -5, -67, 54, -90, 39, 5, -80, 93, -99, 82, -100, -128, -8, -39, -109, 66, -11, 99, -41, 18, -32, -122, 69, 6, -95, -21, 9, 19, -117, -34, -42, 11, 20, 84, 89, 91, -61, -13, -7, 55, 90, -15, 62, 59, -4, 125, -127, -24, -124, -99, -63, -23, 52, 111, -52, -60, -113, -65, -26, 127, 57, 21, 102, 101, -77, 66, -116, 117, 80, 7, 1, -96, -29, -99, 75, -73, 44, -99, 61, -73, 15, -18, 89, 95, 104, -12, 94, 33, 13, -49, 118, -84, -122, -2, -121, 62, -32, -80, 11, -10, 102, -67, 20, -3, 25, -6, 51, -17, -123, -76, 103, 3, 127, -107, -5, 122, 65, 22, 113, 120, 6, -19, -110, 86, 55, -88, -124, 0, -54, 17, 112, 15, 105, -28, 111, -93, 85, -59, -88, 28, 123, 55, 117, 10, 76, 54, -98, 116, 40, -65, -53, -80, 46, 66, -8, -114, 102, 66, 67, -117, 46, 21, -116, -38, 58, -105, 101, 37, -16, 5, 55, -33, -87, 72, 122, -114, -91, 41, -114, 77, 50, 109, 35, -61, 9, -55, -118, 126, -35, -108, 5, 62, 125, -109, -115, -55, 32, -71, 69, 110, 87, -82, 119, 26, 103, -77, -38, -13, 113, 74, 69, 116, 94, -21, 5, 35, 73, -80, -87, 80, 13, 108, 1, 82, -56, -35, -21, -78, -98, 121, 112, -117, 72, 47, 76, -97, -84, -110, -35, -19, -120, -13, 127, 5, 56, 72, -22, 110, -8, -71, 0, -57, -125, -101, 60, -64, -32, 1, 126, -109, 9, 84, 117, 62, -68, -106, 28, -118, -52, -81, 112, 11, 55, 68, -86, -65, 123, 83, 55, -72, 110, 63, -90, 31, 11, 90, -60, 20, 14, -36, 5, -92, 11, -100, 64, -57, -72, -105, 7, 103, 125, 99, -88, 32, -5, 41, -115, -11, 89, 81, 77, -33, -7, -123, -17, 109, 59, 40, -12, -61, 98, -91, 19, -36, 108, 118, -124, -82, -40, -124, -66, 19, 127, -73, -39, 99, 43, -16, -44, -83, -77, -34, 68, -118, -71, -116, 114, 120, -34, -105, -32, -46, 102, 73, -79, 7, 42, 35, -66, 125, 34, 113, 66, 78, 71, 6, 44, -17, 4, -80, 38, -59, 12, -8, -78, 103, 8, 80, 18, -74, 20, 3, 56, -20, 106, -1, -12, 83, 4, 68, -119, 84, -87, 97, -53, 102, 119, 34, -85, 22, -26, 55, -107, 96, -70, 77, -68, -96, -15, -22, -77, -55, 5, 103, -42, -87, 122, -80, -103, -37, -120, -56, -16, -51, -7, -19, -104, 120, 9, 54, -85, 48, -76, -38, 58, -68, 116, -20, -44, 22, -32, 75, -46, -41, 13, -100, 16, -59, -93, -115, 54, 22, -110, -46, -119, 44, -98, -48, 4, -58, -115, -57, 103, -56, 36, -63, 104, -114, -125, 92, 65, 117, -21, -59, -31, 56, -98, -126, 56, 47, -116, 100, 122, -98, 4, 26, -29, -127, -113, 73, 48, 106, 125, -69, -127, 62, 56, -79, 76, 84, -46, -31, -17, 94, -98, 62, 63, 118, -24, 63, 123, -93, -46, 103, 117, -120, -35, 19, 25, 15, -110, -125, 12, -75, -50, 103, 49, 47, 98, 92, 10, -88, 54, -53, 19, 25, -90, 93, -49, 64, 126, -106, -30, -52, 58, 37, 68, -18, -60, 15, -27, 93, -124, 88, 110, -80, -106, 88, 55, 108, -58, -43, -70, 76, 85, 98, 27, -66, 18, 75, 69, 114, 90, -26, -10, -12, -126, 84, -109, 108, 15, -115, 90, 11, -127, 63, -7, 47, 92, -72, 38, -58, -35, 18, 25, 12, -103, 0};
-
- fullBytes = new byte[pubBytes.length + privBytes.length];
-
- System.arraycopy(pubBytes, 0, fullBytes, 0, pubBytes.length);
- System.arraycopy(privBytes, 0, fullBytes, pubBytes.length, privBytes.length);
-
- priv = new NTRUEncryptionPrivateKeyParameters(fullBytes, params.getEncryptionParameters());
- pub = new NTRUEncryptionPublicKeyParameters(pubBytes, params.getEncryptionParameters());
- kp = new AsymmetricCipherKeyPair(pub, priv);
- ntru.init(true, kp.getPublic());
-
- encrypted = ntru.processBlock(plainText, 0, plainText.length);
-
- ntru.init(false, kp.getPrivate());
-
- decrypted = ntru.processBlock(encrypted, 0, encrypted.length);
-
- assertTrue(Arrays.areEqual(plainText, decrypted));
- }
-
- // encrypts and decrypts text using an encoded key pair (fastFp=true)
- public void testEncodedKeysFast()
- throws IOException, InvalidCipherTextException
- {
- byte[] plainText = "secret encrypted text".getBytes();
-
- NTRUEncryptionKeyGenerationParameters params = NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST;
- NTRUEngine ntru = new NTRUEngine();
- byte[] privBytes = {10, 16, 2, 30, -40, -63, -109, -77, -72, -122, 66, 23, -30, -44, -82, 0, 95, 64, 68, 48, -62, -14, 26, -19, -72, -25, 72, 123, 98, 84, -83, 0, 7, 40, 65, 35, 68, 113, 12, -112, 32, -123, 58, 85, -30, -109, -74, 0, 34, -8, -126, 57, 30, 98, -107, -45, -88, 102, 68, 42, -30, -108, -89, 0, 38, -40, -61, 37, 82, 113, -115, 123, -100, 5, 46, 125, -23, 78, -111, -76, 36, -90, 67, -31, 10, 2, 96, -127, 21, 50, -79, 13, -125, -124, 38, 55, -67, -95, 81, -107, 12, 117, -86, 99, -127, 11};
- byte[] pubBytes = {108, -76, -104, -75, -87, -65, -18, -5, 45, -57, -100, -83, 51, 99, 94, 15, -73, 89, -100, 40, -114, 91, -107, 104, 127, 22, 13, 5, -16, 69, -104, -126, -44, 119, 47, -48, 75, 66, 83, -37, -66, -84, 73, 52, 23, -27, 53, 63, 56, 14, -2, 43, -59, -85, -80, 46, 38, -126, 75, -8, -63, 88, 104, 13, 72, -25, -10, -58, -51, 117, -84, 115, -24, -53, 83, -103, -97, 46, 90, -82, -61, 113, -49, -24, -72, 24, -124, -42, -36, 7, 41, 8, 14, -71, -75, -84, -24, -39, 56, 67, 88, 67, 66, -13, 70, -119, -64, 74, -100, -58, 35, 105, -20, 93, 80, -116, -55, 37, -52, 64, 0, -36, -71, 8, 77, -10, -41, -22, -73, 4, -115, -74, -74, -73, 23, -10, -26, 48, 125, -114, -32, -116, 74, 19, -104, 59, 43, 4, 97, -84, 112, 45, 16, 3, -110, -13, 119, -6, 29, -80, 109, 82, -31, 82, 30, 76, -111, -122, -50, -69, -41, -123, 107, 78, -35, 24, -121, -87, -108, 13, 70, 32, -74, 112, 104, -40, -61, 86, -125, 60, -94, -5, -18, 55, 54, -128, 83, -88, 71, 71, -66, 29, -113, 120, 30, 16, -38, 37, 96, -90, 38, -85, 88, 59, 15, -69, 6, -8, 1, 1, 71, 12, 60, -26, -110, 97, 77, 33, 58, 63, 104, 108, 83, 72, -21, -99, 115, -125, -16, 12, 99, 68, 39, -97, -6, 17, 26, -59, 123, -110, -37, -71, 47, 50, 5, 110, -34, 89, -74, 20, 79, -108, -7, 42, 106, -112, 44, 107, 106, -50, 55, 127, -124, 53, 123, -119, -46, -114, -52, -85, 75, 34, -39, -125, 58, -5, -31, -81, -37, -94, -123, 113, 11, -104, -124, 96, -103, 9, 108, 115, 97, -6, 98, -43, 26, -89, -23, 83, 60, 34, -86, -54, 107, 78, -48, 118, -31, -19, 29, -106, 108, 117, 83, 119, 51, -45, 115, 108, -13, -89, -29, 29, -120, 108, 20, 22, -3, 22, 78, -109, 95, 3, -68, -10, -53, -117, -96, -49, 9, 7, 38, 116, 33, -65, 31, 9, -5, -73, 127, 52, 113, 87, -39, 119, -96, 74, -105, 75, -89, 63, 69, -109, -127, 92, -54, 17, -98, -23, -69, 123, -125, 23, -93, 44, -11, -25, -101, 120, -29, 113, -33, 0, -117, -100, -114, 22, 41, -46, 29, -109, 107, 37, -94, 125, 46, 17, 16, -65, -14, 105, -118, 51, -21, 121, -5, 56, 29, 30, -69, -38, -10, -77, -74, 6, -105, 83, 110, 23, 114, -11, -123, -14, 30, -11, -9, 84, -90, -20, -29, 72, -85, 97, -74, -59, -112, -15, -51, -105, 117, 123, -17, -64, -127, 127, -33, -102, 88, 77, 122, -127, -15, 121, -125, -32, 53, 113, 45, -22, 84, -87, 20, 36, 65, 83, -84, -66, -22, 4, 15, -108, -92, 109, -128, -48, 4, -27, -13, 25, 51, -10, 34, 87, 88, 38, -87, 89, -64, -62, 20, 78, 35, -26, -2, 55, 3, -72, -64, 30, 28, -105, 6, -37, -38, -8, 26, -118, 105, -37, -30, 85, -66, 105, -46, -37, -11, -72, 71, 43, -65, -44, 17, -79, 98, 79, -77, -111, 95, 74, 101, -40, -106, 14, -108, -112, 86, 108, 49, 72, -38, -103, -31, 65, -119, 8, 78, -89, 100, -28, 116, 94, 15, -18, 108, 101, 85, 8, -6, 111, -82, -49, -66, -89, 28, -84, -85, -119, 111, 45, 83, -60, -40, -45, -101, -105, -35, 123, -1, 13, -112, 79, -80, -85, -109, -71, 69, 104, 95, -93, 121, -17, 83, 117, -73, -63, -65, -107, -72, 118, -102, -56, 38, 79, 121, -25, -86, -81, -38, 8, 122, 97, 37, 82, -40, 53, 11, 124, -94, -76, -107, -125, -9, -119, 63, 52, -34, -72, -21, 59, 3, -100, -127, 47, -102, 19, -37, -45, -114, -65, 39, -106, 6, -127, -110, -38, 96, -38, -51, 110, -3, 28, 8, 102, -102, 96, -127, 109, -56, -53, -13, 59, -98, 92, 80, 1, 55, -91, -122, -105, 28, 69, -85, 109, -38, 105, 87, -5, 3, -102, 62, -92, 60, 43, -20, -7, -23, -84, 106, 121, -48, 123, -112, 56, -17, -52, 14, -123, -122, 64, 14, -23, -71, 60, 70, -121, 6, 37, -15, 77, 96, 104, -34, 58, -125, -61, 1, -26, 118, -78, -35, -1, 0, 5, 33, -98, -86, -127, 25, 56, -91, 82, -33, 60, -64, -86, 27, 31, -80, -79, 118, -12, -18, 40, -72, 32, 119, -28, -62, 100, -121, -71, -79, -9, 38, -37, 25, 65, -46, 8, -112, 37, 9, -56, 123, -40, -44, -90, -21, -54, -2, -7, 107, -93, 24, -126, 69, 42, -111, -84, 57, 69, -119, 21, 60, 57, -122, 111, -99, 49, -46, -119, 100, 98, 24, -62, 112, 122, 46, 18, -35, -67, 89, 104, 82, 12, 125, 57, -70, -112, -109, 96, 51, -68, 1, -101, -59, -92, 54, 85, -41, 17, 31, 94, 75, -128, 53, 84, 0, -83, -94, -123, 49, -30, -24, 18, 46, 48, -33, 120, 66, -69, 70, 23, -124, -117, 81, 96, 46, 47, -33, 83, -13, -14, -94, 49, 66, -46, 84, -27, -77, 6, 0, -75, -18, 86, -119, -88, 82, -50, 55, -20, 63, 55, -57, 22, -108, -103, -17, -22, 64, 65, 90, -34, -96, -117, 51, 119, -103, -35, 95, -15, -118, 2, -31, 31, -9, -58, 84, -75, 80, 39, -101, -56, 16, -75, 59, 48, -63, -24, -95, 119, 73, -110, -115, 49, -18, 54, -124, 112, -61, -40, -105, -118, -66, 15, -107, 75, 82, -70, -87, -11, -11, 48, 41, 119, -42, -34, -33, 57, 23, -14, -45, -125, -108, -75, 3, 44, 44, 58, 126, -126, -20, -123, 58, 114, 79, -102, -115, 115, 12, 66, 108, 84, 43, -46, -80, -41, -70, 111, -114, 123, 21, 1, 34, -72, 23, 105, -52, -39, -54, -119, 45, 77, -16, -66, -105, -11, 91, -46, 77, -104, -93, 52, -3, 17, 55, -10, 67, -33, 43, 75, -103, 106, 7, -35, -65, -21, 68, 118, -38, 59, -115, 31};
-
- byte[] fullBytes = new byte[pubBytes.length + privBytes.length];
-
- System.arraycopy(pubBytes, 0, fullBytes, 0, pubBytes.length);
- System.arraycopy(privBytes, 0, fullBytes, pubBytes.length, privBytes.length);
-
- NTRUEncryptionPrivateKeyParameters priv = new NTRUEncryptionPrivateKeyParameters(fullBytes, params.getEncryptionParameters());
- NTRUEncryptionPublicKeyParameters pub = new NTRUEncryptionPublicKeyParameters(pubBytes, params.getEncryptionParameters());
- AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(pub, priv);
-
- ntru.init(true, kp.getPublic());
-
- byte[] encrypted = ntru.processBlock(plainText, 0, plainText.length);
-
- assertEquals(encrypted.length, ntru.getOutputBlockSize());
-
- ntru.init(false, kp.getPrivate());
-
- byte[] decrypted = ntru.processBlock(encrypted, 0, encrypted.length);
-
- assertTrue(Arrays.areEqual(plainText, decrypted));
- }
-
- private class VisibleNTRUEngine
- extends NTRUEngine
- {
- public IntegerPolynomial encrypt(IntegerPolynomial m, TernaryPolynomial r, IntegerPolynomial pubKey)
- {
- return super.encrypt(m, r, pubKey);
- }
-
- public IntegerPolynomial decrypt(IntegerPolynomial e, Polynomial priv_t, IntegerPolynomial priv_fp)
- {
- return super.decrypt(e, priv_t, priv_fp);
- }
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUEncryptionParametersTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUEncryptionParametersTest.java
deleted file mode 100644
index 54f53ad..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUEncryptionParametersTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import junit.framework.TestCase;
-import org.bouncycastle.pqc.crypto.ntru.NTRUEncryptionKeyGenerationParameters;
-
-public class NTRUEncryptionParametersTest
- extends TestCase
-{
- public void testLoadSave()
- throws IOException
- {
- NTRUEncryptionKeyGenerationParameters params = NTRUEncryptionKeyGenerationParameters.EES1499EP1;
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- params.writeTo(os);
- ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
- assertEquals(params, new NTRUEncryptionKeyGenerationParameters(is));
- }
-
- public void testEqualsHashCode()
- throws IOException
- {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- NTRUEncryptionKeyGenerationParameters.EES1499EP1.writeTo(os);
- ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
- NTRUEncryptionKeyGenerationParameters params = new NTRUEncryptionKeyGenerationParameters(is);
-
- assertEquals(params, NTRUEncryptionKeyGenerationParameters.EES1499EP1);
- assertEquals(params.hashCode(), NTRUEncryptionKeyGenerationParameters.EES1499EP1.hashCode());
-
- params.N += 1;
- assertFalse(params.equals(NTRUEncryptionKeyGenerationParameters.EES1499EP1));
- assertFalse(NTRUEncryptionKeyGenerationParameters.EES1499EP1.equals(params));
- assertFalse(params.hashCode() == NTRUEncryptionKeyGenerationParameters.EES1499EP1.hashCode());
- }
-
- public void testClone()
- {
- NTRUEncryptionKeyGenerationParameters params = NTRUEncryptionKeyGenerationParameters.APR2011_439;
- assertEquals(params, params.clone());
-
- params = NTRUEncryptionKeyGenerationParameters.APR2011_439_FAST;
- assertEquals(params, params.clone());
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignatureKeyTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignatureKeyTest.java
deleted file mode 100644
index 509839a..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignatureKeyTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import junit.framework.TestCase;
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.pqc.crypto.ntru.NTRUSigner;
-import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyPairGenerator;
-import org.bouncycastle.pqc.crypto.ntru.NTRUSigningPrivateKeyParameters;
-import org.bouncycastle.pqc.crypto.ntru.NTRUSigningPublicKeyParameters;
-
-public class NTRUSignatureKeyTest
- extends TestCase
-{
- public void testEncode()
- throws IOException
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD})
- {
- testEncode(params);
- }
- }
-
- private void testEncode(NTRUSigningKeyGenerationParameters params)
- throws IOException
- {
- NTRUSigner ntru = new NTRUSigner(params.getSigningParameters());
- NTRUSigningKeyPairGenerator kGen = new NTRUSigningKeyPairGenerator();
-
- kGen.init(params);
-
- AsymmetricCipherKeyPair kp = kGen.generateKeyPair();
-
- NTRUSigningPrivateKeyParameters kPriv = (NTRUSigningPrivateKeyParameters)kp.getPrivate();
- NTRUSigningPublicKeyParameters kPub = (NTRUSigningPublicKeyParameters)kp.getPublic();
-
- // encode to byte[] and reconstruct
- byte[] priv = kPriv.getEncoded();
- byte[] pub = kPub.getEncoded();
- AsymmetricCipherKeyPair kp2 = new AsymmetricCipherKeyPair(new NTRUSigningPublicKeyParameters(pub, params.getSigningParameters()), new NTRUSigningPrivateKeyParameters(priv, params));
- assertEquals(kPub, kp2.getPublic());
- assertEquals(kPriv, kp2.getPrivate());
-
- // encode to OutputStream and reconstruct
- ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
- ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
- kPriv.writeTo(bos1);
- kPub.writeTo(bos2);
- ByteArrayInputStream bis1 = new ByteArrayInputStream(bos1.toByteArray());
- ByteArrayInputStream bis2 = new ByteArrayInputStream(bos2.toByteArray());
- AsymmetricCipherKeyPair kp3 = new AsymmetricCipherKeyPair(new NTRUSigningPublicKeyParameters(bis2, params.getSigningParameters()), new NTRUSigningPrivateKeyParameters(bis1, params));
- assertEquals(kPub, kp3.getPublic());
- assertEquals(kPriv, kp3.getPrivate());
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignatureParametersTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignatureParametersTest.java
deleted file mode 100644
index 4c5751e..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignatureParametersTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import junit.framework.TestCase;
-import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyGenerationParameters;
-
-public class NTRUSignatureParametersTest
- extends TestCase
-{
- public void testLoadSave()
- throws IOException
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD, NTRUSigningKeyGenerationParameters.APR2011_743, NTRUSigningKeyGenerationParameters.APR2011_743_PROD})
- {
- testLoadSave(params);
- }
- }
-
- private void testLoadSave(NTRUSigningKeyGenerationParameters params)
- throws IOException
- {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- params.writeTo(os);
- ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
- assertEquals(params, new NTRUSigningKeyGenerationParameters(is));
- }
-
- public void testEqualsHashCode()
- throws IOException
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD, NTRUSigningKeyGenerationParameters.APR2011_743, NTRUSigningKeyGenerationParameters.APR2011_743_PROD})
- {
- testEqualsHashCode(params);
- }
- }
-
- private void testEqualsHashCode(NTRUSigningKeyGenerationParameters params)
- throws IOException
- {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- params.writeTo(os);
- ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
- NTRUSigningKeyGenerationParameters params2 = new NTRUSigningKeyGenerationParameters(is);
-
- assertEquals(params, params2);
- assertEquals(params.hashCode(), params2.hashCode());
-
- params.N += 1;
- assertFalse(params.equals(params2));
- assertFalse(params.equals(params2));
- assertFalse(params.hashCode() == params2.hashCode());
- }
-
- public void testClone()
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD, NTRUSigningKeyGenerationParameters.APR2011_743, NTRUSigningKeyGenerationParameters.APR2011_743_PROD})
- {
- assertEquals(params, params.clone());
- }
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignerTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignerTest.java
deleted file mode 100644
index 3a765af..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSignerTest.java
+++ /dev/null
@@ -1,317 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-
-import junit.framework.TestCase;
-
-/**
- * @deprecated algorithm no longer safe.
- */
-public class NTRUSignerTest
- extends TestCase
-{
- public void testStub()
- {
-
- }
- /*
- public void testCreateBasis()
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157.clone(), NTRUSigningKeyGenerationParameters.TEST157_PROD.clone()})
- {
- testCreateBasis(params);
- }
- }
-
- private void testCreateBasis(NTRUSigningKeyGenerationParameters params)
- {
- NTRUSigningKeyPairGenerator ntru = new NTRUSigningKeyPairGenerator();
-
- ntru.init(params);
-
- NTRUSigningKeyPairGenerator.FGBasis basis = (NTRUSigningKeyPairGenerator.FGBasis)ntru.generateBoundedBasis();
- assertTrue(equalsQ(basis.f, basis.fPrime, basis.F, basis.G, params.q, params.N));
-
- // test KeyGenAlg.FLOAT (default=RESULTANT)
- params.keyGenAlg = NTRUSigningKeyGenerationParameters.KEY_GEN_ALG_FLOAT;
- ntru.init(params);
- basis = (NTRUSigningKeyPairGenerator.FGBasis)ntru.generateBoundedBasis();
- assertTrue(equalsQ(basis.f, basis.fPrime, basis.F, basis.G, params.q, params.N));
- }
-
- // verifies that f*G-g*F=q
- private boolean equalsQ(Polynomial f, Polynomial g, IntegerPolynomial F, IntegerPolynomial G, int q, int N)
- {
- IntegerPolynomial x = f.mult(G);
- x.sub(g.mult(F));
- boolean equalsQ = true;
- for (int i = 1; i < x.coeffs.length; i++)
- {
- equalsQ &= x.coeffs[i] == 0;
- }
- equalsQ &= x.coeffs[0] == q;
- return equalsQ;
- }
-
- /**
- * a test for the one-method-call variants: sign(byte, SignatureKeyPair) and verify(byte[], byte[], SignatureKeyPair)
- *
- public void testSignVerify157()
- throws IOException
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157.clone(), NTRUSigningKeyGenerationParameters.TEST157_PROD.clone(), NTRUSigningKeyGenerationParameters.APR2011_439.clone(), NTRUSigningKeyGenerationParameters.APR2011_439_PROD.clone(), NTRUSigningKeyGenerationParameters.APR2011_743.clone(), NTRUSigningKeyGenerationParameters.APR2011_743_PROD.clone()})
- {
- testSignVerify(params);
- }
- }
-
- public void testSignVerify439()
- throws IOException
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.APR2011_439.clone(), NTRUSigningKeyGenerationParameters.APR2011_439_PROD.clone()})
- {
- testSignVerify(params);
- }
- }
-//
-// public void testSignVerify743()
-// throws IOException
-// {
-// for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.APR2011_743.clone(), NTRUSigningKeyGenerationParameters.APR2011_743_PROD.clone()})
-// {
-// testSignVerify(params);
-// }
-// }
-
- private void testSignVerify(NTRUSigningKeyGenerationParameters params)
- throws IOException
- {
- NTRUSigner ntru = new NTRUSigner(params.getSigningParameters());
- NTRUSigningKeyPairGenerator kGen = new NTRUSigningKeyPairGenerator();
-
- kGen.init(params);
-
- AsymmetricCipherKeyPair kp = kGen.generateKeyPair();
-
- Random rng = new Random();
- byte[] msg = new byte[10 + rng.nextInt(1000)];
- rng.nextBytes(msg);
-
- // sign and verify
- ntru.init(true, kp.getPrivate());
-
- ntru.update(msg, 0, msg.length);
-
- byte[] s = ntru.generateSignature();
-
- ntru.init(false, kp.getPublic());
-
- ntru.update(msg, 0, msg.length);
-
- boolean valid = ntru.verifySignature(s);
-
- assertTrue(valid);
-
- // altering the signature should make it invalid
- s[rng.nextInt(params.N)] += 1;
- ntru.init(false, kp.getPublic());
-
- ntru.update(msg, 0, msg.length);
-
- valid = ntru.verifySignature(s);
- assertFalse(valid);
-
- // test that a random signature fails
- rng.nextBytes(s);
-
- ntru.init(false, kp.getPublic());
-
- ntru.update(msg, 0, msg.length);
-
- valid = ntru.verifySignature(s);
- assertFalse(valid);
-
- // encode, decode keypair, test
- NTRUSigningPrivateKeyParameters priv = new NTRUSigningPrivateKeyParameters(((NTRUSigningPrivateKeyParameters)kp.getPrivate()).getEncoded(), params);
- NTRUSigningPublicKeyParameters pub = new NTRUSigningPublicKeyParameters(((NTRUSigningPublicKeyParameters)kp.getPublic()).getEncoded(), params.getSigningParameters());
- kp = new AsymmetricCipherKeyPair(pub, priv);
-
- ntru.init(true, kp.getPrivate());
- ntru.update(msg, 0, msg.length);
-
- s = ntru.generateSignature();
-
- ntru.init(false, kp.getPublic());
- ntru.update(msg, 0, msg.length);
-
- valid = ntru.verifySignature(s);
- assertTrue(valid);
-
- // altering the signature should make it invalid
- s[rng.nextInt(s.length)] += 1;
- ntru.init(false, kp.getPublic());
- ntru.update(msg, 0, msg.length);
- valid = ntru.verifySignature(s);
- assertFalse(valid);
-
- // sparse/dense
- params.sparse = !params.sparse;
-
- ntru.init(true, kp.getPrivate());
- ntru.update(msg, 0, msg.length);
-
- s = ntru.generateSignature();
-
- ntru.init(false, kp.getPublic());
- ntru.update(msg, 0, msg.length);
- valid = ntru.verifySignature(s);
- assertTrue(valid);
-
- s[rng.nextInt(s.length)] += 1;
- ntru.init(false, kp.getPublic());
- ntru.update(msg, 0, msg.length);
- valid = ntru.verifySignature(s);
- assertFalse(valid);
- params.sparse = !params.sparse;
-
- // decrease NormBound to force multiple signing attempts
- NTRUSigningKeyGenerationParameters params2 = params.clone();
- params2.normBoundSq *= 4.0 / 9;
- params2.signFailTolerance = 10000;
- ntru = new NTRUSigner(params2.getSigningParameters());
-
- ntru.init(true, kp.getPrivate());
- ntru.update(msg, 0, msg.length);
-
- s = ntru.generateSignature();
-
- ntru.init(false, kp.getPublic());
- ntru.update(msg, 0, msg.length);
- valid = ntru.verifySignature(s);
-
- assertTrue(valid);
-
- // test KeyGenAlg.FLOAT (default=RESULTANT)
- params2 = params.clone();
- params.keyGenAlg = NTRUSigningKeyGenerationParameters.KEY_GEN_ALG_FLOAT;
- ntru = new NTRUSigner(params.getSigningParameters());
-
- kGen.init(params);
-
- kp = kGen.generateKeyPair();
- ntru.init(true, kp.getPrivate());
- ntru.update(msg, 0, msg.length);
-
- s = ntru.generateSignature();
- ntru.init(false, kp.getPublic());
- ntru.update(msg, 0, msg.length);
- valid = ntru.verifySignature(s);
- assertTrue(valid);
- s[rng.nextInt(s.length)] += 1;
- ntru.init(false, kp.getPublic());
- ntru.update(msg, 0, msg.length);
- valid = ntru.verifySignature(s);
- assertFalse(valid);
- }
-
- /**
- * test for the initSign/update/sign and initVerify/update/verify variant
- *
- public void testInitUpdateSign()
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157.clone(), NTRUSigningKeyGenerationParameters.TEST157_PROD.clone()})
- {
- testInitUpdateSign(params);
- }
- }
-
- private void testInitUpdateSign(NTRUSigningKeyGenerationParameters params)
- {
- NTRUSigner ntru = new NTRUSigner(params.getSigningParameters());
- NTRUSigningKeyPairGenerator kGen = new NTRUSigningKeyPairGenerator();
-
- kGen.init(params);
-
- AsymmetricCipherKeyPair kp = kGen.generateKeyPair();
-
- Random rng = new Random();
- byte[] msg = new byte[10 + rng.nextInt(1000)];
- rng.nextBytes(msg);
-
- // sign and verify a message in two pieces each
- ntru.init(true, kp.getPrivate());
- int splitIdx = rng.nextInt(msg.length);
- ntru.update(msg[0]); // first byte
- ntru.update(msg, 1, splitIdx - 1); // part 1 of msg
- ntru.update(msg, splitIdx, msg.length - splitIdx);
- byte[] s = ntru.generateSignature(); // part 2 of msg
- ntru.init(false, kp.getPublic());
- splitIdx = rng.nextInt(msg.length);
- ntru.update(msg, 0, splitIdx); // part 1 of msg
- ntru.update(msg, splitIdx, msg.length - splitIdx); // part 2 of msg
- boolean valid = ntru.verifySignature(s);
- assertTrue(valid);
- // verify the same signature with the one-step method
- ntru.init(false, (NTRUSigningPublicKeyParameters)kp.getPublic());
- ntru.update(msg, 0, msg.length); // part 1 of msg
- valid = ntru.verifySignature(s);
- assertTrue(valid);
-
- // sign using the one-step method and verify using the multi-step method
- ntru.init(true, kp.getPrivate());
- ntru.update(msg, 0, msg.length);
- s = ntru.generateSignature();
- ntru.init(false, (NTRUSigningPublicKeyParameters)kp.getPublic());
- splitIdx = rng.nextInt(msg.length);
- ntru.update(msg, 0, splitIdx); // part 1 of msg
- ntru.update(msg, splitIdx, msg.length - splitIdx); // part 2 of msg
- valid = ntru.verifySignature(s);
- assertTrue(valid);
- }
-
- public void testCreateMsgRep()
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157.clone(), NTRUSigningKeyGenerationParameters.TEST157_PROD.clone()})
- {
- testCreateMsgRep(params);
- }
- }
-
- private void testCreateMsgRep(NTRUSigningKeyGenerationParameters params)
- {
- VisibleNTRUSigner ntru = new VisibleNTRUSigner(params.getSigningParameters());
- byte[] msgHash = "adfsadfsdfs23234234".getBytes();
-
- // verify that the message representative is reproducible
- IntegerPolynomial i1 = ntru.createMsgRep(msgHash, 1);
- IntegerPolynomial i2 = ntru.createMsgRep(msgHash, 1);
- assertTrue(Arrays.areEqual(i1.coeffs, i2.coeffs));
- i1 = ntru.createMsgRep(msgHash, 5);
- i2 = ntru.createMsgRep(msgHash, 5);
- assertTrue(Arrays.areEqual(i1.coeffs, i2.coeffs));
-
- i1 = ntru.createMsgRep(msgHash, 2);
- i2 = ntru.createMsgRep(msgHash, 3);
- assertFalse(Arrays.areEqual(i1.coeffs, i2.coeffs));
- }
-
- private class VisibleNTRUSigner
- extends NTRUSigner
- {
-
- /**
- * Constructs a new instance with a set of signature parameters.
- *
- * @param params signature parameters
- *
- public VisibleNTRUSigner(NTRUSigningParameters params)
- {
- super(params);
- }
-
- public IntegerPolynomial createMsgRep(byte[] hash, int i)
- {
- return super.createMsgRep(hash, i);
- }
- }
- */
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSigningParametersTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSigningParametersTest.java
deleted file mode 100644
index 7cf7de8..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/NTRUSigningParametersTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import junit.framework.TestCase;
-import org.bouncycastle.pqc.crypto.ntru.NTRUSigningKeyGenerationParameters;
-
-public class NTRUSigningParametersTest
- extends TestCase
-{
-
- public void testLoadSave()
- throws IOException
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD})
- {
- testLoadSave(params);
- }
- }
-
- private void testLoadSave(NTRUSigningKeyGenerationParameters params)
- throws IOException
- {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- params.writeTo(os);
- ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
- assertEquals(params, new NTRUSigningKeyGenerationParameters(is));
- }
-
- public void testEqualsHashCode()
- throws IOException
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD})
- {
- testEqualsHashCode(params);
- }
- }
-
- private void testEqualsHashCode(NTRUSigningKeyGenerationParameters params)
- throws IOException
- {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- params.writeTo(os);
- ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
- NTRUSigningKeyGenerationParameters params2 = new NTRUSigningKeyGenerationParameters(is);
-
- assertEquals(params, params2);
- assertEquals(params.hashCode(), params2.hashCode());
-
- params.N += 1;
- assertFalse(params.equals(params2));
- assertFalse(params.equals(params2));
- assertFalse(params.hashCode() == params2.hashCode());
- }
-
- public void testClone()
- {
- for (NTRUSigningKeyGenerationParameters params : new NTRUSigningKeyGenerationParameters[]{NTRUSigningKeyGenerationParameters.TEST157, NTRUSigningKeyGenerationParameters.TEST157_PROD})
- {
- assertEquals(params, params.clone());
- }
- }
-} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/RainbowSignerTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/RainbowSignerTest.java
deleted file mode 100644
index ae6774b..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/RainbowSignerTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.digests.SHA224Digest;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.pqc.crypto.DigestingMessageSigner;
-import org.bouncycastle.pqc.crypto.rainbow.RainbowKeyGenerationParameters;
-import org.bouncycastle.pqc.crypto.rainbow.RainbowKeyPairGenerator;
-import org.bouncycastle.pqc.crypto.rainbow.RainbowParameters;
-import org.bouncycastle.pqc.crypto.rainbow.RainbowSigner;
-import org.bouncycastle.util.BigIntegers;
-import org.bouncycastle.util.encoders.Hex;
-import org.bouncycastle.util.test.FixedSecureRandom;
-import org.bouncycastle.util.test.SimpleTest;
-
-
-public class RainbowSignerTest
-extends SimpleTest
-{
- byte[] keyData = Hex.decode("b5014e4b60ef2ba8b6211b4062ba3224e0427dd3");
-
- SecureRandom keyRandom = new FixedSecureRandom(new byte[][] { keyData, keyData });
-
-
- public String getName()
- {
- return "Rainbow";
- }
-
- public void performTest()
- {
- RainbowParameters params = new RainbowParameters();
-
- RainbowKeyPairGenerator rainbowKeyGen = new RainbowKeyPairGenerator();
- RainbowKeyGenerationParameters genParam = new RainbowKeyGenerationParameters(keyRandom, params);
-
- rainbowKeyGen.init(genParam);
-
- AsymmetricCipherKeyPair pair = rainbowKeyGen.generateKeyPair();
-
- ParametersWithRandom param = new ParametersWithRandom(pair.getPrivate(), keyRandom);
-
- DigestingMessageSigner rainbowSigner = new DigestingMessageSigner(new RainbowSigner() , new SHA224Digest());
- rainbowSigner.init(true, param);
-
- byte[] message = BigIntegers.asUnsignedByteArray(new BigInteger("968236873715988614170569073515315707566766479517"));
- rainbowSigner.update(message, 0, message.length);
- byte[] sig = rainbowSigner.generateSignature();
-
- rainbowSigner.init(false, pair.getPublic());
- rainbowSigner.update(message, 0, message.length);
- if (!rainbowSigner.verify(sig))
- {
- fail("verification fails");
- }
- }
-
- public static void main(
- String[] args)
- {
- runTest(new RainbowSignerTest());
- }
-}
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/RegressionTest.java b/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/RegressionTest.java
deleted file mode 100644
index bc5a979..0000000
--- a/bcprov/src/main/java/org/bouncycastle/pqc/crypto/test/RegressionTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.bouncycastle.pqc.crypto.test;
-
-import org.bouncycastle.util.test.Test;
-import org.bouncycastle.util.test.TestResult;
-
-public class RegressionTest
-{
- public static Test[] tests = {
- new GMSSSignerTest(),
- new McElieceFujisakiCipherTest(),
- new McElieceKobaraImaiCipherTest(),
- new McEliecePKCSCipherTest(),
- new McEliecePointchevalCipherTest(),
- new RainbowSignerTest()
- };
-
- public static void main(
- String[] args)
- {
- for (int i = 0; i != tests.length; i++)
- {
- TestResult result = tests[i].perform();
-
- if (result.getException() != null)
- {
- result.getException().printStackTrace();
- }
-
- System.out.println(result);
- }
- }
-}
-