All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.pqc.crypto.xmss.XMSSMTSignature Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for Java 1.8 and later with debug enabled.

The newest version!
package org.bouncycastle.pqc.crypto.xmss;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Encodable;

/**
 * XMSS^MT Signature.
 */
public final class XMSSMTSignature
    implements XMSSStoreableObjectInterface, Encodable
{

    private final XMSSMTParameters params;
    private final long index;
    private final byte[] random;
    private final List reducedSignatures;

    private XMSSMTSignature(Builder builder)
    {
        super();
        params = builder.params;
        if (params == null)
        {
            throw new NullPointerException("params == null");
        }
        int n = params.getTreeDigestSize();
        byte[] signature = builder.signature;
        if (signature != null)
        {
            /* import */
            int len = params.getWOTSPlus().getParams().getLen();
            int indexSize = (int)Math.ceil(params.getHeight() / (double)8);
            int randomSize = n;
            int reducedSignatureSizeSingle = ((params.getHeight() / params.getLayers()) + len) * n;
            int reducedSignaturesSizeTotal = reducedSignatureSizeSingle * params.getLayers();
            int totalSize = indexSize + randomSize + reducedSignaturesSizeTotal;
            if (signature.length != totalSize)
            {
                throw new IllegalArgumentException("signature has wrong size");
            }
            int position = 0;
            index = XMSSUtil.bytesToXBigEndian(signature, position, indexSize);

            if (!XMSSUtil.isIndexValid(params.getHeight(), index))
            {
                throw new IllegalArgumentException("index out of bounds");
            }
            position += indexSize;
            random = XMSSUtil.extractBytesAtOffset(signature, position, randomSize);
            position += randomSize;
            reducedSignatures = new ArrayList();
            while (position < signature.length)
            {
                XMSSReducedSignature xmssSig = new XMSSReducedSignature.Builder(params.getXMSSParameters())
                    .withReducedSignature(XMSSUtil.extractBytesAtOffset(signature, position, reducedSignatureSizeSingle))
                    .build();
                reducedSignatures.add(xmssSig);
                position += reducedSignatureSizeSingle;
            }
        }
        else
        {
            /* set */
            index = builder.index;
            byte[] tmpRandom = builder.random;
            if (tmpRandom != null)
            {
                if (tmpRandom.length != n)
                {
                    throw new IllegalArgumentException("size of random needs to be equal to size of digest");
                }
                random = tmpRandom;
            }
            else
            {
                random = new byte[n];
            }
            List tmpReducedSignatures = builder.reducedSignatures;
            if (tmpReducedSignatures != null)
            {
                reducedSignatures = tmpReducedSignatures;
            }
            else
            {
                reducedSignatures = new ArrayList();
            }
        }
    }

    public byte[] getEncoded()
        throws IOException
    {
        return toByteArray();
    }

    public static class Builder
    {

        /* mandatory */
        private final XMSSMTParameters params;
        /* optional */
        private long index = 0L;
        private byte[] random = null;
        private List reducedSignatures = null;
        private byte[] signature = null;

        public Builder(XMSSMTParameters params)
        {
            super();
            this.params = params;
        }

        public Builder withIndex(long val)
        {
            index = val;
            return this;
        }

        public Builder withRandom(byte[] val)
        {
            random = XMSSUtil.cloneArray(val);
            return this;
        }

        public Builder withReducedSignatures(List val)
        {
            reducedSignatures = val;
            return this;
        }

        public Builder withSignature(byte[] val)
        {
            signature = Arrays.clone(val);
            return this;
        }

        public XMSSMTSignature build()
        {
            return new XMSSMTSignature(this);
        }
    }

    public byte[] toByteArray()
    {
        /* index || random || reduced signatures */
        int n = params.getTreeDigestSize();
        int len = params.getWOTSPlus().getParams().getLen();
        int indexSize = (int)Math.ceil(params.getHeight() / (double)8);
        int randomSize = n;
        int reducedSignatureSizeSingle = ((params.getHeight() / params.getLayers()) + len) * n;
        int reducedSignaturesSizeTotal = reducedSignatureSizeSingle * params.getLayers();
        int totalSize = indexSize + randomSize + reducedSignaturesSizeTotal;
        byte[] out = new byte[totalSize];
        int position = 0;
        /* copy index */
        byte[] indexBytes = XMSSUtil.toBytesBigEndian(index, indexSize);
        XMSSUtil.copyBytesAtOffset(out, indexBytes, position);
        position += indexSize;
        /* copy random */
        XMSSUtil.copyBytesAtOffset(out, random, position);
        position += randomSize;
        /* copy reduced signatures */
        for (XMSSReducedSignature reducedSignature : reducedSignatures)
        {
            byte[] signature = reducedSignature.toByteArray();
            XMSSUtil.copyBytesAtOffset(out, signature, position);
            position += reducedSignatureSizeSingle;
        }
        return out;
    }

    public long getIndex()
    {
        return index;
    }

    public byte[] getRandom()
    {
        return XMSSUtil.cloneArray(random);
    }

    public List getReducedSignatures()
    {
        return reducedSignatures;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy