22
33import java .security .SecureRandom ;
44
5- import junit . framework . TestCase ;
5+ import org . bouncycastle . crypto . AsymmetricCipherKeyPair ;
66import org .bouncycastle .crypto .AsymmetricCipherKeyPairGenerator ;
77import org .bouncycastle .crypto .EncapsulatedSecretExtractor ;
88import org .bouncycastle .crypto .EncapsulatedSecretGenerator ;
9+ import org .bouncycastle .crypto .SecretWithEncapsulation ;
910import org .bouncycastle .crypto .digests .SHAKEDigest ;
1011import org .bouncycastle .crypto .params .AsymmetricKeyParameter ;
1112import org .bouncycastle .pqc .crypto .hqc .HQCKEMExtractor ;
1516import org .bouncycastle .pqc .crypto .hqc .HQCParameters ;
1617import org .bouncycastle .pqc .crypto .hqc .HQCPrivateKeyParameters ;
1718import org .bouncycastle .pqc .crypto .hqc .HQCPublicKeyParameters ;
19+ import org .bouncycastle .util .Arrays ;
20+ import org .junit .Assert ;
21+
22+ import junit .framework .TestCase ;
1823
1924public class HQCTest
2025 extends TestCase
2126{
22- public static void main (String [] args )
23- throws Exception
27+ private final SecureRandom RANDOM = new SecureRandom ();
28+
29+ public void testConsistencyHQC128 ()
30+ {
31+ implTestConsistency (HQCParameters .hqc128 );
32+ }
33+
34+ public void testConsistencyHQC192 ()
2435 {
25- HQCTest test = new HQCTest ();
26- test .testVectors ();
36+ implTestConsistency (HQCParameters .hqc192 );
2737 }
2838
29- @ Override
30- public String getName ()
39+ public void testConsistencyHQC256 ()
3140 {
32- return "HQC Test" ;
41+ implTestConsistency ( HQCParameters . hqc256 ) ;
3342 }
3443
3544 public void testVectors ()
@@ -49,7 +58,7 @@ public void testVectors()
4958 HQCParameters .hqc256
5059 };
5160
52- TestUtils .testTestVector (false , true , "pqc/crypto/hqc" , files , new TestUtils .KeyEncapsulationOperation ()
61+ TestUtils .testTestVector (true , true , "pqc/crypto/hqc" , files , new TestUtils .KeyEncapsulationOperation ()
5362 {
5463 int sessionKeySize = 0 ;
5564
@@ -102,20 +111,48 @@ public int getSessionKeySize()
102111 });
103112 }
104113
114+ private void implTestConsistency (HQCParameters parameters )
115+ {
116+ HQCKeyPairGenerator kpg = new HQCKeyPairGenerator ();
117+ kpg .init (new HQCKeyGenerationParameters (RANDOM , parameters ));
118+
119+ for (int i = 0 ; i < 10 ; ++i )
120+ {
121+ AsymmetricCipherKeyPair kp = kpg .generateKeyPair ();
122+
123+ for (int j = 0 ; j < 10 ; ++j )
124+ {
125+ HQCKEMGenerator generator = new HQCKEMGenerator (RANDOM );
126+ SecretWithEncapsulation encapsulated = generator .generateEncapsulated (kp .getPublic ());
127+ byte [] encapSecret = encapsulated .getSecret ();
128+ byte [] encapsulation = encapsulated .getEncapsulation ();
129+ Assert .assertEquals (parameters .getSessionKeySize () / 8 , encapSecret .length );
130+ Assert .assertEquals (parameters .getEncapsulationLength (), encapsulation .length );
131+
132+ HQCKEMExtractor extractor = new HQCKEMExtractor ((HQCPrivateKeyParameters )kp .getPrivate ());
133+ byte [] decapSecret = extractor .extractSecret (encapsulation );
134+ if (!Arrays .areEqual (encapSecret , decapSecret ))
135+ {
136+ Assert .fail ("Consistency " + parameters .getName () + " #" + i + "[" + j + "]" );
137+ }
138+ }
139+ }
140+ }
141+
105142 private static class Shake256SecureRandom
106143 extends SecureRandom
107144 {
108- private final SHAKEDigest digest = new SHAKEDigest (256 );
145+ private final SHAKEDigest xof = new SHAKEDigest (256 );
109146
110147 Shake256SecureRandom (byte [] seed )
111148 {
112- digest .update (seed , 0 , seed .length );
113- digest .update ((byte ) 0 );
149+ xof .update (seed , 0 , seed .length );
150+ xof .update ((byte ) 0 );
114151 }
115152
116153 public void nextBytes (byte [] bytes )
117154 {
118- digest .doOutput (bytes , 0 , bytes .length );
155+ xof .doOutput (bytes , 0 , bytes .length );
119156 }
120157 }
121158}
0 commit comments