| 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(); |
| } |
| } |