Skip to content

Commit 0cdc08a

Browse files
author
gefeili
committed
Update RomulusDigest
1 parent aa70711 commit 0cdc08a

File tree

2 files changed

+27
-148
lines changed

2 files changed

+27
-148
lines changed

core/src/main/java/org/bouncycastle/crypto/digests/RomulusDigest.java

Lines changed: 23 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package org.bouncycastle.crypto.digests;
22

3-
import java.io.ByteArrayOutputStream;
4-
5-
import org.bouncycastle.crypto.DataLengthException;
6-
import org.bouncycastle.crypto.Digest;
73
import org.bouncycastle.util.Arrays;
84

95
/**
@@ -13,10 +9,10 @@
139
*/
1410

1511
public class RomulusDigest
16-
implements Digest
12+
extends BufferBaseDigest
1713
{
18-
private final int CRYPTO_BYTES = 32;
19-
14+
byte[] h = new byte[16];
15+
byte[] g = new byte[16];
2016
/*
2117
* This file includes only the encryption function of SKINNY-128-384+ as required by Romulus-v1.3
2218
*/
@@ -69,6 +65,12 @@ public class RomulusDigest
6965
(byte)0x16, (byte)0x2C, (byte)0x18, (byte)0x30, (byte)0x21, (byte)0x02, (byte)0x05, (byte)0x0B, (byte)0x17, (byte)0x2E,
7066
(byte)0x1C, (byte)0x38, (byte)0x31, (byte)0x23, (byte)0x06, (byte)0x0D, (byte)0x1B, (byte)0x36, (byte)0x2D, (byte)0x1A};
7167

68+
public RomulusDigest()
69+
{
70+
super(ProcessingBufferType.Immediate, 32);
71+
DigestSize = 32;
72+
}
73+
7274
void skinny_128_384_plus_enc(byte[] input, byte[] userkey)
7375
{
7476
byte[][] state = new byte[4][4];
@@ -212,75 +214,36 @@ void ipad_256(byte[] m, int inOff, byte[] mp, int len8)
212214
mp[31] = (byte)(len8 & 0x1f);
213215
}
214216

215-
private void crypto_hash(byte[] out, int outOff, byte[] input, int inlen)
216-
{
217-
byte[] h = new byte[16];
218-
byte[] g = new byte[16];
219-
int mlen;
220-
byte[] p = new byte[32];
221-
mlen = inlen;
222-
int inOff = 0;
223-
while (mlen >= 32)
224-
{ // Normal loop
225-
hirose_128_128_256(h, g, input, inOff);
226-
inOff += 32;
227-
mlen -= 32;
228-
}
229-
// Partial block (or in case there is no partial block we add a 0^2n block
230-
ipad_256(input, inOff, p, mlen);
231-
h[0] ^= 2;
232-
hirose_128_128_256(h, g, p, 0);
233-
// Assign the output tag
234-
System.arraycopy(h, 0, out, outOff, 16);
235-
System.arraycopy(g, 0, out, 16 + outOff, 16);
236-
}
237-
238-
private final ByteArrayOutputStream message = new ByteArrayOutputStream();
239-
240217
@Override
241218
public String getAlgorithmName()
242219
{
243220
return "Romulus Hash";
244221
}
245222

246223
@Override
247-
public int getDigestSize()
248-
{
249-
return CRYPTO_BYTES;
250-
}
251-
252-
@Override
253-
public void update(byte input)
224+
protected void processBytes(byte[] input, int inOff)
254225
{
255-
message.write(input);
226+
hirose_128_128_256(h, g, input, inOff);
256227
}
257228

258229
@Override
259-
public void update(byte[] input, int inOff, int len)
230+
protected void finish(byte[] output, int outOff)
260231
{
261-
if (inOff + len > input.length)
262-
{
263-
throw new DataLengthException(" input buffer too short");
264-
}
265-
message.write(input, inOff, len);
266-
}
267-
268-
@Override
269-
public int doFinal(byte[] output, int outOff)
270-
{
271-
if (outOff + 32 > output.length)
272-
{
273-
throw new DataLengthException(" output buffer too short");
274-
}
275-
byte[] input = message.toByteArray();
276-
int inlen = input.length;
277-
crypto_hash(output, outOff, input, inlen);
278-
return CRYPTO_BYTES;
232+
byte[] p = new byte[32];
233+
ipad_256(m_buf, 0, p, m_bufPos);
234+
h[0] ^= 2;
235+
hirose_128_128_256(h, g, p, 0);
236+
// Assign the output tag
237+
System.arraycopy(h, 0, output, outOff, 16);
238+
System.arraycopy(g, 0, output, 16 + outOff, 16);
279239
}
280240

281241
@Override
282242
public void reset()
283243
{
284-
message.reset();
244+
Arrays.clear(m_buf);
245+
m_bufPos = 0;
246+
Arrays.clear(h);
247+
Arrays.clear(g);
285248
}
286249
}

core/src/test/java/org/bouncycastle/crypto/test/RomulusTest.java

Lines changed: 4 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
11
package org.bouncycastle.crypto.test;
22

3-
import java.io.BufferedReader;
4-
import java.io.InputStream;
5-
import java.io.InputStreamReader;
6-
import java.util.HashMap;
7-
83
import org.bouncycastle.crypto.CipherParameters;
9-
import org.bouncycastle.crypto.DataLengthException;
10-
import org.bouncycastle.crypto.Digest;
114
import org.bouncycastle.crypto.digests.RomulusDigest;
125
import org.bouncycastle.crypto.engines.RomulusEngine;
136
import org.bouncycastle.crypto.modes.AEADCipher;
147
import org.bouncycastle.crypto.params.KeyParameter;
158
import org.bouncycastle.crypto.params.ParametersWithIV;
16-
import org.bouncycastle.util.encoders.Hex;
179
import org.bouncycastle.util.test.SimpleTest;
1810

1911
public class RomulusTest
@@ -27,6 +19,10 @@ public String getName()
2719
public void performTest()
2820
throws Exception
2921
{
22+
DigestTest.implTestVectorsDigest(this, new RomulusDigest(), "crypto/romulus", "LWC_HASH_KAT_256.txt");
23+
DigestTest.checkDigestReset(this, new RomulusDigest());
24+
DigestTest.implTestExceptionsAndParametersDigest(this, new RomulusDigest(), 32);
25+
3026
CipherTest.implTestVectorsEngine(new RomulusEngine(RomulusEngine.RomulusParameters.RomulusM), "crypto/romulus", "m_LWC_AEAD_KAT_128_128.txt", this);
3127
CipherTest.implTestVectorsEngine(new RomulusEngine(RomulusEngine.RomulusParameters.RomulusT), "crypto/romulus", "t_LWC_AEAD_KAT_128_128.txt", this);
3228
CipherTest.implTestVectorsEngine(new RomulusEngine(RomulusEngine.RomulusParameters.RomulusN), "crypto/romulus", "n_LWC_AEAD_KAT_128_128.txt", this);
@@ -154,90 +150,10 @@ private void implTestParametersEngine(RomulusEngine cipher, int keySize, int ivS
154150
}
155151
}
156152

157-
158-
private void testVectorsHash()
159-
throws Exception
160-
{
161-
RomulusDigest Romulus = new RomulusDigest();
162-
InputStream src = RomulusTest.class.getResourceAsStream("/org/bouncycastle/crypto/test/romulus/LWC_HASH_KAT_256.txt");
163-
BufferedReader bin = new BufferedReader(new InputStreamReader(src));
164-
String line;
165-
byte[] ptByte, adByte;
166-
byte[] rv;
167-
HashMap<String, String> map = new HashMap<String, String>();
168-
while ((line = bin.readLine()) != null)
169-
{
170-
int a = line.indexOf('=');
171-
if (a < 0)
172-
{
173-
// if (!map.get("Count").equals("3"))
174-
// {
175-
// continue;
176-
// }
177-
Romulus.reset();
178-
ptByte = Hex.decode((String)map.get("Msg"));
179-
Romulus.update(ptByte, 0, ptByte.length);
180-
byte[] hash = new byte[Romulus.getDigestSize()];
181-
Romulus.doFinal(hash, 0);
182-
if (!areEqual(hash, Hex.decode((String)map.get("MD"))))
183-
{
184-
mismatch("Keystream " + map.get("Count"), (String)map.get("MD"), hash);
185-
}
186-
// else
187-
// {
188-
// System.out.println("Keystream " + map.get("Count") + " pass");
189-
// }
190-
map.clear();
191-
Romulus.reset();
192-
}
193-
else
194-
{
195-
map.put(line.substring(0, a).trim(), line.substring(a + 1).trim());
196-
}
197-
}
198-
System.out.println("Romulus Hash pass");
199-
}
200-
201-
202-
private void testExceptions(Digest digest, int digestsize)
203-
{
204-
if (digest.getDigestSize() != digestsize)
205-
{
206-
fail(digest.getAlgorithmName() + ": digest size is not correct");
207-
}
208-
209-
try
210-
{
211-
digest.update(new byte[1], 1, 1);
212-
fail(digest.getAlgorithmName() + ": input for update is too short");
213-
}
214-
catch (DataLengthException e)
215-
{
216-
//expected
217-
}
218-
try
219-
{
220-
digest.doFinal(new byte[digest.getDigestSize() - 1], 2);
221-
fail(digest.getAlgorithmName() + ": output for dofinal is too short");
222-
}
223-
catch (DataLengthException e)
224-
{
225-
//expected
226-
}
227-
System.out.println(digest.getAlgorithmName() + " test Exceptions pass");
228-
}
229-
230-
231-
private void mismatch(String name, String expected, byte[] found)
232-
{
233-
fail("mismatch on " + name, expected, new String(Hex.encode(found)));
234-
}
235-
236153
public static void main(String[] args)
237154
{
238155
runTest(new RomulusTest());
239156
}
240-
241157
}
242158

243159

0 commit comments

Comments
 (0)