![JAR search and dependency download from the Maven repository](/logo.png)
nl.open.jwtdependency.org.bouncycastle.crypto.digests.GOST3411Digest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-jwt-nodependencies Show documentation
Show all versions of java-jwt-nodependencies Show documentation
This is a drop in replacement for the auth0 java-jwt library (see https://github.com/auth0/java-jwt). This jar makes sure there are no external dependencies (e.g. fasterXml, Apacha Commons) needed. This is useful when deploying to an application server (e.g. tomcat with Alfreso or Pega).
The newest version!
package org.bouncycastle.crypto.digests;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.ExtendedDigest;
import org.bouncycastle.crypto.engines.GOST28147Engine;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithSBox;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Memoable;
import org.bouncycastle.util.Pack;
/**
* implementation of GOST R 34.11-94
*/
public class GOST3411Digest
implements ExtendedDigest, Memoable
{
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()
{
sBox = GOST28147Engine.getSBox("D-A");
cipher.init(true, new ParametersWithSBox(null, sBox));
reset();
}
/**
* Constructor to allow use of a particular sbox with GOST28147
* @see GOST28147Engine#getSBox(String)
*/
public GOST3411Digest(byte[] sBoxParam)
{
sBox = Arrays.clone(sBoxParam);
cipher.init(true, new ParametersWithSBox(null, sBox));
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 DIGEST_LENGTH;
}
public void update(byte in)
{
xBuf[xBufOff++] = in;
if (xBufOff == xBuf.length)
{
sumByteArray(xBuf); // calc sum M
processBlock(xBuf, 0);
xBufOff = 0;
}
byteCount++;
}
public void update(byte[] in, int inOff, int len)
{
while ((xBufOff != 0) && (len > 0))
{
update(in[inOff]);
inOff++;
len--;
}
while (len > xBuf.length)
{
System.arraycopy(in, inOff, xBuf, 0, xBuf.length);
sumByteArray(xBuf); // calc sum M
processBlock(xBuf, 0);
inOff += xBuf.length;
len -= xBuf.length;
byteCount += xBuf.length;
}
// 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++)
{
K[4*k] = in[k];
K[1 + 4*k] = in[ 8 + k];
K[2 + 4*k] = in[16 + k];
K[3 + 4*k] = in[24 + k];
}
return K;
}
//A (x) = (x0 ^ x1) || x3 || x2 || x1
byte[] a = new byte[8];
private byte[] A(byte[] in)
{
for(int j=0; j<8; j++)
{
a[j]=(byte)(in[j] ^ in[j+8]);
}
System.arraycopy(in, 8, in, 0, 24);
System.arraycopy(a, 0, in, 24, 8);
return in;
}
//Encrypt function, ECB mode
private void E(byte[] key, byte[] s, int sOff, byte[] in, int inOff)
{
cipher.init(true, new KeyParameter(key));
cipher.processBlock(in, inOff, s, sOff);
}
// (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, wS);
w_S[15] = (short)(wS[0] ^ wS[1] ^ wS[2] ^ wS[3] ^ wS[12] ^ wS[15]);
System.arraycopy(wS, 1, w_S, 0, 15);
cpyShortToBytes(w_S, 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[] in, int inOff)
{
System.arraycopy(in, inOff, M, 0, 32);
//key step 1
// H = h3 || h2 || h1 || h0
// S = s3 || s2 || s1 || s0
System.arraycopy(H, 0, U, 0, 32);
System.arraycopy(M, 0, V, 0, 32);
for (int j=0; j<32; j++)
{
W[j] = (byte)(U[j]^V[j]);
}
// Encrypt gost28147-ECB
E(P(W), S, 0, H, 0); // s0 = EK0 [h0]
//keys step 2,3,4
for (int i=1; i<4; i++)
{
byte[] tmpA = A(U);
for (int j=0; j<32; j++)
{
U[j] = (byte)(tmpA[j] ^ C[i][j]);
}
V = A(A(V));
for (int j=0; j<32; j++)
{
W[j] = (byte)(U[j]^V[j]);
}
// Encrypt gost28147-ECB
E(P(W), S, i * 8, H, i * 8); // si = EKi [hi]
}
// x(M, H) = y61(H^y(M^y12(S)))
for(int n = 0; n < 12; n++)
{
fw(S);
}
for(int n = 0; n < 32; n++)
{
S[n] = (byte)(S[n] ^ M[n]);
}
fw(S);
for(int n = 0; n < 32; n++)
{
S[n] = (byte)(H[n] ^ S[n]);
}
for(int n = 0; n < 61; n++)
{
fw(S);
}
System.arraycopy(S, 0, H, 0, H.length);
}
private void finish()
{
Pack.longToLittleEndian(byteCount * 8, L, 0); // get length into L (byteCount * 8 = bitCount)
while (xBufOff != 0)
{
update((byte)0);
}
processBlock(L, 0);
processBlock(Sum, 0);
}
public int doFinal(
byte[] out,
int outOff)
{
finish();
System.arraycopy(H, 0, out, outOff, H.length);
reset();
return DIGEST_LENGTH;
}
/**
* 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()
{
byteCount = 0;
xBufOff = 0;
for(int i=0; i (Sum + a mod (2^256))
private void sumByteArray(byte[] in)
{
int carry = 0;
for (int i = 0; i != Sum.length; i++)
{
int sum = (Sum[i] & 0xff) + (in[i] & 0xff) + carry;
Sum[i] = (byte)sum;
carry = sum >>> 8;
}
}
private void cpyBytesToShort(byte[] S, short[] wS)
{
for(int i=0; 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.sBox = t.sBox;
cipher.init(true, new ParametersWithSBox(null, sBox));
reset();
System.arraycopy(t.H, 0, this.H, 0, t.H.length);
System.arraycopy(t.L, 0, this.L, 0, t.L.length);
System.arraycopy(t.M, 0, this.M, 0, t.M.length);
System.arraycopy(t.Sum, 0, this.Sum, 0, t.Sum.length);
System.arraycopy(t.C[1], 0, this.C[1], 0, t.C[1].length);
System.arraycopy(t.C[2], 0, this.C[2], 0, t.C[2].length);
System.arraycopy(t.C[3], 0, this.C[3], 0, t.C[3].length);
System.arraycopy(t.xBuf, 0, this.xBuf, 0, t.xBuf.length);
this.xBufOff = t.xBufOff;
this.byteCount = t.byteCount;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy