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

io.takamaka.crypto.digests.CSHAKEDigest Maven / Gradle / Ivy

Go to download

This package contains an old version of the qtesla algorithm from the bouncycastle library. Changes have been introduced in the current library that make the old keys incompatible with the new ones. The purpose of this package is to maintain, within the takamaka.io software, compatibility with the old implementation of signature keys.

The newest version!
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package io.takamaka.crypto.digests;

import io.takamaka.crypto.tkmsecurityprovider.util.Arrays;

/**
 * Customizable SHAKE function.
 */
public class CSHAKEDigest
    extends SHAKEDigest
{
    private static final byte[] padding = new byte[100];
    private final byte[] diff;

    /**
     * Base constructor.
     *
     * @param bitLength bit length of the underlying SHAKE function, 128 or 256.
     * @param N the function name string, note this is reserved for use by NIST. Avoid using it if not required.
     * @param S the customization string - available for local use.
     */
    public CSHAKEDigest(int bitLength, byte[] N, byte[] S)
    {
        super(bitLength);

        if ((N == null || N.length == 0) && (S == null || S.length == 0))
        {
            diff = null;
        }
        else
        {
            diff = Arrays.concatenate(leftEncode(rate / 8), encodeString(N), encodeString(S));
            diffPadAndAbsorb();
        }
    }

    private void diffPadAndAbsorb()
    {
        int blockSize = rate / 8;
        absorb(diff, 0, diff.length);

        int required = blockSize - (diff.length % blockSize);

        while (required > padding.length)
        {
            absorb(padding, 0, padding.length);
            required -= padding.length;
        }
        
        absorb(padding, 0, required);
    }

    private byte[] encodeString(byte[] str)
    {
        if (str == null || str.length == 0)
        {
            return leftEncode(0);
        }

        return Arrays.concatenate(leftEncode(str.length * 8L), str);
    }
    
    private static byte[] leftEncode(long strLen)
    {
    	byte n = 1;

        long v = strLen;
    	while ((v >>= 8) != 0)
        {
    		n++;
    	}

        byte[] b = new byte[n + 1];

    	b[0] = n;
  
    	for (int i = 1; i <= n; i++)
    	{
    		b[i] = (byte)(strLen >> (8 * (n - i)));
    	}
 
    	return b;
    }
    
    @Override
    public int doOutput(byte[] out, int outOff, int outLen)
    {
        if (diff != null)
        {
            if (!squeezing)
            {
                absorbBits(0x00, 2);
            }

            squeeze(out, outOff, ((long)outLen) * 8);

            return outLen;
        }
        else
        {
            return super.doOutput(out, outOff, outLen);
        }
    }

    @Override
    public void reset()
    {
        super.reset();
        
        if (diff != null)
        {
            diffPadAndAbsorb();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy