diff options
Diffstat (limited to 'libraries/spongycastle/prov/src/main/java/org/spongycastle/pqc/jcajce/provider/rainbow/BCRainbowPrivateKey.java')
-rw-r--r-- | libraries/spongycastle/prov/src/main/java/org/spongycastle/pqc/jcajce/provider/rainbow/BCRainbowPrivateKey.java | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/libraries/spongycastle/prov/src/main/java/org/spongycastle/pqc/jcajce/provider/rainbow/BCRainbowPrivateKey.java b/libraries/spongycastle/prov/src/main/java/org/spongycastle/pqc/jcajce/provider/rainbow/BCRainbowPrivateKey.java new file mode 100644 index 000000000..114d20095 --- /dev/null +++ b/libraries/spongycastle/prov/src/main/java/org/spongycastle/pqc/jcajce/provider/rainbow/BCRainbowPrivateKey.java @@ -0,0 +1,243 @@ +package org.spongycastle.pqc.jcajce.provider.rainbow; + +import java.io.IOException; +import java.security.PrivateKey; +import java.util.Arrays; + +import org.spongycastle.asn1.DERNull; +import org.spongycastle.asn1.pkcs.PrivateKeyInfo; +import org.spongycastle.asn1.x509.AlgorithmIdentifier; +import org.spongycastle.pqc.asn1.PQCObjectIdentifiers; +import org.spongycastle.pqc.asn1.RainbowPrivateKey; +import org.spongycastle.pqc.crypto.rainbow.Layer; +import org.spongycastle.pqc.crypto.rainbow.RainbowPrivateKeyParameters; +import org.spongycastle.pqc.crypto.rainbow.util.RainbowUtil; +import org.spongycastle.pqc.jcajce.spec.RainbowPrivateKeySpec; + +/** + * The Private key in Rainbow consists of the linear affine maps L1, L2 and the + * map F, consisting of quadratic polynomials. In this implementation, we + * denote: L1 = A1*x + b1 L2 = A2*x + b2 + * <p/> + * The coefficients of the polynomials in F are stored in 3-dimensional arrays + * per layer. The indices of these arrays denote the polynomial, and the + * variables. + * <p/> + * More detailed information about the private key 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 BCRainbowPrivateKey + implements PrivateKey +{ + private static final long serialVersionUID = 1L; + + // the inverse of L1 + private short[][] A1inv; + + // translation vector element of L1 + private short[] b1; + + // the inverse of L2 + private short[][] A2inv; + + // translation vector of L2 + private short[] b2; + + /* + * components of F + */ + private Layer[] layers; + + // set of vinegar vars per layer. + private int[] vi; + + + /** + * Constructor. + * + * @param A1inv + * @param b1 + * @param A2inv + * @param b2 + * @param layers + */ + public BCRainbowPrivateKey(short[][] A1inv, short[] b1, short[][] A2inv, + short[] b2, int[] vi, Layer[] layers) + { + this.A1inv = A1inv; + this.b1 = b1; + this.A2inv = A2inv; + this.b2 = b2; + this.vi = vi; + this.layers = layers; + } + + /** + * Constructor (used by the {@link RainbowKeyFactorySpi}). + * + * @param keySpec a {@link RainbowPrivateKeySpec} + */ + public BCRainbowPrivateKey(RainbowPrivateKeySpec keySpec) + { + this(keySpec.getInvA1(), keySpec.getB1(), keySpec.getInvA2(), keySpec + .getB2(), keySpec.getVi(), keySpec.getLayers()); + } + + public BCRainbowPrivateKey( + RainbowPrivateKeyParameters params) + { + this(params.getInvA1(), params.getB1(), params.getInvA2(), params.getB2(), params.getVi(), params.getLayers()); + } + + /** + * 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 L1. + * + * @return b1 the translation part of L1 + */ + public short[] getB1() + { + return this.b1; + } + + /** + * 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; + } + + /** + * Compare this Rainbow private key with another object. + * + * @param other the other object + * @return the result of the comparison + */ + public boolean equals(Object other) + { + if (other == null || !(other instanceof BCRainbowPrivateKey)) + { + return false; + } + BCRainbowPrivateKey otherKey = (BCRainbowPrivateKey)other; + + boolean eq = true; + // compare using shortcut rule ( && instead of &) + eq = eq && RainbowUtil.equals(A1inv, otherKey.getInvA1()); + eq = eq && RainbowUtil.equals(A2inv, otherKey.getInvA2()); + eq = eq && RainbowUtil.equals(b1, otherKey.getB1()); + eq = eq && RainbowUtil.equals(b2, otherKey.getB2()); + eq = eq && Arrays.equals(vi, otherKey.getVi()); + if (layers.length != otherKey.getLayers().length) + { + return false; + } + for (int i = layers.length - 1; i >= 0; i--) + { + eq &= layers[i].equals(otherKey.getLayers()[i]); + } + return eq; + } + + public int hashCode() + { + int hash = layers.length; + + hash = hash * 37 + org.spongycastle.util.Arrays.hashCode(A1inv); + hash = hash * 37 + org.spongycastle.util.Arrays.hashCode(b1); + hash = hash * 37 + org.spongycastle.util.Arrays.hashCode(A2inv); + hash = hash * 37 + org.spongycastle.util.Arrays.hashCode(b2); + hash = hash * 37 + org.spongycastle.util.Arrays.hashCode(vi); + + for (int i = layers.length - 1; i >= 0; i--) + { + hash = hash * 37 + layers[i].hashCode(); + } + + + return hash; + } + + /** + * @return name of the algorithm - "Rainbow" + */ + public final String getAlgorithm() + { + return "Rainbow"; + } + + public byte[] getEncoded() + { + RainbowPrivateKey privateKey = new RainbowPrivateKey(A1inv, b1, A2inv, b2, vi, layers); + + PrivateKeyInfo pki; + try + { + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.rainbow, DERNull.INSTANCE); + pki = new PrivateKeyInfo(algorithmIdentifier, privateKey); + } + catch (IOException e) + { + e.printStackTrace(); + return null; + } + try + { + byte[] encoded = pki.getEncoded(); + return encoded; + } + catch (IOException e) + { + e.printStackTrace(); + return null; + } + } + + public String getFormat() + { + return "PKCS#8"; + } +} |