| package org.bouncycastle.pqc.asn1; |
| |
| import java.math.BigInteger; |
| import java.util.Vector; |
| |
| import org.bouncycastle.asn1.ASN1Encodable; |
| import org.bouncycastle.asn1.ASN1EncodableVector; |
| import org.bouncycastle.asn1.ASN1Integer; |
| import org.bouncycastle.asn1.ASN1Object; |
| import org.bouncycastle.asn1.ASN1Primitive; |
| import org.bouncycastle.asn1.ASN1Sequence; |
| import org.bouncycastle.asn1.DEROctetString; |
| import org.bouncycastle.asn1.DERSequence; |
| import org.bouncycastle.asn1.x509.AlgorithmIdentifier; |
| import org.bouncycastle.pqc.crypto.gmss.GMSSLeaf; |
| import org.bouncycastle.pqc.crypto.gmss.GMSSParameters; |
| import org.bouncycastle.pqc.crypto.gmss.GMSSRootCalc; |
| import org.bouncycastle.pqc.crypto.gmss.GMSSRootSig; |
| import org.bouncycastle.pqc.crypto.gmss.Treehash; |
| |
| public class GMSSPrivateKey |
| extends ASN1Object |
| { |
| private ASN1Primitive primitive; |
| |
| private GMSSPrivateKey(ASN1Sequence mtsPrivateKey) |
| { |
| // --- Decode <index>. |
| ASN1Sequence indexPart = (ASN1Sequence)mtsPrivateKey.getObjectAt(0); |
| int[] index = new int[indexPart.size()]; |
| for (int i = 0; i < indexPart.size(); i++) |
| { |
| index[i] = checkBigIntegerInIntRange(indexPart.getObjectAt(i)); |
| } |
| |
| // --- Decode <curSeeds>. |
| ASN1Sequence curSeedsPart = (ASN1Sequence)mtsPrivateKey.getObjectAt(1); |
| byte[][] curSeeds = new byte[curSeedsPart.size()][]; |
| for (int i = 0; i < curSeeds.length; i++) |
| { |
| curSeeds[i] = ((DEROctetString)curSeedsPart.getObjectAt(i)).getOctets(); |
| } |
| |
| // --- Decode <nextNextSeeds>. |
| ASN1Sequence nextNextSeedsPart = (ASN1Sequence)mtsPrivateKey.getObjectAt(2); |
| byte[][] nextNextSeeds = new byte[nextNextSeedsPart.size()][]; |
| for (int i = 0; i < nextNextSeeds.length; i++) |
| { |
| nextNextSeeds[i] = ((DEROctetString)nextNextSeedsPart.getObjectAt(i)).getOctets(); |
| } |
| |
| // --- Decode <curAuth>. |
| ASN1Sequence curAuthPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(3); |
| ASN1Sequence curAuthPart1; |
| |
| byte[][][] curAuth = new byte[curAuthPart0.size()][][]; |
| for (int i = 0; i < curAuth.length; i++) |
| { |
| curAuthPart1 = (ASN1Sequence)curAuthPart0.getObjectAt(i); |
| curAuth[i] = new byte[curAuthPart1.size()][]; |
| for (int j = 0; j < curAuth[i].length; j++) |
| { |
| curAuth[i][j] = ((DEROctetString)curAuthPart1.getObjectAt(j)).getOctets(); |
| } |
| } |
| |
| // --- Decode <nextAuth>. |
| ASN1Sequence nextAuthPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(4); |
| ASN1Sequence nextAuthPart1; |
| |
| byte[][][] nextAuth = new byte[nextAuthPart0.size()][][]; |
| for (int i = 0; i < nextAuth.length; i++) |
| { |
| nextAuthPart1 = (ASN1Sequence)nextAuthPart0.getObjectAt(i); |
| nextAuth[i] = new byte[nextAuthPart1.size()][]; |
| for (int j = 0; j < nextAuth[i].length; j++) |
| { |
| nextAuth[i][j] = ((DEROctetString)nextAuthPart1.getObjectAt(j)).getOctets(); |
| } |
| } |
| |
| // --- Decode <curTreehash>. |
| ASN1Sequence seqOfcurTreehash0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(5); |
| ASN1Sequence seqOfcurTreehash1; |
| ASN1Sequence seqOfcurTreehashStat; |
| ASN1Sequence seqOfcurTreehashBytes; |
| ASN1Sequence seqOfcurTreehashInts; |
| ASN1Sequence seqOfcurTreehashString; |
| |
| Treehash[][] curTreehash = new Treehash[seqOfcurTreehash0.size()][]; |
| /* |
| for (int i = 0; i < curTreehash.length; i++) |
| { |
| seqOfcurTreehash1 = (ASN1Sequence)seqOfcurTreehash0.getObjectAt(i); |
| curTreehash[i] = new Treehash[seqOfcurTreehash1.size()]; |
| for (int j = 0; j < curTreehash[i].length; j++) |
| { |
| seqOfcurTreehashStat = (ASN1Sequence)seqOfcurTreehash1.getObjectAt(j); |
| seqOfcurTreehashString = (ASN1Sequence)seqOfcurTreehashStat |
| .getObjectAt(0); |
| seqOfcurTreehashBytes = (ASN1Sequence)seqOfcurTreehashStat |
| .getObjectAt(1); |
| seqOfcurTreehashInts = (ASN1Sequence)seqOfcurTreehashStat |
| .getObjectAt(2); |
| |
| String[] name = new String[2]; |
| name[0] = ((DERIA5String)seqOfcurTreehashString.getObjectAt(0)).getString(); |
| name[1] = ((DERIA5String)seqOfcurTreehashString.getObjectAt(1)).getString(); |
| |
| int tailLength = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(1)); |
| byte[][] statByte = new byte[3 + tailLength][]; |
| statByte[0] = ((DEROctetString)seqOfcurTreehashBytes.getObjectAt(0)).getOctets(); |
| |
| if (statByte[0].length == 0) |
| { // if null was encoded |
| statByte[0] = null; |
| } |
| |
| statByte[1] = ((DEROctetString)seqOfcurTreehashBytes.getObjectAt(1)).getOctets(); |
| statByte[2] = ((DEROctetString)seqOfcurTreehashBytes.getObjectAt(2)).getOctets(); |
| for (int k = 0; k < tailLength; k++) |
| { |
| statByte[3 + k] = ((DEROctetString)seqOfcurTreehashBytes |
| .getObjectAt(3 + k)).getOctets(); |
| } |
| int[] statInt = new int[6 + tailLength]; |
| statInt[0] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(0)); |
| statInt[1] = tailLength; |
| statInt[2] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(2)); |
| statInt[3] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(3)); |
| statInt[4] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(4)); |
| statInt[5] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(5)); |
| for (int k = 0; k < tailLength; k++) |
| { |
| statInt[6 + k] = checkBigIntegerInIntRange(seqOfcurTreehashInts.getObjectAt(6 + k)); |
| } |
| |
| // TODO: Check if we can do better than throwing away name[1] !!! |
| curTreehash[i][j] = new Treehash(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); |
| } |
| } |
| |
| |
| // --- Decode <nextTreehash>. |
| ASN1Sequence seqOfNextTreehash0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(6); |
| ASN1Sequence seqOfNextTreehash1; |
| ASN1Sequence seqOfNextTreehashStat; |
| ASN1Sequence seqOfNextTreehashBytes; |
| ASN1Sequence seqOfNextTreehashInts; |
| ASN1Sequence seqOfNextTreehashString; |
| |
| Treehash[][] nextTreehash = new Treehash[seqOfNextTreehash0.size()][]; |
| |
| for (int i = 0; i < nextTreehash.length; i++) |
| { |
| seqOfNextTreehash1 = (ASN1Sequence)seqOfNextTreehash0.getObjectAt(i); |
| nextTreehash[i] = new Treehash[seqOfNextTreehash1.size()]; |
| for (int j = 0; j < nextTreehash[i].length; j++) |
| { |
| seqOfNextTreehashStat = (ASN1Sequence)seqOfNextTreehash1 |
| .getObjectAt(j); |
| seqOfNextTreehashString = (ASN1Sequence)seqOfNextTreehashStat |
| .getObjectAt(0); |
| seqOfNextTreehashBytes = (ASN1Sequence)seqOfNextTreehashStat |
| .getObjectAt(1); |
| seqOfNextTreehashInts = (ASN1Sequence)seqOfNextTreehashStat |
| .getObjectAt(2); |
| |
| String[] name = new String[2]; |
| name[0] = ((DERIA5String)seqOfNextTreehashString.getObjectAt(0)) |
| .getString(); |
| name[1] = ((DERIA5String)seqOfNextTreehashString.getObjectAt(1)) |
| .getString(); |
| |
| int tailLength = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(1)); |
| |
| byte[][] statByte = new byte[3 + tailLength][]; |
| statByte[0] = ((DEROctetString)seqOfNextTreehashBytes.getObjectAt(0)).getOctets(); |
| if (statByte[0].length == 0) |
| { // if null was encoded |
| statByte[0] = null; |
| } |
| |
| statByte[1] = ((DEROctetString)seqOfNextTreehashBytes.getObjectAt(1)).getOctets(); |
| statByte[2] = ((DEROctetString)seqOfNextTreehashBytes.getObjectAt(2)).getOctets(); |
| for (int k = 0; k < tailLength; k++) |
| { |
| statByte[3 + k] = ((DEROctetString)seqOfNextTreehashBytes |
| .getObjectAt(3 + k)).getOctets(); |
| } |
| int[] statInt = new int[6 + tailLength]; |
| statInt[0] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(0)); |
| |
| statInt[1] = tailLength; |
| statInt[2] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(2)); |
| |
| statInt[3] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(3)); |
| |
| statInt[4] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(4)); |
| |
| statInt[5] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(5)); |
| |
| for (int k = 0; k < tailLength; k++) |
| { |
| statInt[6 + k] = checkBigIntegerInIntRange(seqOfNextTreehashInts.getObjectAt(6 + k)); |
| |
| } |
| nextTreehash[i][j] = new Treehash(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); |
| } |
| } |
| |
| |
| // --- Decode <keep>. |
| ASN1Sequence keepPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(7); |
| ASN1Sequence keepPart1; |
| |
| byte[][][] keep = new byte[keepPart0.size()][][]; |
| for (int i = 0; i < keep.length; i++) |
| { |
| keepPart1 = (ASN1Sequence)keepPart0.getObjectAt(i); |
| keep[i] = new byte[keepPart1.size()][]; |
| for (int j = 0; j < keep[i].length; j++) |
| { |
| keep[i][j] = ((DEROctetString)keepPart1.getObjectAt(j)).getOctets(); |
| } |
| } |
| |
| // --- Decode <curStack>. |
| ASN1Sequence curStackPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(8); |
| ASN1Sequence curStackPart1; |
| |
| Vector[] curStack = new Vector[curStackPart0.size()]; |
| for (int i = 0; i < curStack.length; i++) |
| { |
| curStackPart1 = (ASN1Sequence)curStackPart0.getObjectAt(i); |
| curStack[i] = new Vector(); |
| for (int j = 0; j < curStackPart1.size(); j++) |
| { |
| curStack[i].addElement(((DEROctetString)curStackPart1.getObjectAt(j)).getOctets()); |
| } |
| } |
| |
| // --- Decode <nextStack>. |
| ASN1Sequence nextStackPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(9); |
| ASN1Sequence nextStackPart1; |
| |
| Vector[] nextStack = new Vector[nextStackPart0.size()]; |
| for (int i = 0; i < nextStack.length; i++) |
| { |
| nextStackPart1 = (ASN1Sequence)nextStackPart0.getObjectAt(i); |
| nextStack[i] = new Vector(); |
| for (int j = 0; j < nextStackPart1.size(); j++) |
| { |
| nextStack[i].addElement(((DEROctetString)nextStackPart1 |
| .getObjectAt(j)).getOctets()); |
| } |
| } |
| |
| // --- Decode <curRetain>. |
| ASN1Sequence curRetainPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(10); |
| ASN1Sequence curRetainPart1; |
| ASN1Sequence curRetainPart2; |
| |
| Vector[][] curRetain = new Vector[curRetainPart0.size()][]; |
| for (int i = 0; i < curRetain.length; i++) |
| { |
| curRetainPart1 = (ASN1Sequence)curRetainPart0.getObjectAt(i); |
| curRetain[i] = new Vector[curRetainPart1.size()]; |
| for (int j = 0; j < curRetain[i].length; j++) |
| { |
| curRetainPart2 = (ASN1Sequence)curRetainPart1.getObjectAt(j); |
| curRetain[i][j] = new Vector(); |
| for (int k = 0; k < curRetainPart2.size(); k++) |
| { |
| curRetain[i][j] |
| .addElement(((DEROctetString)curRetainPart2 |
| .getObjectAt(k)).getOctets()); |
| } |
| } |
| } |
| |
| // --- Decode <nextRetain>. |
| ASN1Sequence nextRetainPart0 = (ASN1Sequence)mtsPrivateKey.getObjectAt(11); |
| ASN1Sequence nextRetainPart1; |
| ASN1Sequence nextRetainPart2; |
| |
| Vector[][] nextRetain = new Vector[nextRetainPart0.size()][]; |
| for (int i = 0; i < nextRetain.length; i++) |
| { |
| nextRetainPart1 = (ASN1Sequence)nextRetainPart0.getObjectAt(i); |
| nextRetain[i] = new Vector[nextRetainPart1.size()]; |
| for (int j = 0; j < nextRetain[i].length; j++) |
| { |
| nextRetainPart2 = (ASN1Sequence)nextRetainPart1.getObjectAt(j); |
| nextRetain[i][j] = new Vector(); |
| for (int k = 0; k < nextRetainPart2.size(); k++) |
| { |
| nextRetain[i][j] |
| .addElement(((DEROctetString)nextRetainPart2 |
| .getObjectAt(k)).getOctets()); |
| } |
| } |
| } |
| |
| // --- Decode <nextNextLeaf>. |
| ASN1Sequence seqOfLeafs = (ASN1Sequence)mtsPrivateKey.getObjectAt(12); |
| ASN1Sequence seqOfLeafStat; |
| ASN1Sequence seqOfLeafBytes; |
| ASN1Sequence seqOfLeafInts; |
| ASN1Sequence seqOfLeafString; |
| |
| GMSSLeaf[] nextNextLeaf = new GMSSLeaf[seqOfLeafs.size()]; |
| |
| for (int i = 0; i < nextNextLeaf.length; i++) |
| { |
| seqOfLeafStat = (ASN1Sequence)seqOfLeafs.getObjectAt(i); |
| // nextNextAuth[i]= new byte[nextNextAuthPart1.size()][]; |
| seqOfLeafString = (ASN1Sequence)seqOfLeafStat.getObjectAt(0); |
| seqOfLeafBytes = (ASN1Sequence)seqOfLeafStat.getObjectAt(1); |
| seqOfLeafInts = (ASN1Sequence)seqOfLeafStat.getObjectAt(2); |
| |
| String[] name = new String[2]; |
| name[0] = ((DERIA5String)seqOfLeafString.getObjectAt(0)).getString(); |
| name[1] = ((DERIA5String)seqOfLeafString.getObjectAt(1)).getString(); |
| byte[][] statByte = new byte[4][]; |
| statByte[0] = ((DEROctetString)seqOfLeafBytes.getObjectAt(0)) |
| .getOctets(); |
| statByte[1] = ((DEROctetString)seqOfLeafBytes.getObjectAt(1)) |
| .getOctets(); |
| statByte[2] = ((DEROctetString)seqOfLeafBytes.getObjectAt(2)) |
| .getOctets(); |
| statByte[3] = ((DEROctetString)seqOfLeafBytes.getObjectAt(3)) |
| .getOctets(); |
| int[] statInt = new int[4]; |
| statInt[0] = checkBigIntegerInIntRange(seqOfLeafInts.getObjectAt(0)); |
| statInt[1] = checkBigIntegerInIntRange(seqOfLeafInts.getObjectAt(1)); |
| statInt[2] = checkBigIntegerInIntRange(seqOfLeafInts.getObjectAt(2)); |
| statInt[3] = checkBigIntegerInIntRange(seqOfLeafInts.getObjectAt(3)); |
| nextNextLeaf[i] = new GMSSLeaf(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); |
| } |
| |
| // --- Decode <upperLeaf>. |
| ASN1Sequence seqOfUpperLeafs = (ASN1Sequence)mtsPrivateKey.getObjectAt(13); |
| ASN1Sequence seqOfUpperLeafStat; |
| ASN1Sequence seqOfUpperLeafBytes; |
| ASN1Sequence seqOfUpperLeafInts; |
| ASN1Sequence seqOfUpperLeafString; |
| |
| GMSSLeaf[] upperLeaf = new GMSSLeaf[seqOfUpperLeafs.size()]; |
| |
| for (int i = 0; i < upperLeaf.length; i++) |
| { |
| seqOfUpperLeafStat = (ASN1Sequence)seqOfUpperLeafs.getObjectAt(i); |
| seqOfUpperLeafString = (ASN1Sequence)seqOfUpperLeafStat.getObjectAt(0); |
| seqOfUpperLeafBytes = (ASN1Sequence)seqOfUpperLeafStat.getObjectAt(1); |
| seqOfUpperLeafInts = (ASN1Sequence)seqOfUpperLeafStat.getObjectAt(2); |
| |
| String[] name = new String[2]; |
| name[0] = ((DERIA5String)seqOfUpperLeafString.getObjectAt(0)).getString(); |
| name[1] = ((DERIA5String)seqOfUpperLeafString.getObjectAt(1)).getString(); |
| byte[][] statByte = new byte[4][]; |
| statByte[0] = ((DEROctetString)seqOfUpperLeafBytes.getObjectAt(0)) |
| .getOctets(); |
| statByte[1] = ((DEROctetString)seqOfUpperLeafBytes.getObjectAt(1)) |
| .getOctets(); |
| statByte[2] = ((DEROctetString)seqOfUpperLeafBytes.getObjectAt(2)) |
| .getOctets(); |
| statByte[3] = ((DEROctetString)seqOfUpperLeafBytes.getObjectAt(3)) |
| .getOctets(); |
| int[] statInt = new int[4]; |
| statInt[0] = checkBigIntegerInIntRange(seqOfUpperLeafInts.getObjectAt(0)); |
| statInt[1] = checkBigIntegerInIntRange(seqOfUpperLeafInts.getObjectAt(1)); |
| statInt[2] = checkBigIntegerInIntRange(seqOfUpperLeafInts.getObjectAt(2)); |
| statInt[3] = checkBigIntegerInIntRange(seqOfUpperLeafInts.getObjectAt(3)); |
| upperLeaf[i] = new GMSSLeaf(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); |
| } |
| |
| // --- Decode <upperTreehashLeaf>. |
| ASN1Sequence seqOfUpperTHLeafs = (ASN1Sequence)mtsPrivateKey.getObjectAt(14); |
| ASN1Sequence seqOfUpperTHLeafStat; |
| ASN1Sequence seqOfUpperTHLeafBytes; |
| ASN1Sequence seqOfUpperTHLeafInts; |
| ASN1Sequence seqOfUpperTHLeafString; |
| |
| GMSSLeaf[] upperTHLeaf = new GMSSLeaf[seqOfUpperTHLeafs.size()]; |
| |
| for (int i = 0; i < upperTHLeaf.length; i++) |
| { |
| seqOfUpperTHLeafStat = (ASN1Sequence)seqOfUpperTHLeafs.getObjectAt(i); |
| seqOfUpperTHLeafString = (ASN1Sequence)seqOfUpperTHLeafStat.getObjectAt(0); |
| seqOfUpperTHLeafBytes = (ASN1Sequence)seqOfUpperTHLeafStat.getObjectAt(1); |
| seqOfUpperTHLeafInts = (ASN1Sequence)seqOfUpperTHLeafStat.getObjectAt(2); |
| |
| String[] name = new String[2]; |
| name[0] = ((DERIA5String)seqOfUpperTHLeafString.getObjectAt(0)) |
| .getString(); |
| name[1] = ((DERIA5String)seqOfUpperTHLeafString.getObjectAt(1)) |
| .getString(); |
| byte[][] statByte = new byte[4][]; |
| statByte[0] = ((DEROctetString)seqOfUpperTHLeafBytes.getObjectAt(0)) |
| .getOctets(); |
| statByte[1] = ((DEROctetString)seqOfUpperTHLeafBytes.getObjectAt(1)) |
| .getOctets(); |
| statByte[2] = ((DEROctetString)seqOfUpperTHLeafBytes.getObjectAt(2)) |
| .getOctets(); |
| statByte[3] = ((DEROctetString)seqOfUpperTHLeafBytes.getObjectAt(3)) |
| .getOctets(); |
| int[] statInt = new int[4]; |
| statInt[0] = checkBigIntegerInIntRange(seqOfUpperTHLeafInts.getObjectAt(0)); |
| statInt[1] = checkBigIntegerInIntRange(seqOfUpperTHLeafInts.getObjectAt(1)); |
| statInt[2] = checkBigIntegerInIntRange(seqOfUpperTHLeafInts.getObjectAt(2)); |
| statInt[3] = checkBigIntegerInIntRange(seqOfUpperTHLeafInts.getObjectAt(3)); |
| upperTHLeaf[i] = new GMSSLeaf(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); |
| } |
| |
| // --- Decode <minTreehash>. |
| ASN1Sequence minTreehashPart = (ASN1Sequence)mtsPrivateKey.getObjectAt(15); |
| int[] minTreehash = new int[minTreehashPart.size()]; |
| for (int i = 0; i < minTreehashPart.size(); i++) |
| { |
| minTreehash[i] = checkBigIntegerInIntRange(minTreehashPart.getObjectAt(i)); |
| } |
| |
| // --- Decode <nextRoot>. |
| ASN1Sequence seqOfnextRoots = (ASN1Sequence)mtsPrivateKey.getObjectAt(16); |
| byte[][] nextRoot = new byte[seqOfnextRoots.size()][]; |
| for (int i = 0; i < nextRoot.length; i++) |
| { |
| nextRoot[i] = ((DEROctetString)seqOfnextRoots.getObjectAt(i)) |
| .getOctets(); |
| } |
| |
| // --- Decode <nextNextRoot>. |
| ASN1Sequence seqOfnextNextRoot = (ASN1Sequence)mtsPrivateKey.getObjectAt(17); |
| ASN1Sequence seqOfnextNextRootStat; |
| ASN1Sequence seqOfnextNextRootBytes; |
| ASN1Sequence seqOfnextNextRootInts; |
| ASN1Sequence seqOfnextNextRootString; |
| ASN1Sequence seqOfnextNextRootTreeH; |
| ASN1Sequence seqOfnextNextRootRetain; |
| |
| GMSSRootCalc[] nextNextRoot = new GMSSRootCalc[seqOfnextNextRoot.size()]; |
| |
| for (int i = 0; i < nextNextRoot.length; i++) |
| { |
| seqOfnextNextRootStat = (ASN1Sequence)seqOfnextNextRoot.getObjectAt(i); |
| seqOfnextNextRootString = (ASN1Sequence)seqOfnextNextRootStat |
| .getObjectAt(0); |
| seqOfnextNextRootBytes = (ASN1Sequence)seqOfnextNextRootStat |
| .getObjectAt(1); |
| seqOfnextNextRootInts = (ASN1Sequence)seqOfnextNextRootStat.getObjectAt(2); |
| seqOfnextNextRootTreeH = (ASN1Sequence)seqOfnextNextRootStat |
| .getObjectAt(3); |
| seqOfnextNextRootRetain = (ASN1Sequence)seqOfnextNextRootStat |
| .getObjectAt(4); |
| |
| // decode treehash of nextNextRoot |
| // --------------------------------- |
| ASN1Sequence seqOfnextNextRootTreeHStat; |
| ASN1Sequence seqOfnextNextRootTreeHBytes; |
| ASN1Sequence seqOfnextNextRootTreeHInts; |
| ASN1Sequence seqOfnextNextRootTreeHString; |
| |
| Treehash[] nnRTreehash = new Treehash[seqOfnextNextRootTreeH.size()]; |
| |
| for (int k = 0; k < nnRTreehash.length; k++) |
| { |
| seqOfnextNextRootTreeHStat = (ASN1Sequence)seqOfnextNextRootTreeH |
| .getObjectAt(k); |
| seqOfnextNextRootTreeHString = (ASN1Sequence)seqOfnextNextRootTreeHStat |
| .getObjectAt(0); |
| seqOfnextNextRootTreeHBytes = (ASN1Sequence)seqOfnextNextRootTreeHStat |
| .getObjectAt(1); |
| seqOfnextNextRootTreeHInts = (ASN1Sequence)seqOfnextNextRootTreeHStat |
| .getObjectAt(2); |
| |
| String[] name = new String[2]; |
| name[0] = ((DERIA5String)seqOfnextNextRootTreeHString.getObjectAt(0)) |
| .getString(); |
| name[1] = ((DERIA5String)seqOfnextNextRootTreeHString.getObjectAt(1)) |
| .getString(); |
| |
| int tailLength = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(1)); |
| |
| byte[][] statByte = new byte[3 + tailLength][]; |
| statByte[0] = ((DEROctetString)seqOfnextNextRootTreeHBytes |
| .getObjectAt(0)).getOctets(); |
| if (statByte[0].length == 0) |
| { // if null was encoded |
| statByte[0] = null; |
| } |
| |
| statByte[1] = ((DEROctetString)seqOfnextNextRootTreeHBytes |
| .getObjectAt(1)).getOctets(); |
| statByte[2] = ((DEROctetString)seqOfnextNextRootTreeHBytes |
| .getObjectAt(2)).getOctets(); |
| for (int j = 0; j < tailLength; j++) |
| { |
| statByte[3 + j] = ((DEROctetString)seqOfnextNextRootTreeHBytes |
| .getObjectAt(3 + j)).getOctets(); |
| } |
| int[] statInt = new int[6 + tailLength]; |
| statInt[0] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(0)); |
| |
| statInt[1] = tailLength; |
| statInt[2] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(2)); |
| |
| statInt[3] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(3)); |
| |
| statInt[4] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(4)); |
| |
| statInt[5] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts.getObjectAt(5)); |
| |
| for (int j = 0; j < tailLength; j++) |
| { |
| statInt[6 + j] = checkBigIntegerInIntRange(seqOfnextNextRootTreeHInts |
| .getObjectAt(6 + j)); |
| } |
| nnRTreehash[k] = new Treehash(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); |
| } |
| // --------------------------------- |
| |
| // decode retain of nextNextRoot |
| // --------------------------------- |
| // ASN1Sequence seqOfnextNextRootRetainPart0 = |
| // (ASN1Sequence)seqOfnextNextRootRetain.get(0); |
| ASN1Sequence seqOfnextNextRootRetainPart1; |
| |
| Vector[] nnRRetain = new Vector[seqOfnextNextRootRetain.size()]; |
| for (int j = 0; j < nnRRetain.length; j++) |
| { |
| seqOfnextNextRootRetainPart1 = (ASN1Sequence)seqOfnextNextRootRetain |
| .getObjectAt(j); |
| nnRRetain[j] = new Vector(); |
| for (int k = 0; k < seqOfnextNextRootRetainPart1.size(); k++) |
| { |
| nnRRetain[j] |
| .addElement(((DEROctetString)seqOfnextNextRootRetainPart1 |
| .getObjectAt(k)).getOctets()); |
| } |
| } |
| // --------------------------------- |
| |
| String[] name = new String[2]; |
| name[0] = ((DERIA5String)seqOfnextNextRootString.getObjectAt(0)) |
| .getString(); |
| name[1] = ((DERIA5String)seqOfnextNextRootString.getObjectAt(1)) |
| .getString(); |
| |
| int heightOfTree = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(0)); |
| int tailLength = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(7)); |
| byte[][] statByte = new byte[1 + heightOfTree + tailLength][]; |
| statByte[0] = ((DEROctetString)seqOfnextNextRootBytes.getObjectAt(0)) |
| .getOctets(); |
| for (int j = 0; j < heightOfTree; j++) |
| { |
| statByte[1 + j] = ((DEROctetString)seqOfnextNextRootBytes |
| .getObjectAt(1 + j)).getOctets(); |
| } |
| for (int j = 0; j < tailLength; j++) |
| { |
| statByte[1 + heightOfTree + j] = ((DEROctetString)seqOfnextNextRootBytes |
| .getObjectAt(1 + heightOfTree + j)).getOctets(); |
| } |
| int[] statInt = new int[8 + heightOfTree + tailLength]; |
| statInt[0] = heightOfTree; |
| statInt[1] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(1)); |
| statInt[2] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(2)); |
| statInt[3] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(3)); |
| statInt[4] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(4)); |
| statInt[5] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(5)); |
| statInt[6] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(6)); |
| statInt[7] = tailLength; |
| for (int j = 0; j < heightOfTree; j++) |
| { |
| statInt[8 + j] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(8 + j)); |
| } |
| for (int j = 0; j < tailLength; j++) |
| { |
| statInt[8 + heightOfTree + j] = checkBigIntegerInIntRange(seqOfnextNextRootInts.getObjectAt(8 |
| + heightOfTree + j)); |
| } |
| nextNextRoot[i] = new GMSSRootCalc(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt, |
| nnRTreehash, nnRRetain); |
| } |
| |
| // --- Decode <curRootSig>. |
| ASN1Sequence seqOfcurRootSig = (ASN1Sequence)mtsPrivateKey.getObjectAt(18); |
| byte[][] curRootSig = new byte[seqOfcurRootSig.size()][]; |
| for (int i = 0; i < curRootSig.length; i++) |
| { |
| curRootSig[i] = ((DEROctetString)seqOfcurRootSig.getObjectAt(i)) |
| .getOctets(); |
| } |
| |
| // --- Decode <nextRootSig>. |
| ASN1Sequence seqOfnextRootSigs = (ASN1Sequence)mtsPrivateKey.getObjectAt(19); |
| ASN1Sequence seqOfnRSStats; |
| ASN1Sequence seqOfnRSStrings; |
| ASN1Sequence seqOfnRSInts; |
| ASN1Sequence seqOfnRSBytes; |
| |
| GMSSRootSig[] nextRootSig = new GMSSRootSig[seqOfnextRootSigs.size()]; |
| |
| for (int i = 0; i < nextRootSig.length; i++) |
| { |
| seqOfnRSStats = (ASN1Sequence)seqOfnextRootSigs.getObjectAt(i); |
| // nextNextAuth[i]= new byte[nextNextAuthPart1.size()][]; |
| seqOfnRSStrings = (ASN1Sequence)seqOfnRSStats.getObjectAt(0); |
| seqOfnRSBytes = (ASN1Sequence)seqOfnRSStats.getObjectAt(1); |
| seqOfnRSInts = (ASN1Sequence)seqOfnRSStats.getObjectAt(2); |
| |
| String[] name = new String[2]; |
| name[0] = ((DERIA5String)seqOfnRSStrings.getObjectAt(0)).getString(); |
| name[1] = ((DERIA5String)seqOfnRSStrings.getObjectAt(1)).getString(); |
| byte[][] statByte = new byte[5][]; |
| statByte[0] = ((DEROctetString)seqOfnRSBytes.getObjectAt(0)) |
| .getOctets(); |
| statByte[1] = ((DEROctetString)seqOfnRSBytes.getObjectAt(1)) |
| .getOctets(); |
| statByte[2] = ((DEROctetString)seqOfnRSBytes.getObjectAt(2)) |
| .getOctets(); |
| statByte[3] = ((DEROctetString)seqOfnRSBytes.getObjectAt(3)) |
| .getOctets(); |
| statByte[4] = ((DEROctetString)seqOfnRSBytes.getObjectAt(4)) |
| .getOctets(); |
| int[] statInt = new int[9]; |
| statInt[0] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(0)); |
| statInt[1] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(1)); |
| statInt[2] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(2)); |
| statInt[3] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(3)); |
| statInt[4] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(4)); |
| statInt[5] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(5)); |
| statInt[6] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(6)); |
| statInt[7] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(7)); |
| statInt[8] = checkBigIntegerInIntRange(seqOfnRSInts.getObjectAt(8)); |
| nextRootSig[i] = new GMSSRootSig(DigestFactory.getDigest(name[0]).getClass(), statByte, statInt); |
| } |
| |
| // --- Decode <name>. |
| |
| // TODO: Really check, why there are multiple algorithms, we only |
| // use the first one!!! |
| ASN1Sequence namePart = (ASN1Sequence)mtsPrivateKey.getObjectAt(20); |
| String[] name = new String[namePart.size()]; |
| for (int i = 0; i < name.length; i++) |
| { |
| name[i] = ((DERIA5String)namePart.getObjectAt(i)).getString(); |
| } |
| */ |
| } |
| |
| public GMSSPrivateKey(int[] index, byte[][] currentSeed, |
| byte[][] nextNextSeed, byte[][][] currentAuthPath, |
| byte[][][] nextAuthPath, Treehash[][] currentTreehash, |
| Treehash[][] nextTreehash, Vector[] currentStack, |
| Vector[] nextStack, Vector[][] currentRetain, |
| Vector[][] nextRetain, byte[][][] keep, GMSSLeaf[] nextNextLeaf, |
| GMSSLeaf[] upperLeaf, GMSSLeaf[] upperTreehashLeaf, |
| int[] minTreehash, byte[][] nextRoot, GMSSRootCalc[] nextNextRoot, |
| byte[][] currentRootSig, GMSSRootSig[] nextRootSig, |
| GMSSParameters gmssParameterset, AlgorithmIdentifier digestAlg) |
| { |
| AlgorithmIdentifier[] names = new AlgorithmIdentifier[] { digestAlg }; |
| this.primitive = encode(index, currentSeed, nextNextSeed, currentAuthPath, nextAuthPath, keep, currentTreehash, nextTreehash, currentStack, nextStack, currentRetain, nextRetain, nextNextLeaf, upperLeaf, upperTreehashLeaf, minTreehash, nextRoot, nextNextRoot, currentRootSig, nextRootSig, gmssParameterset, names); |
| } |
| |
| |
| // TODO: change method signature to something more integrated into BouncyCastle |
| |
| /** |
| * @param index tree indices |
| * @param currentSeeds seed for the generation of private OTS keys for the |
| * current subtrees (TREE) |
| * @param nextNextSeeds seed for the generation of private OTS keys for the |
| * subtrees after next (TREE++) |
| * @param currentAuthPaths array of current authentication paths (AUTHPATH) |
| * @param nextAuthPaths array of next authentication paths (AUTHPATH+) |
| * @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 |
| * @param algorithms An array of algorithm identifiers, containing the hash function details |
| */ |
| private ASN1Primitive encode(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, |
| AlgorithmIdentifier[] algorithms) |
| { |
| |
| ASN1EncodableVector result = new ASN1EncodableVector(); |
| |
| // --- Encode <index>. |
| ASN1EncodableVector indexPart = new ASN1EncodableVector(); |
| for (int i = 0; i < index.length; i++) |
| { |
| indexPart.add(new ASN1Integer(index[i])); |
| } |
| result.add(new DERSequence(indexPart)); |
| |
| // --- Encode <curSeeds>. |
| ASN1EncodableVector curSeedsPart = new ASN1EncodableVector(); |
| for (int i = 0; i < currentSeeds.length; i++) |
| { |
| curSeedsPart.add(new DEROctetString(currentSeeds[i])); |
| } |
| result.add(new DERSequence(curSeedsPart)); |
| |
| // --- Encode <nextNextSeeds>. |
| ASN1EncodableVector nextNextSeedsPart = new ASN1EncodableVector(); |
| for (int i = 0; i < nextNextSeeds.length; i++) |
| { |
| nextNextSeedsPart.add(new DEROctetString(nextNextSeeds[i])); |
| } |
| result.add(new DERSequence(nextNextSeedsPart)); |
| |
| // --- Encode <curAuth>. |
| ASN1EncodableVector curAuthPart0 = new ASN1EncodableVector(); |
| ASN1EncodableVector curAuthPart1 = new ASN1EncodableVector(); |
| for (int i = 0; i < currentAuthPaths.length; i++) |
| { |
| for (int j = 0; j < currentAuthPaths[i].length; j++) |
| { |
| curAuthPart0.add(new DEROctetString(currentAuthPaths[i][j])); |
| } |
| curAuthPart1.add(new DERSequence(curAuthPart0)); |
| curAuthPart0 = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(curAuthPart1)); |
| |
| // --- Encode <nextAuth>. |
| ASN1EncodableVector nextAuthPart0 = new ASN1EncodableVector(); |
| ASN1EncodableVector nextAuthPart1 = new ASN1EncodableVector(); |
| for (int i = 0; i < nextAuthPaths.length; i++) |
| { |
| for (int j = 0; j < nextAuthPaths[i].length; j++) |
| { |
| nextAuthPart0.add(new DEROctetString(nextAuthPaths[i][j])); |
| } |
| nextAuthPart1.add(new DERSequence(nextAuthPart0)); |
| nextAuthPart0 = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(nextAuthPart1)); |
| |
| // --- Encode <curTreehash>. |
| ASN1EncodableVector seqOfTreehash0 = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfTreehash1 = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfStat = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfByte = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfInt = new ASN1EncodableVector(); |
| |
| for (int i = 0; i < currentTreehash.length; i++) |
| { |
| for (int j = 0; j < currentTreehash[i].length; j++) |
| { |
| seqOfStat.add(new DERSequence(algorithms[0])); |
| |
| int tailLength = currentTreehash[i][j].getStatInt()[1]; |
| |
| seqOfByte.add(new DEROctetString(currentTreehash[i][j] |
| .getStatByte()[0])); |
| seqOfByte.add(new DEROctetString(currentTreehash[i][j] |
| .getStatByte()[1])); |
| seqOfByte.add(new DEROctetString(currentTreehash[i][j] |
| .getStatByte()[2])); |
| for (int k = 0; k < tailLength; k++) |
| { |
| seqOfByte.add(new DEROctetString(currentTreehash[i][j] |
| .getStatByte()[3 + k])); |
| } |
| seqOfStat.add(new DERSequence(seqOfByte)); |
| seqOfByte = new ASN1EncodableVector(); |
| |
| seqOfInt.add(new ASN1Integer( |
| currentTreehash[i][j].getStatInt()[0])); |
| seqOfInt.add(new ASN1Integer(tailLength)); |
| seqOfInt.add(new ASN1Integer( |
| currentTreehash[i][j].getStatInt()[2])); |
| seqOfInt.add(new ASN1Integer( |
| currentTreehash[i][j].getStatInt()[3])); |
| seqOfInt.add(new ASN1Integer( |
| currentTreehash[i][j].getStatInt()[4])); |
| seqOfInt.add(new ASN1Integer( |
| currentTreehash[i][j].getStatInt()[5])); |
| for (int k = 0; k < tailLength; k++) |
| { |
| seqOfInt.add(new ASN1Integer(currentTreehash[i][j] |
| .getStatInt()[6 + k])); |
| } |
| seqOfStat.add(new DERSequence(seqOfInt)); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| seqOfTreehash1.add(new DERSequence(seqOfStat)); |
| seqOfStat = new ASN1EncodableVector(); |
| } |
| seqOfTreehash0.add(new DERSequence(seqOfTreehash1)); |
| seqOfTreehash1 = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(seqOfTreehash0)); |
| |
| // --- Encode <nextTreehash>. |
| seqOfTreehash0 = new ASN1EncodableVector(); |
| seqOfTreehash1 = new ASN1EncodableVector(); |
| seqOfStat = new ASN1EncodableVector(); |
| seqOfByte = new ASN1EncodableVector(); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| for (int i = 0; i < nextTreehash.length; i++) |
| { |
| for (int j = 0; j < nextTreehash[i].length; j++) |
| { |
| seqOfStat.add(new DERSequence(algorithms[0])); |
| |
| int tailLength = nextTreehash[i][j].getStatInt()[1]; |
| |
| seqOfByte.add(new DEROctetString(nextTreehash[i][j] |
| .getStatByte()[0])); |
| seqOfByte.add(new DEROctetString(nextTreehash[i][j] |
| .getStatByte()[1])); |
| seqOfByte.add(new DEROctetString(nextTreehash[i][j] |
| .getStatByte()[2])); |
| for (int k = 0; k < tailLength; k++) |
| { |
| seqOfByte.add(new DEROctetString(nextTreehash[i][j] |
| .getStatByte()[3 + k])); |
| } |
| seqOfStat.add(new DERSequence(seqOfByte)); |
| seqOfByte = new ASN1EncodableVector(); |
| |
| seqOfInt |
| .add(new ASN1Integer(nextTreehash[i][j].getStatInt()[0])); |
| seqOfInt.add(new ASN1Integer(tailLength)); |
| seqOfInt |
| .add(new ASN1Integer(nextTreehash[i][j].getStatInt()[2])); |
| seqOfInt |
| .add(new ASN1Integer(nextTreehash[i][j].getStatInt()[3])); |
| seqOfInt |
| .add(new ASN1Integer(nextTreehash[i][j].getStatInt()[4])); |
| seqOfInt |
| .add(new ASN1Integer(nextTreehash[i][j].getStatInt()[5])); |
| for (int k = 0; k < tailLength; k++) |
| { |
| seqOfInt.add(new ASN1Integer(nextTreehash[i][j] |
| .getStatInt()[6 + k])); |
| } |
| seqOfStat.add(new DERSequence(seqOfInt)); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| seqOfTreehash1.add(new DERSequence(seqOfStat)); |
| seqOfStat = new ASN1EncodableVector(); |
| } |
| seqOfTreehash0.add(new DERSequence(new DERSequence(seqOfTreehash1))); |
| seqOfTreehash1 = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(seqOfTreehash0)); |
| |
| // --- Encode <keep>. |
| ASN1EncodableVector keepPart0 = new ASN1EncodableVector(); |
| ASN1EncodableVector keepPart1 = new ASN1EncodableVector(); |
| for (int i = 0; i < keep.length; i++) |
| { |
| for (int j = 0; j < keep[i].length; j++) |
| { |
| keepPart0.add(new DEROctetString(keep[i][j])); |
| } |
| keepPart1.add(new DERSequence(keepPart0)); |
| keepPart0 = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(keepPart1)); |
| |
| // --- Encode <curStack>. |
| ASN1EncodableVector curStackPart0 = new ASN1EncodableVector(); |
| ASN1EncodableVector curStackPart1 = new ASN1EncodableVector(); |
| for (int i = 0; i < currentStack.length; i++) |
| { |
| for (int j = 0; j < currentStack[i].size(); j++) |
| { |
| curStackPart0.add(new DEROctetString((byte[])currentStack[i] |
| .elementAt(j))); |
| } |
| curStackPart1.add(new DERSequence(curStackPart0)); |
| curStackPart0 = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(curStackPart1)); |
| |
| // --- Encode <nextStack>. |
| ASN1EncodableVector nextStackPart0 = new ASN1EncodableVector(); |
| ASN1EncodableVector nextStackPart1 = new ASN1EncodableVector(); |
| for (int i = 0; i < nextStack.length; i++) |
| { |
| for (int j = 0; j < nextStack[i].size(); j++) |
| { |
| nextStackPart0.add(new DEROctetString((byte[])nextStack[i] |
| .elementAt(j))); |
| } |
| nextStackPart1.add(new DERSequence(nextStackPart0)); |
| nextStackPart0 = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(nextStackPart1)); |
| |
| // --- Encode <curRetain>. |
| ASN1EncodableVector currentRetainPart0 = new ASN1EncodableVector(); |
| ASN1EncodableVector currentRetainPart1 = new ASN1EncodableVector(); |
| ASN1EncodableVector currentRetainPart2 = new ASN1EncodableVector(); |
| for (int i = 0; i < currentRetain.length; i++) |
| { |
| for (int j = 0; j < currentRetain[i].length; j++) |
| { |
| for (int k = 0; k < currentRetain[i][j].size(); k++) |
| { |
| currentRetainPart0.add(new DEROctetString( |
| (byte[])currentRetain[i][j].elementAt(k))); |
| } |
| currentRetainPart1.add(new DERSequence(currentRetainPart0)); |
| currentRetainPart0 = new ASN1EncodableVector(); |
| } |
| currentRetainPart2.add(new DERSequence(currentRetainPart1)); |
| currentRetainPart1 = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(currentRetainPart2)); |
| |
| // --- Encode <nextRetain>. |
| ASN1EncodableVector nextRetainPart0 = new ASN1EncodableVector(); |
| ASN1EncodableVector nextRetainPart1 = new ASN1EncodableVector(); |
| ASN1EncodableVector nextRetainPart2 = new ASN1EncodableVector(); |
| for (int i = 0; i < nextRetain.length; i++) |
| { |
| for (int j = 0; j < nextRetain[i].length; j++) |
| { |
| for (int k = 0; k < nextRetain[i][j].size(); k++) |
| { |
| nextRetainPart0.add(new DEROctetString( |
| (byte[])nextRetain[i][j].elementAt(k))); |
| } |
| nextRetainPart1.add(new DERSequence(nextRetainPart0)); |
| nextRetainPart0 = new ASN1EncodableVector(); |
| } |
| nextRetainPart2.add(new DERSequence(nextRetainPart1)); |
| nextRetainPart1 = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(nextRetainPart2)); |
| |
| // --- Encode <nextNextLeaf>. |
| ASN1EncodableVector seqOfLeaf = new ASN1EncodableVector(); |
| seqOfStat = new ASN1EncodableVector(); |
| seqOfByte = new ASN1EncodableVector(); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| for (int i = 0; i < nextNextLeaf.length; i++) |
| { |
| seqOfStat.add(new DERSequence(algorithms[0])); |
| |
| byte[][] tempByte = nextNextLeaf[i].getStatByte(); |
| seqOfByte.add(new DEROctetString(tempByte[0])); |
| seqOfByte.add(new DEROctetString(tempByte[1])); |
| seqOfByte.add(new DEROctetString(tempByte[2])); |
| seqOfByte.add(new DEROctetString(tempByte[3])); |
| seqOfStat.add(new DERSequence(seqOfByte)); |
| seqOfByte = new ASN1EncodableVector(); |
| |
| int[] tempInt = nextNextLeaf[i].getStatInt(); |
| seqOfInt.add(new ASN1Integer(tempInt[0])); |
| seqOfInt.add(new ASN1Integer(tempInt[1])); |
| seqOfInt.add(new ASN1Integer(tempInt[2])); |
| seqOfInt.add(new ASN1Integer(tempInt[3])); |
| seqOfStat.add(new DERSequence(seqOfInt)); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| seqOfLeaf.add(new DERSequence(seqOfStat)); |
| seqOfStat = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(seqOfLeaf)); |
| |
| // --- Encode <upperLEAF>. |
| ASN1EncodableVector seqOfUpperLeaf = new ASN1EncodableVector(); |
| seqOfStat = new ASN1EncodableVector(); |
| seqOfByte = new ASN1EncodableVector(); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| for (int i = 0; i < upperLeaf.length; i++) |
| { |
| seqOfStat.add(new DERSequence(algorithms[0])); |
| |
| byte[][] tempByte = upperLeaf[i].getStatByte(); |
| seqOfByte.add(new DEROctetString(tempByte[0])); |
| seqOfByte.add(new DEROctetString(tempByte[1])); |
| seqOfByte.add(new DEROctetString(tempByte[2])); |
| seqOfByte.add(new DEROctetString(tempByte[3])); |
| seqOfStat.add(new DERSequence(seqOfByte)); |
| seqOfByte = new ASN1EncodableVector(); |
| |
| int[] tempInt = upperLeaf[i].getStatInt(); |
| seqOfInt.add(new ASN1Integer(tempInt[0])); |
| seqOfInt.add(new ASN1Integer(tempInt[1])); |
| seqOfInt.add(new ASN1Integer(tempInt[2])); |
| seqOfInt.add(new ASN1Integer(tempInt[3])); |
| seqOfStat.add(new DERSequence(seqOfInt)); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| seqOfUpperLeaf.add(new DERSequence(seqOfStat)); |
| seqOfStat = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(seqOfUpperLeaf)); |
| |
| // encode <upperTreehashLeaf> |
| ASN1EncodableVector seqOfUpperTreehashLeaf = new ASN1EncodableVector(); |
| seqOfStat = new ASN1EncodableVector(); |
| seqOfByte = new ASN1EncodableVector(); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| for (int i = 0; i < upperTreehashLeaf.length; i++) |
| { |
| seqOfStat.add(new DERSequence(algorithms[0])); |
| |
| byte[][] tempByte = upperTreehashLeaf[i].getStatByte(); |
| seqOfByte.add(new DEROctetString(tempByte[0])); |
| seqOfByte.add(new DEROctetString(tempByte[1])); |
| seqOfByte.add(new DEROctetString(tempByte[2])); |
| seqOfByte.add(new DEROctetString(tempByte[3])); |
| seqOfStat.add(new DERSequence(seqOfByte)); |
| seqOfByte = new ASN1EncodableVector(); |
| |
| int[] tempInt = upperTreehashLeaf[i].getStatInt(); |
| seqOfInt.add(new ASN1Integer(tempInt[0])); |
| seqOfInt.add(new ASN1Integer(tempInt[1])); |
| seqOfInt.add(new ASN1Integer(tempInt[2])); |
| seqOfInt.add(new ASN1Integer(tempInt[3])); |
| seqOfStat.add(new DERSequence(seqOfInt)); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| seqOfUpperTreehashLeaf.add(new DERSequence(seqOfStat)); |
| seqOfStat = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(seqOfUpperTreehashLeaf)); |
| |
| // --- Encode <minTreehash>. |
| ASN1EncodableVector minTreehashPart = new ASN1EncodableVector(); |
| for (int i = 0; i < minTreehash.length; i++) |
| { |
| minTreehashPart.add(new ASN1Integer(minTreehash[i])); |
| } |
| result.add(new DERSequence(minTreehashPart)); |
| |
| // --- Encode <nextRoot>. |
| ASN1EncodableVector nextRootPart = new ASN1EncodableVector(); |
| for (int i = 0; i < nextRoot.length; i++) |
| { |
| nextRootPart.add(new DEROctetString(nextRoot[i])); |
| } |
| result.add(new DERSequence(nextRootPart)); |
| |
| // --- Encode <nextNextRoot>. |
| ASN1EncodableVector seqOfnextNextRoot = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfnnRStats = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfnnRStrings = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfnnRBytes = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfnnRInts = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfnnRTreehash = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfnnRRetain = new ASN1EncodableVector(); |
| |
| for (int i = 0; i < nextNextRoot.length; i++) |
| { |
| seqOfnnRStats.add(new DERSequence(algorithms[0])); |
| seqOfnnRStrings = new ASN1EncodableVector(); |
| |
| int heightOfTree = nextNextRoot[i].getStatInt()[0]; |
| int tailLength = nextNextRoot[i].getStatInt()[7]; |
| |
| seqOfnnRBytes.add(new DEROctetString( |
| nextNextRoot[i].getStatByte()[0])); |
| for (int j = 0; j < heightOfTree; j++) |
| { |
| seqOfnnRBytes.add(new DEROctetString(nextNextRoot[i] |
| .getStatByte()[1 + j])); |
| } |
| for (int j = 0; j < tailLength; j++) |
| { |
| seqOfnnRBytes.add(new DEROctetString(nextNextRoot[i] |
| .getStatByte()[1 + heightOfTree + j])); |
| } |
| |
| seqOfnnRStats.add(new DERSequence(seqOfnnRBytes)); |
| seqOfnnRBytes = new ASN1EncodableVector(); |
| |
| seqOfnnRInts.add(new ASN1Integer(heightOfTree)); |
| seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[1])); |
| seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[2])); |
| seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[3])); |
| seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[4])); |
| seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[5])); |
| seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[6])); |
| seqOfnnRInts.add(new ASN1Integer(tailLength)); |
| for (int j = 0; j < heightOfTree; j++) |
| { |
| seqOfnnRInts.add(new ASN1Integer( |
| nextNextRoot[i].getStatInt()[8 + j])); |
| } |
| for (int j = 0; j < tailLength; j++) |
| { |
| seqOfnnRInts.add(new ASN1Integer(nextNextRoot[i].getStatInt()[8 |
| + heightOfTree + j])); |
| } |
| |
| seqOfnnRStats.add(new DERSequence(seqOfnnRInts)); |
| seqOfnnRInts = new ASN1EncodableVector(); |
| |
| // add treehash of nextNextRoot object |
| // ---------------------------- |
| seqOfStat = new ASN1EncodableVector(); |
| seqOfByte = new ASN1EncodableVector(); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| if (nextNextRoot[i].getTreehash() != null) |
| { |
| for (int j = 0; j < nextNextRoot[i].getTreehash().length; j++) |
| { |
| seqOfStat.add(new DERSequence(algorithms[0])); |
| |
| tailLength = nextNextRoot[i].getTreehash()[j].getStatInt()[1]; |
| |
| seqOfByte.add(new DEROctetString(nextNextRoot[i] |
| .getTreehash()[j].getStatByte()[0])); |
| seqOfByte.add(new DEROctetString(nextNextRoot[i] |
| .getTreehash()[j].getStatByte()[1])); |
| seqOfByte.add(new DEROctetString(nextNextRoot[i] |
| .getTreehash()[j].getStatByte()[2])); |
| for (int k = 0; k < tailLength; k++) |
| { |
| seqOfByte.add(new DEROctetString(nextNextRoot[i] |
| .getTreehash()[j].getStatByte()[3 + k])); |
| } |
| seqOfStat.add(new DERSequence(seqOfByte)); |
| seqOfByte = new ASN1EncodableVector(); |
| |
| seqOfInt.add(new ASN1Integer( |
| nextNextRoot[i].getTreehash()[j].getStatInt()[0])); |
| seqOfInt.add(new ASN1Integer(tailLength)); |
| seqOfInt.add(new ASN1Integer( |
| nextNextRoot[i].getTreehash()[j].getStatInt()[2])); |
| seqOfInt.add(new ASN1Integer( |
| nextNextRoot[i].getTreehash()[j].getStatInt()[3])); |
| seqOfInt.add(new ASN1Integer( |
| nextNextRoot[i].getTreehash()[j].getStatInt()[4])); |
| seqOfInt.add(new ASN1Integer( |
| nextNextRoot[i].getTreehash()[j].getStatInt()[5])); |
| for (int k = 0; k < tailLength; k++) |
| { |
| seqOfInt.add(new ASN1Integer(nextNextRoot[i] |
| .getTreehash()[j].getStatInt()[6 + k])); |
| } |
| seqOfStat.add(new DERSequence(seqOfInt)); |
| seqOfInt = new ASN1EncodableVector(); |
| |
| seqOfnnRTreehash.add(new DERSequence(seqOfStat)); |
| seqOfStat = new ASN1EncodableVector(); |
| } |
| } |
| // ---------------------------- |
| seqOfnnRStats.add(new DERSequence(seqOfnnRTreehash)); |
| seqOfnnRTreehash = new ASN1EncodableVector(); |
| |
| // encode retain of nextNextRoot |
| // ---------------------------- |
| // --- Encode <curRetain>. |
| currentRetainPart0 = new ASN1EncodableVector(); |
| if (nextNextRoot[i].getRetain() != null) |
| { |
| for (int j = 0; j < nextNextRoot[i].getRetain().length; j++) |
| { |
| for (int k = 0; k < nextNextRoot[i].getRetain()[j].size(); k++) |
| { |
| currentRetainPart0.add(new DEROctetString( |
| (byte[])nextNextRoot[i].getRetain()[j] |
| .elementAt(k))); |
| } |
| seqOfnnRRetain.add(new DERSequence(currentRetainPart0)); |
| currentRetainPart0 = new ASN1EncodableVector(); |
| } |
| } |
| // ---------------------------- |
| seqOfnnRStats.add(new DERSequence(seqOfnnRRetain)); |
| seqOfnnRRetain = new ASN1EncodableVector(); |
| |
| seqOfnextNextRoot.add(new DERSequence(seqOfnnRStats)); |
| seqOfnnRStats = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(seqOfnextNextRoot)); |
| |
| // --- Encode <curRootSig>. |
| ASN1EncodableVector curRootSigPart = new ASN1EncodableVector(); |
| for (int i = 0; i < currentRootSig.length; i++) |
| { |
| curRootSigPart.add(new DEROctetString(currentRootSig[i])); |
| } |
| result.add(new DERSequence(curRootSigPart)); |
| |
| // --- Encode <nextRootSig>. |
| ASN1EncodableVector seqOfnextRootSigs = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfnRSStats = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfnRSStrings = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfnRSBytes = new ASN1EncodableVector(); |
| ASN1EncodableVector seqOfnRSInts = new ASN1EncodableVector(); |
| |
| for (int i = 0; i < nextRootSig.length; i++) |
| { |
| seqOfnRSStats.add(new DERSequence(algorithms[0])); |
| seqOfnRSStrings = new ASN1EncodableVector(); |
| |
| seqOfnRSBytes.add(new DEROctetString( |
| nextRootSig[i].getStatByte()[0])); |
| seqOfnRSBytes.add(new DEROctetString( |
| nextRootSig[i].getStatByte()[1])); |
| seqOfnRSBytes.add(new DEROctetString( |
| nextRootSig[i].getStatByte()[2])); |
| seqOfnRSBytes.add(new DEROctetString( |
| nextRootSig[i].getStatByte()[3])); |
| seqOfnRSBytes.add(new DEROctetString( |
| nextRootSig[i].getStatByte()[4])); |
| |
| seqOfnRSStats.add(new DERSequence(seqOfnRSBytes)); |
| seqOfnRSBytes = new ASN1EncodableVector(); |
| |
| seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[0])); |
| seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[1])); |
| seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[2])); |
| seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[3])); |
| seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[4])); |
| seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[5])); |
| seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[6])); |
| seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[7])); |
| seqOfnRSInts.add(new ASN1Integer(nextRootSig[i].getStatInt()[8])); |
| |
| seqOfnRSStats.add(new DERSequence(seqOfnRSInts)); |
| seqOfnRSInts = new ASN1EncodableVector(); |
| |
| seqOfnextRootSigs.add(new DERSequence(seqOfnRSStats)); |
| seqOfnRSStats = new ASN1EncodableVector(); |
| } |
| result.add(new DERSequence(seqOfnextRootSigs)); |
| |
| // --- Encode <parameterset>. |
| ASN1EncodableVector parSetPart0 = new ASN1EncodableVector(); |
| ASN1EncodableVector parSetPart1 = new ASN1EncodableVector(); |
| ASN1EncodableVector parSetPart2 = new ASN1EncodableVector(); |
| ASN1EncodableVector parSetPart3 = new ASN1EncodableVector(); |
| |
| for (int i = 0; i < gmssParameterset.getHeightOfTrees().length; i++) |
| { |
| parSetPart1.add(new ASN1Integer( |
| gmssParameterset.getHeightOfTrees()[i])); |
| parSetPart2.add(new ASN1Integer(gmssParameterset |
| .getWinternitzParameter()[i])); |
| parSetPart3.add(new ASN1Integer(gmssParameterset.getK()[i])); |
| } |
| parSetPart0.add(new ASN1Integer(gmssParameterset.getNumOfLayers())); |
| parSetPart0.add(new DERSequence(parSetPart1)); |
| parSetPart0.add(new DERSequence(parSetPart2)); |
| parSetPart0.add(new DERSequence(parSetPart3)); |
| result.add(new DERSequence(parSetPart0)); |
| |
| // --- Encode <names>. |
| ASN1EncodableVector namesPart = new ASN1EncodableVector(); |
| |
| for (int i = 0; i < algorithms.length; i++) |
| { |
| namesPart.add(algorithms[i]); |
| } |
| |
| result.add(new DERSequence(namesPart)); |
| return new DERSequence(result); |
| |
| } |
| |
| private static int checkBigIntegerInIntRange(ASN1Encodable a) |
| { |
| BigInteger b = ((ASN1Integer)a).getValue(); |
| if ((b.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) || |
| (b.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0)) |
| { |
| throw new IllegalArgumentException("BigInteger not in Range: " + b.toString()); |
| } |
| return b.intValue(); |
| } |
| |
| |
| public ASN1Primitive toASN1Primitive() |
| { |
| return this.primitive; |
| } |
| } |