Skip to content

Commit b85eff9

Browse files
committed
added backwards compatibility for Dilithium and Falcon public keys.
updated Kyber public key to follow draft RFC.
1 parent 38c8fee commit b85eff9

File tree

6 files changed

+84
-22
lines changed

6 files changed

+84
-22
lines changed

core/src/main/java/org/bouncycastle/pqc/crypto/crystals/dilithium/DilithiumPublicKeyParameters.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ public byte[] getEncoded()
2323
return Arrays.concatenate(rho, t1);
2424
}
2525

26+
public DilithiumPublicKeyParameters(DilithiumParameters params, byte[] encoding)
27+
{
28+
super(false, params);
29+
this.rho = Arrays.copyOfRange(encoding, 0, DilithiumEngine.SeedBytes);
30+
this.t1 = Arrays.copyOfRange(encoding, DilithiumEngine.SeedBytes, encoding.length);
31+
}
32+
2633
public DilithiumPublicKeyParameters(DilithiumParameters params, byte[] rho, byte[] t1)
2734
{
2835
super(false, params);

core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberKEMGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recip
2626
KyberPublicKeyParameters key = (KyberPublicKeyParameters)recipientKey;
2727
KyberEngine engine = key.getParameters().getEngine();
2828
engine.init(sr);
29-
byte[][] kemEncrypt = engine.kemEncrypt(key.publicKey);
29+
byte[][] kemEncrypt = engine.kemEncrypt(key.getPublicKey());
3030
return new KyberKEMGenerator.SecretWithEncapsulationImpl(kemEncrypt[0], kemEncrypt[1]);
3131
}
3232

core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberPublicKeyParameters.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,40 @@
55
public class KyberPublicKeyParameters
66
extends KyberKeyParameters
77
{
8-
final byte[] publicKey;
8+
final byte[] t;
9+
final byte[] rho;
910

1011
public byte[] getPublicKey()
1112
{
12-
return Arrays.clone(publicKey);
13+
return Arrays.concatenate(t, rho);
1314
}
1415

1516
public byte[] getEncoded()
1617
{
1718
return getPublicKey();
1819
}
1920

20-
public KyberPublicKeyParameters(KyberParameters params, byte[] publicKey)
21+
public KyberPublicKeyParameters(KyberParameters params, byte[] t, byte[] rho)
2122
{
2223
super(false, params);
23-
this.publicKey = Arrays.clone(publicKey);
24+
this.t = Arrays.clone(t);
25+
this.rho = Arrays.clone(rho);
26+
}
27+
28+
public KyberPublicKeyParameters(KyberParameters params, byte[] encoding)
29+
{
30+
super(false, params);
31+
this.t = Arrays.copyOfRange(encoding,0, encoding.length - KyberEngine.KyberSymBytes);
32+
this.rho = Arrays.copyOfRange(encoding, encoding.length - KyberEngine.KyberSymBytes, encoding.length);
33+
}
34+
35+
public byte[] getT()
36+
{
37+
return Arrays.clone(t);
38+
}
39+
40+
public byte[] getRho()
41+
{
42+
return Arrays.clone(rho);
2443
}
2544
}

core/src/main/java/org/bouncycastle/pqc/crypto/falcon/FalconPublicKeyParameters.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
public class FalconPublicKeyParameters
66
extends FalconKeyParameters
77
{
8-
98
private byte[] H;
109

1110
public FalconPublicKeyParameters(FalconParameters parameters, byte[] H)

core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -470,11 +470,26 @@ private static class FalconConverter
470470
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
471471
throws IOException
472472
{
473-
byte[] keyEnc = ASN1OctetString.getInstance(ASN1Sequence.getInstance(keyInfo.parsePublicKey()).getObjectAt(0)).getOctets();
474-
475473
FalconParameters falconParams = Utils.falconParamsLookup(keyInfo.getAlgorithm().getAlgorithm());
476474

477-
return new FalconPublicKeyParameters(falconParams, keyEnc);
475+
ASN1Primitive obj = keyInfo.parsePublicKey();
476+
if (obj instanceof ASN1Sequence)
477+
{
478+
byte[] keyEnc = ASN1OctetString.getInstance(ASN1Sequence.getInstance(obj).getObjectAt(0)).getOctets();
479+
480+
return new FalconPublicKeyParameters(falconParams, keyEnc);
481+
}
482+
else
483+
{
484+
// header byte + h
485+
byte[] keyEnc = ASN1OctetString.getInstance(obj).getOctets();
486+
487+
if (keyEnc[0] != (byte)(0x00 + falconParams.getLogN()))
488+
{
489+
throw new IllegalArgumentException("byte[] enc of Falcon h value not tagged correctly");
490+
}
491+
return new FalconPublicKeyParameters(falconParams, Arrays.copyOfRange(keyEnc, 1, keyEnc.length));
492+
}
478493
}
479494
}
480495

@@ -484,11 +499,23 @@ private static class KyberConverter
484499
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
485500
throws IOException
486501
{
487-
byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets();
502+
KyberParameters kyberParameters = Utils.kyberParamsLookup(keyInfo.getAlgorithm().getAlgorithm());
488503

489-
KyberParameters kyberParams = Utils.kyberParamsLookup(keyInfo.getAlgorithm().getAlgorithm());
504+
ASN1Primitive obj = keyInfo.parsePublicKey();
505+
if (obj instanceof ASN1Sequence)
506+
{
507+
ASN1Sequence keySeq = ASN1Sequence.getInstance(obj);
490508

491-
return new KyberPublicKeyParameters(kyberParams, keyEnc);
509+
return new KyberPublicKeyParameters(kyberParameters,
510+
ASN1OctetString.getInstance(keySeq.getObjectAt(0)).getOctets(),
511+
ASN1OctetString.getInstance(keySeq.getObjectAt(1)).getOctets());
512+
}
513+
else
514+
{
515+
byte[] encKey = ASN1OctetString.getInstance(obj).getOctets();
516+
517+
return new KyberPublicKeyParameters(kyberParameters, encKey);
518+
}
492519
}
493520
}
494521

@@ -526,13 +553,23 @@ private static class DilithiumConverter
526553
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
527554
throws IOException
528555
{
529-
ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.parsePublicKey());
530-
531556
DilithiumParameters dilithiumParams = Utils.dilithiumParamsLookup(keyInfo.getAlgorithm().getAlgorithm());
532557

533-
return new DilithiumPublicKeyParameters(dilithiumParams,
534-
ASN1OctetString.getInstance(keySeq.getObjectAt(0)).getOctets(),
535-
ASN1OctetString.getInstance(keySeq.getObjectAt(1)).getOctets());
558+
ASN1Primitive obj = keyInfo.parsePublicKey();
559+
if (obj instanceof ASN1Sequence)
560+
{
561+
ASN1Sequence keySeq = ASN1Sequence.getInstance(obj);
562+
563+
return new DilithiumPublicKeyParameters(dilithiumParams,
564+
ASN1OctetString.getInstance(keySeq.getObjectAt(0)).getOctets(),
565+
ASN1OctetString.getInstance(keySeq.getObjectAt(1)).getOctets());
566+
}
567+
else
568+
{
569+
byte[] encKey = ASN1OctetString.getInstance(obj).getOctets();
570+
571+
return new DilithiumPublicKeyParameters(dilithiumParams, encKey);
572+
}
536573
}
537574
}
538575

core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,7 @@ else if (publicKey instanceof SABERPublicKeyParameters)
188188
byte[] encoding = params.getEncoded();
189189

190190
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.saberOidLookup(params.getParameters()));
191-
192-
// https://datatracker.ietf.org/doc/draft-uni-qsckeys/
191+
193192
return new SubjectPublicKeyInfo(algorithmIdentifier, new DERSequence(new DEROctetString(encoding)));
194193
}
195194
else if (publicKey instanceof PicnicPublicKeyParameters)
@@ -231,10 +230,11 @@ else if (publicKey instanceof KyberPublicKeyParameters)
231230
{
232231
KyberPublicKeyParameters params = (KyberPublicKeyParameters)publicKey;
233232

234-
byte[] encoding = params.getEncoded();
235233
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.kyberOidLookup(params.getParameters()));
236-
237-
return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding));
234+
ASN1EncodableVector v = new ASN1EncodableVector();
235+
v.add(new DEROctetString(params.getT()));
236+
v.add(new DEROctetString(params.getRho()));
237+
return new SubjectPublicKeyInfo(algorithmIdentifier, new DERSequence(v));
238238
}
239239
else if (publicKey instanceof NTRULPRimePublicKeyParameters)
240240
{

0 commit comments

Comments
 (0)