diff options
Diffstat (limited to 'libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/ntru/NTRUSigningKeyGenerationParameters.java')
-rw-r--r-- | libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/ntru/NTRUSigningKeyGenerationParameters.java | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/ntru/NTRUSigningKeyGenerationParameters.java b/libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/ntru/NTRUSigningKeyGenerationParameters.java new file mode 100644 index 000000000..2f6eaab55 --- /dev/null +++ b/libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/ntru/NTRUSigningKeyGenerationParameters.java @@ -0,0 +1,407 @@ +package org.spongycastle.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.spongycastle.crypto.Digest; +import org.spongycastle.crypto.KeyGenerationParameters; +import org.spongycastle.crypto.digests.SHA256Digest; +import org.spongycastle.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, 400, 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, 400, 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, 405, 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, 405, 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.spongycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.spongycastle.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.spongycastle.pqc.math.ntru.polynomial.SparseTernaryPolynomial} vs {@link org.spongycastle.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(); + } +} |