Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.bouncycastle.crypto.digests;
  
implementation of GOST R 34.11-94
 
 public class GOST3411Digest
     implements ExtendedDigestMemoable
 {
     private static final int    DIGEST_LENGTH = 32;
 
     private byte[]   H = new byte[32], L = new byte[32],
                      M = new byte[32], Sum = new byte[32];
     private byte[][] C = new byte[4][32];
 
     private byte[]  xBuf = new byte[32];
     private int  xBufOff;
     private long byteCount;
     
     private BlockCipher cipher = new GOST28147Engine();
     private byte[] sBox;

    
Standard constructor
 
     public GOST3411Digest()
     {
          = GOST28147Engine.getSBox("D-A");
         .init(truenew ParametersWithSBox(null));
 
         reset();
     }

    
Constructor to allow use of a particular sbox with GOST28147

 
     public GOST3411Digest(byte[] sBoxParam)
     {
          = Arrays.clone(sBoxParam);
         .init(truenew ParametersWithSBox(null));
 
         reset();
     }

    
Copy constructor. This will copy the state of the provided message digest.
 
     public GOST3411Digest(GOST3411Digest t)
     {
         reset(t);
     }
 
     public String getAlgorithmName()
     {
         return "GOST3411";
     }
 
     public int getDigestSize()
     {
         return ;
     }
 
     public void update(byte in)
     {
         [++] = in;
         if ( == .)
         {
             sumByteArray(); // calc sum M
             processBlock(, 0);
              = 0;
         }
         ++;
     }
 
     public void update(byte[] inint inOffint len)
     {
         while (( != 0) && (len > 0))
         {
             update(in[inOff]);
             inOff++;
             len--;
         }
 
         while (len > .)
         {
             System.arraycopy(ininOff, 0, .);
 
             sumByteArray(); // calc sum M
             processBlock(, 0);
            inOff += .;
            len -= .;
             += .;
        }
        // load in the remainder.
        while (len > 0)
        {
            update(in[inOff]);
            inOff++;
            len--;
        }
    }
    // (i + 1 + 4(k - 1)) = 8i + k      i = 0-3, k = 1-8
    private byte[] K = new byte[32];
    private byte[] P(byte[] in)
    {
        for(int k = 0; k < 8; k++)
        {
            [4*k] = in[k];
            [1 + 4*k] = in[ 8 + k];
            [2 + 4*k] = in[16 + k];
            [3 + 4*k] = in[24 + k];
        }
        return ;
    }
    //A (x) = (x0 ^ x1) || x3 || x2 || x1
    byte[] a = new byte[8];
    private byte[] A(byte[] in)
    {
        for(int j=0; j<8; j++)
        {
            [j]=(byte)(in[j] ^ in[j+8]);
        }
        System.arraycopy(in, 8, in, 0, 24);
        System.arraycopy(, 0, in, 24, 8);
        return in;
    }
    //Encrypt function, ECB mode
    private void E(byte[] keybyte[] sint sOffbyte[] inint inOff)
    {
        .init(truenew KeyParameter(key));
        
        .processBlock(ininOffssOff);
    }
    // (in:) n16||..||n1 ==> (out:) n1^n2^n3^n4^n13^n16||n16||..||n2
    short[] wS = new short[16], w_S = new short[16];
    private void fw(byte[] in)
    {
        cpyBytesToShort(in);
        [15] = (short)([0] ^ [1] ^ [2] ^ [3] ^ [12] ^ [15]);
        System.arraycopy(, 1, , 0, 15);
        cpyShortToBytes(in);
    }
    // block processing
    byte[] S = new byte[32];
    byte[] U = new byte[32], V = new byte[32], W = new byte[32];
    protected void processBlock(byte[] inint inOff)
    {
        System.arraycopy(ininOff, 0, 32);
        //key step 1
 
        // H = h3 || h2 || h1 || h0
        // S = s3 || s2 || s1 || s0
        System.arraycopy(, 0, , 0, 32);
        System.arraycopy(, 0, , 0, 32);
        for (int j=0; j<32; j++)
        {
            [j] = (byte)([j]^[j]);
        }
        // Encrypt gost28147-ECB
        E(P(), , 0, , 0); // s0 = EK0 [h0]
        //keys step 2,3,4
        for (int i=1; i<4; i++)
        {
            byte[] tmpA = A();
            for (int j=0; j<32; j++)
            {
                [j] = (byte)(tmpA[j] ^ [i][j]);
            }
             = A(A());
            for (int j=0; j<32; j++)
            {
                [j] = (byte)([j]^[j]);
            }
            // Encrypt gost28147-ECB
            E(P(), i * 8, i * 8); // si = EKi [hi]
        }
        // x(M, H) = y61(H^y(M^y12(S)))
        for(int n = 0; n < 12; n++)
        {
            fw();
        }
        for(int n = 0; n < 32; n++)
        {
            [n] = (byte)([n] ^ [n]);
        }
        fw();
        for(int n = 0; n < 32; n++)
        {
            [n] = (byte)([n] ^ [n]);
        }
        for(int n = 0; n < 61; n++)
        {
            fw();
        }
        System.arraycopy(, 0, , 0, .);
    }
    private void finish()
    {
        Pack.longToLittleEndian( * 8, , 0); // get length into L (byteCount * 8 = bitCount)
        while ( != 0)
        {
            update((byte)0);
        }
        processBlock(, 0);
        processBlock(, 0);
    }
    public int doFinal(
        byte[]  out,
        int     outOff)
    {
        finish();
        System.arraycopy(, 0, outoutOff.);
        reset();
        return ;
    }

    
reset the chaining variables to the IV values.
    private static final byte[]  C2 = {
       0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,
       (byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,
       0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF,0x00,0x00,(byte)0xFF,
       (byte)0xFF,0x00,0x00,0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF};
    public void reset()
    {
         = 0;
         = 0;
        for(int i=0; i<.i++)
        {
            [i] = 0;  // start vector H
        }
        for(int i=0; i<.i++)
        {
            [i] = 0;
        }
        for(int i=0; i<.i++)
        {
            [i] = 0;
        }
        for(int i=0; i<[1].lengthi++)
        {
            [1][i] = 0;  // real index C = +1 because index array with 0.
        }
        for(int i=0; i<[3].lengthi++)
        {
            [3][i] = 0;
        }
        for(int i=0; i<.i++)
        {
            [i] = 0;
        }
        for(int i = 0; i < .i++)
        {
            [i] = 0;
        }
        System.arraycopy(, 0, [2], 0, .);
    }
    //  256 bitsblock modul -> (Sum + a mod (2^256))
    private void sumByteArray(byte[] in)
    {
        int carry = 0;
        for (int i = 0; i != .i++)
        {
            int sum = ([i] & 0xff) + (in[i] & 0xff) + carry;
            [i] = (byte)sum;
            carry = sum >>> 8;
        }
    }
    private void cpyBytesToShort(byte[] Sshort[] wS)
    {
        for(int i=0; i<S.length/2; i++)
        {
            wS[i] = (short)(((S[i*2+1]<<8)&0xFF00)|(S[i*2]&0xFF));
        }
    }
    private void cpyShortToBytes(short[] wSbyte[] S)
    {
        for(int i=0; i<S.length/2; i++) 
        {
            S[i*2 + 1] = (byte)(wS[i] >> 8);
            S[i*2] = (byte)wS[i];
        }
    }
   public int getByteLength() 
   {
      return 32;
   }
    public Memoable copy()
    {
        return new GOST3411Digest(this);
    }
    public void reset(Memoable other)
    {
        GOST3411Digest t = (GOST3411Digest)other;
        this. = t.sBox;
        .init(truenew ParametersWithSBox(null));
        reset();
        System.arraycopy(t.H, 0, this., 0, t.H.length);
        System.arraycopy(t.L, 0, this., 0, t.L.length);
        System.arraycopy(t.M, 0, this., 0, t.M.length);
        System.arraycopy(t.Sum, 0, this., 0, t.Sum.length);
        System.arraycopy(t.C[1], 0, this.[1], 0, t.C[1].length);
        System.arraycopy(t.C[2], 0, this.[2], 0, t.C[2].length);
        System.arraycopy(t.C[3], 0, this.[3], 0, t.C[3].length);
        System.arraycopy(t.xBuf, 0, this., 0, t.xBuf.length);
        this. = t.xBufOff;
        this. = t.byteCount;
    }
New to GrepCode? Check out our FAQ X