| package org.bouncycastle.pqc.asn1; |
| |
| import org.bouncycastle.asn1.ASN1EncodableVector; |
| import org.bouncycastle.asn1.ASN1Integer; |
| import org.bouncycastle.asn1.ASN1Object; |
| import org.bouncycastle.asn1.ASN1ObjectIdentifier; |
| import org.bouncycastle.asn1.ASN1OctetString; |
| import org.bouncycastle.asn1.ASN1Primitive; |
| import org.bouncycastle.asn1.ASN1Sequence; |
| import org.bouncycastle.asn1.DEROctetString; |
| import org.bouncycastle.asn1.DERSequence; |
| import org.bouncycastle.pqc.crypto.rainbow.util.RainbowUtil; |
| |
| /** |
| * This class implements an ASN.1 encoded Rainbow public key. The ASN.1 definition |
| * of this structure is: |
| * <pre> |
| * RainbowPublicKey ::= SEQUENCE { |
| * CHOICE |
| * { |
| * oid OBJECT IDENTIFIER -- OID identifying the algorithm |
| * version INTEGER -- 0 |
| * } |
| * docLength Integer -- length of the code |
| * coeffquadratic SEQUENCE OF OCTET STRING -- quadratic (mixed) coefficients |
| * coeffsingular SEQUENCE OF OCTET STRING -- singular coefficients |
| * coeffscalar SEQUENCE OF OCTET STRING -- scalar coefficients |
| * } |
| * </pre> |
| */ |
| public class RainbowPublicKey |
| extends ASN1Object |
| { |
| private ASN1Integer version; |
| private ASN1ObjectIdentifier oid; |
| private ASN1Integer docLength; |
| private byte[][] coeffQuadratic; |
| private byte[][] coeffSingular; |
| private byte[] coeffScalar; |
| |
| private RainbowPublicKey(ASN1Sequence seq) |
| { |
| // <oidString> or version |
| if (seq.getObjectAt(0) instanceof ASN1Integer) |
| { |
| version = ASN1Integer.getInstance(seq.getObjectAt(0)); |
| } |
| else |
| { |
| oid = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); |
| } |
| |
| docLength = ASN1Integer.getInstance(seq.getObjectAt(1)); |
| |
| ASN1Sequence asnCoeffQuad = ASN1Sequence.getInstance(seq.getObjectAt(2)); |
| coeffQuadratic = new byte[asnCoeffQuad.size()][]; |
| for (int quadSize = 0; quadSize < asnCoeffQuad.size(); quadSize++) |
| { |
| coeffQuadratic[quadSize] = ASN1OctetString.getInstance(asnCoeffQuad.getObjectAt(quadSize)).getOctets(); |
| } |
| |
| ASN1Sequence asnCoeffSing = (ASN1Sequence)seq.getObjectAt(3); |
| coeffSingular = new byte[asnCoeffSing.size()][]; |
| for (int singSize = 0; singSize < asnCoeffSing.size(); singSize++) |
| { |
| coeffSingular[singSize] = ASN1OctetString.getInstance(asnCoeffSing.getObjectAt(singSize)).getOctets(); |
| } |
| |
| ASN1Sequence asnCoeffScalar = (ASN1Sequence)seq.getObjectAt(4); |
| coeffScalar = ASN1OctetString.getInstance(asnCoeffScalar.getObjectAt(0)).getOctets(); |
| } |
| |
| public RainbowPublicKey(int docLength, short[][] coeffQuadratic, short[][] coeffSingular, short[] coeffScalar) |
| { |
| this.version = new ASN1Integer(0); |
| this.docLength = new ASN1Integer(docLength); |
| this.coeffQuadratic = RainbowUtil.convertArray(coeffQuadratic); |
| this.coeffSingular = RainbowUtil.convertArray(coeffSingular); |
| this.coeffScalar = RainbowUtil.convertArray(coeffScalar); |
| } |
| |
| public static RainbowPublicKey getInstance(Object o) |
| { |
| if (o instanceof RainbowPublicKey) |
| { |
| return (RainbowPublicKey)o; |
| } |
| else if (o != null) |
| { |
| return new RainbowPublicKey(ASN1Sequence.getInstance(o)); |
| } |
| |
| return null; |
| } |
| |
| public ASN1Integer getVersion() |
| { |
| return version; |
| } |
| |
| /** |
| * @return the docLength |
| */ |
| public int getDocLength() |
| { |
| return this.docLength.getValue().intValue(); |
| } |
| |
| /** |
| * @return the coeffquadratic |
| */ |
| public short[][] getCoeffQuadratic() |
| { |
| return RainbowUtil.convertArray(coeffQuadratic); |
| } |
| |
| /** |
| * @return the coeffsingular |
| */ |
| public short[][] getCoeffSingular() |
| { |
| return RainbowUtil.convertArray(coeffSingular); |
| } |
| |
| /** |
| * @return the coeffscalar |
| */ |
| public short[] getCoeffScalar() |
| { |
| return RainbowUtil.convertArray(coeffScalar); |
| } |
| |
| public ASN1Primitive toASN1Primitive() |
| { |
| ASN1EncodableVector v = new ASN1EncodableVector(); |
| |
| // encode <oidString> or version |
| if (version != null) |
| { |
| v.add(version); |
| } |
| else |
| { |
| v.add(oid); |
| } |
| |
| // encode <docLength> |
| v.add(docLength); |
| |
| // encode <coeffQuadratic> |
| ASN1EncodableVector asnCoeffQuad = new ASN1EncodableVector(); |
| for (int i = 0; i < coeffQuadratic.length; i++) |
| { |
| asnCoeffQuad.add(new DEROctetString(coeffQuadratic[i])); |
| } |
| v.add(new DERSequence(asnCoeffQuad)); |
| |
| // encode <coeffSingular> |
| ASN1EncodableVector asnCoeffSing = new ASN1EncodableVector(); |
| for (int i = 0; i < coeffSingular.length; i++) |
| { |
| asnCoeffSing.add(new DEROctetString(coeffSingular[i])); |
| } |
| v.add(new DERSequence(asnCoeffSing)); |
| |
| // encode <coeffScalar> |
| ASN1EncodableVector asnCoeffScalar = new ASN1EncodableVector(); |
| asnCoeffScalar.add(new DEROctetString(coeffScalar)); |
| v.add(new DERSequence(asnCoeffScalar)); |
| |
| |
| return new DERSequence(v); |
| } |
| } |