Skip to content

Commit 3db1328

Browse files
author
royb
committed
Added vector test for hpke
1 parent 2a61791 commit 3db1328

File tree

3 files changed

+128697
-104
lines changed

3 files changed

+128697
-104
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
package org.bouncycastle.crypto.test;
2+
3+
import junit.framework.TestCase;
4+
import org.apache.commons.math3.analysis.function.Exp;
5+
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
6+
import org.bouncycastle.crypto.hpke.Context;
7+
import org.bouncycastle.crypto.hpke.HPKE;
8+
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
9+
import org.bouncycastle.crypto.params.KeyParameter;
10+
import org.bouncycastle.pqc.crypto.test.SABERVectorTest;
11+
import org.bouncycastle.util.Arrays;
12+
import org.bouncycastle.util.encoders.Hex;
13+
14+
import java.io.BufferedReader;
15+
import java.io.InputStream;
16+
import java.io.InputStreamReader;
17+
import java.util.ArrayList;
18+
import java.util.HashMap;
19+
20+
public class HPKETestVectors
21+
extends TestCase
22+
{
23+
class Encryption
24+
{
25+
byte[] aad;
26+
byte[] ct;
27+
28+
byte[] nonce;
29+
30+
byte[] pt;
31+
32+
public Encryption(byte[] aad, byte[] ct, byte[] nonce, byte[] pt)
33+
{
34+
this.aad = aad;
35+
this.ct = ct;
36+
this.nonce = nonce;
37+
this.pt = pt;
38+
}
39+
}
40+
41+
class Export
42+
{
43+
byte[] exporter_context;
44+
int L;
45+
byte[] exported_value;
46+
47+
public Export(byte[] exporter_context, int l, byte[] exported_value)
48+
{
49+
this.exporter_context = exporter_context;
50+
L = l;
51+
this.exported_value = exported_value;
52+
}
53+
}
54+
55+
public void testVectors() throws Exception
56+
{
57+
InputStream src = HPKETestVectors.class.getResourceAsStream("/org/bouncycastle/crypto/test/hpke.txt");
58+
BufferedReader bin = new BufferedReader(new InputStreamReader(src));
59+
HashMap<String, String> buf = new HashMap<String, String>();
60+
HashMap<String, String> bufEnc = new HashMap<String, String>();
61+
HashMap<String, String> bufExp = new HashMap<String, String>();
62+
ArrayList<Encryption> encryptions = new ArrayList<Encryption>();
63+
ArrayList<Export> exports = new ArrayList<Export>();
64+
String line = null;
65+
66+
while ((line = bin.readLine()) != null)
67+
{
68+
line = line.trim();
69+
70+
if (line.startsWith("#"))
71+
{
72+
continue;
73+
}
74+
if (line.length() == 0)
75+
{
76+
if (buf.size() > 0)
77+
{
78+
String count = (String) buf.get("count");
79+
System.out.println("test case: " + count);
80+
81+
byte mode = Byte.parseByte((String) buf.get("mode"));
82+
short kem_id = (short) Integer.parseInt((String) buf.get("kem_id"));
83+
short kdf_id = (short) Integer.parseInt((String) buf.get("kdf_id"));
84+
short aead_id = (short) Integer.parseInt((String) buf.get("aead_id"));
85+
byte[] info = Hex.decode((String) buf.get("info"));
86+
byte[] ikmR = Hex.decode((String) buf.get("ikmR"));
87+
byte[] ikmE = Hex.decode((String) buf.get("ikmE"));
88+
byte[] ikmS = null;
89+
byte[] skRm = Hex.decode((String) buf.get("skRm"));
90+
byte[] skSm = null;
91+
byte[] skEm = Hex.decode((String) buf.get("skEm"));
92+
byte[] pkRm = Hex.decode((String) buf.get("pkRm"));
93+
byte[] pkSm = null;
94+
byte[] pkEm = Hex.decode((String) buf.get("pkEm"));
95+
byte[] psk = null;
96+
byte[] psk_id = null;
97+
byte[] enc = Hex.decode((String) buf.get("enc"));
98+
byte[] shared_secret = Hex.decode((String) buf.get("shared_secret"));
99+
byte[] key_schedule_context = Hex.decode((String) buf.get("key_schedule_context"));
100+
byte[] secret = Hex.decode((String) buf.get("secret"));
101+
byte[] key = Hex.decode((String) buf.get("key"));
102+
byte[] base_nonce = Hex.decode((String) buf.get("base_nonce"));
103+
byte[] exporter_secret = Hex.decode((String) buf.get("exporter_secret"));
104+
if(mode == 2 || mode == 3)
105+
{
106+
pkSm = Hex.decode((String) buf.get("pkSm"));
107+
ikmS = Hex.decode((String) buf.get("ikmS"));
108+
skSm = Hex.decode((String) buf.get("skSm"));
109+
}
110+
if(mode == 1 || mode == 3)
111+
{
112+
psk = Hex.decode((String) buf.get("psk"));
113+
psk_id = Hex.decode((String) buf.get("psk_id"));
114+
}
115+
116+
117+
HPKE hpke = new HPKE(mode, kem_id, kdf_id, aead_id);
118+
119+
// Testing AEAD
120+
Context c;
121+
for (Encryption encryption : encryptions)
122+
{
123+
hpke.AEAD(key, encryption.nonce);
124+
assertTrue(Arrays.areEqual(hpke.aead.Seal(encryption.aad, encryption.pt), encryption.ct));
125+
}
126+
127+
// Testing HPKE
128+
AsymmetricCipherKeyPair receiver = hpke.dhkem.DeserializePrivateKey(skRm, pkRm);
129+
AsymmetricKeyParameter sender = null;
130+
Context ctx;
131+
byte[] message;
132+
133+
switch (mode)
134+
{
135+
case 0:
136+
ctx = hpke.SetupBaseR(pkEm, receiver, info);
137+
break;
138+
case 1:
139+
ctx = hpke.SetupPSKR(pkEm, receiver, info, psk, psk_id);
140+
break;
141+
case 2:
142+
sender = hpke.dhkem.DeserializePublicKey(pkSm);
143+
ctx = hpke.SetupAuthR(pkEm, receiver, info, sender);
144+
break;
145+
case 3:
146+
sender = hpke.dhkem.DeserializePublicKey(pkSm);
147+
ctx = hpke.SetupAuthPSKR(pkEm, receiver, info, psk, psk_id, sender);
148+
break;
149+
default:
150+
throw new Exception("invalid mode");
151+
}
152+
153+
byte[] got;
154+
for (int i = 0; i < encryptions.size(); i++)
155+
{
156+
Encryption encryption = encryptions.get(i);
157+
// testing one shot api
158+
if (i == 0)
159+
{
160+
message = hpke.Open(pkEm, receiver, info, encryption.aad, encryption.ct, psk, psk_id, sender);
161+
assertTrue(Arrays.areEqual(message, encryption.pt));
162+
}
163+
message = ctx.aead.Open(encryption.aad, encryption.ct);
164+
assertTrue(Arrays.areEqual(message, encryption.pt));
165+
}
166+
for (Export export : exports)
167+
{
168+
got = ctx.Export(export.exporter_context, export.L);
169+
assertTrue(Arrays.areEqual(got, export.exported_value));
170+
}
171+
172+
}
173+
buf.clear();
174+
encryptions.clear();
175+
exports.clear();
176+
177+
continue;
178+
}
179+
180+
int a = line.indexOf("=");
181+
if (a > -1)
182+
{
183+
buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim());
184+
}
185+
186+
a = line.indexOf("encryptionsSTART");
187+
if (a > -1)
188+
{
189+
while((line = bin.readLine()) != null)
190+
{
191+
line = line.trim();
192+
193+
if (line.equals("<"))
194+
{
195+
if (buf.size() > 0)
196+
{
197+
byte[] aad = Hex.decode((String)bufEnc.get("aad"));
198+
byte[] ct = Hex.decode((String)bufEnc.get("ct"));
199+
byte[] nonce = Hex.decode((String)bufEnc.get("nonce"));
200+
byte[] pt = Hex.decode((String)bufEnc.get("pt"));
201+
encryptions.add(new Encryption(aad, ct, nonce, pt));
202+
bufEnc.clear();
203+
}
204+
}
205+
206+
a = line.indexOf("=");
207+
208+
if (a > -1)
209+
{
210+
bufEnc.put(line.substring(0, a).trim(), line.substring(a + 1).trim());
211+
}
212+
213+
if(line.equals("encryptionsSTOP"))
214+
{
215+
break;
216+
}
217+
}
218+
}
219+
a = line.indexOf("exportsSTART");
220+
if (a > -1)
221+
{
222+
while((line = bin.readLine()) != null)
223+
{
224+
line = line.trim();
225+
226+
if (line.equals("<"))
227+
{
228+
if (buf.size() > 0)
229+
{
230+
byte[] exporter_context = Hex.decode((String)bufExp.get("exporter_context"));
231+
int L = Integer.parseInt(((String)bufExp.get("L")));
232+
byte[] exported_value = Hex.decode((String)bufExp.get("exported_value"));
233+
exports.add(new Export(exporter_context, L, exported_value));
234+
bufExp.clear();
235+
}
236+
}
237+
238+
a = line.indexOf("=");
239+
240+
if (a > -1)
241+
{
242+
bufExp.put(line.substring(0, a).trim(), line.substring(a + 1).trim());
243+
}
244+
245+
if(line.equals("exportsSTOP"))
246+
{
247+
break;
248+
}
249+
}
250+
}
251+
252+
}
253+
254+
255+
}
256+
}

0 commit comments

Comments
 (0)