Skip to content

Commit d38e26d

Browse files
author
gefeili
committed
Merge branch 'main' into 1836-openpgp-unpacking-time
2 parents ed00ff2 + 4580acc commit d38e26d

File tree

48 files changed

+968
-290
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+968
-290
lines changed

core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSPrivateKeyParameters.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,23 @@ public class HSSPrivateKeyParameters
2626

2727
private HSSPublicKeyParameters publicKey;
2828

29+
public HSSPrivateKeyParameters(LMSPrivateKeyParameters key, long index, long indexLimit)
30+
{
31+
super(true);
32+
33+
this.l = 1;
34+
this.keys = Collections.singletonList(key);
35+
this.sig = Collections.emptyList();
36+
this.index = index;
37+
this.indexLimit = indexLimit;
38+
this.isShard = false;
39+
40+
//
41+
// Correct Intermediate LMS values will be constructed during reset to index.
42+
//
43+
resetKeyToIndex();
44+
}
45+
2946
public HSSPrivateKeyParameters(int l, List<LMSPrivateKeyParameters> keys, List<LMSSignature> sig, long index, long indexLimit)
3047
{
3148
super(true);
@@ -104,7 +121,16 @@ else if (src instanceof byte[])
104121
try // 1.5 / 1.6 compatibility
105122
{
106123
in = new DataInputStream(new ByteArrayInputStream((byte[])src));
107-
return getInstance(in);
124+
try
125+
{
126+
return getInstance(in);
127+
}
128+
catch (Exception e)
129+
{
130+
// old style single LMS key.
131+
LMSPrivateKeyParameters lmsKey = LMSPrivateKeyParameters.getInstance(src);
132+
return new HSSPrivateKeyParameters(lmsKey, lmsKey.getIndex(), lmsKey.getIndex() + lmsKey.getUsagesRemaining());
133+
}
108134
}
109135
finally
110136
{

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

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.bouncycastle.pqc.crypto.util;
22

3-
import java.io.ByteArrayInputStream;
43
import java.io.IOException;
54
import java.io.InputStream;
65

@@ -12,7 +11,6 @@
1211
import org.bouncycastle.asn1.ASN1OctetString;
1312
import org.bouncycastle.asn1.ASN1Primitive;
1413
import org.bouncycastle.asn1.ASN1Sequence;
15-
import org.bouncycastle.asn1.BERTags;
1614
import org.bouncycastle.asn1.DEROctetString;
1715
import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
1816
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
@@ -45,7 +43,6 @@
4543
import org.bouncycastle.pqc.crypto.hqc.HQCParameters;
4644
import org.bouncycastle.pqc.crypto.hqc.HQCPrivateKeyParameters;
4745
import org.bouncycastle.pqc.crypto.lms.HSSPrivateKeyParameters;
48-
import org.bouncycastle.pqc.crypto.lms.LMSPrivateKeyParameters;
4946
import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters;
5047
import org.bouncycastle.pqc.crypto.mldsa.MLDSAPrivateKeyParameters;
5148
import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters;
@@ -156,29 +153,17 @@ else if (algOID.equals(PQCObjectIdentifiers.newHope))
156153
}
157154
else if (algOID.equals(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig))
158155
{
159-
byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets();
156+
ASN1OctetString lmsKey = parseOctetString(keyInfo.getPrivateKey(), 64);
157+
byte[] keyEnc = lmsKey.getOctets();
160158
ASN1BitString pubKey = keyInfo.getPublicKeyData();
161159

162-
if (Pack.bigEndianToInt(keyEnc, 0) == 1)
160+
if (pubKey != null)
163161
{
164-
if (pubKey != null)
165-
{
166-
byte[] pubEnc = pubKey.getOctets();
162+
byte[] pubEnc = pubKey.getOctets();
167163

168-
return LMSPrivateKeyParameters.getInstance(Arrays.copyOfRange(keyEnc, 4, keyEnc.length), Arrays.copyOfRange(pubEnc, 4, pubEnc.length));
169-
}
170-
return LMSPrivateKeyParameters.getInstance(Arrays.copyOfRange(keyEnc, 4, keyEnc.length));
171-
}
172-
else
173-
{
174-
if (pubKey != null)
175-
{
176-
byte[] pubEnc = pubKey.getOctets();
177-
178-
return HSSPrivateKeyParameters.getInstance(Arrays.copyOfRange(keyEnc, 4, keyEnc.length), pubEnc);
179-
}
180-
return HSSPrivateKeyParameters.getInstance(Arrays.copyOfRange(keyEnc, 4, keyEnc.length));
164+
return HSSPrivateKeyParameters.getInstance(Arrays.copyOfRange(keyEnc, 4, keyEnc.length), pubEnc);
181165
}
166+
return HSSPrivateKeyParameters.getInstance(Arrays.copyOfRange(keyEnc, 4, keyEnc.length));
182167
}
183168
else if (algOID.on(BCObjectIdentifiers.sphincsPlus) || algOID.on(BCObjectIdentifiers.sphincsPlus_interop))
184169
{
@@ -466,6 +451,7 @@ else if (algOID.equals(PQCObjectIdentifiers.mcElieceCca2))
466451
* So it seems for the new PQC algorithms, there's a couple of approaches to what goes in the OCTET STRING
467452
*/
468453
private static ASN1OctetString parseOctetString(ASN1OctetString octStr, int expectedLength)
454+
throws IOException
469455
{
470456
byte[] data = octStr.getOctets();
471457
//
@@ -478,37 +464,15 @@ private static ASN1OctetString parseOctetString(ASN1OctetString octStr, int expe
478464

479465
//
480466
// possible internal OCTET STRING, possibly long form with or without the internal OCTET STRING
481-
ByteArrayInputStream bIn = new ByteArrayInputStream(data);
482-
483-
int tag = bIn.read();
484-
int len = readLen(bIn);
485-
if (tag == BERTags.OCTET_STRING)
467+
data = Utils.readOctetString(data);
468+
if (data != null)
486469
{
487-
if (len == bIn.available())
488-
{
489-
return ASN1OctetString.getInstance(data);
490-
}
470+
return new DEROctetString(data);
491471
}
492472

493473
return octStr;
494474
}
495-
496-
private static int readLen(ByteArrayInputStream bIn)
497-
{
498-
int length = bIn.read();
499-
if (length != (length & 0x7f))
500-
{
501-
int count = length & 0x7f;
502-
length = 0;
503-
while (count-- != 0)
504-
{
505-
length = (length << 8) + bIn.read();
506-
}
507-
}
508-
509-
return length;
510-
}
511-
475+
512476
private static short[] convert(byte[] octets)
513477
{
514478
short[] rv = new short[octets.length / 2];

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

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import org.bouncycastle.pqc.crypto.hqc.HQCParameters;
4040
import org.bouncycastle.pqc.crypto.hqc.HQCPublicKeyParameters;
4141
import org.bouncycastle.pqc.crypto.lms.HSSPublicKeyParameters;
42-
import org.bouncycastle.pqc.crypto.lms.LMSPublicKeyParameters;
42+
import org.bouncycastle.pqc.crypto.lms.LMSKeyParameters;
4343
import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters;
4444
import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters;
4545
import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters;
@@ -131,7 +131,7 @@ public class PublicKeyFactory
131131
converters.put(BCObjectIdentifiers.sphincsPlus_shake_256s, new SPHINCSPlusConverter());
132132
converters.put(BCObjectIdentifiers.sphincsPlus_shake_256f, new SPHINCSPlusConverter());
133133
converters.put(new ASN1ObjectIdentifier("1.3.9999.6.4.10"), new SPHINCSPlusConverter());
134-
134+
135135
converters.put(BCObjectIdentifiers.mceliece348864_r3, new CMCEConverter());
136136
converters.put(BCObjectIdentifiers.mceliece348864f_r3, new CMCEConverter());
137137
converters.put(BCObjectIdentifiers.mceliece460896_r3, new CMCEConverter());
@@ -437,21 +437,25 @@ private static class LMSConverter
437437
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
438438
throws IOException
439439
{
440-
byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets();
440+
byte[] keyEnc = keyInfo.getPublicKeyData().getOctets();
441+
byte[] data = Utils.readOctetString(keyEnc);
441442

442-
if (Pack.bigEndianToInt(keyEnc, 0) == 1)
443+
if (data != null)
443444
{
444-
return LMSPublicKeyParameters.getInstance(Arrays.copyOfRange(keyEnc, 4, keyEnc.length));
445+
return getLmsKeyParameters(data);
445446
}
446-
else
447+
448+
return getLmsKeyParameters(keyEnc);
449+
}
450+
451+
private LMSKeyParameters getLmsKeyParameters(byte[] keyEnc)
452+
throws IOException
453+
{
454+
if (keyEnc.length == 64)
447455
{
448-
// public key with extra tree height
449-
if (keyEnc.length == 64)
450-
{
451-
keyEnc = Arrays.copyOfRange(keyEnc, 4, keyEnc.length);
452-
}
453-
return HSSPublicKeyParameters.getInstance(keyEnc);
456+
keyEnc = Arrays.copyOfRange(keyEnc, 4, keyEnc.length);
454457
}
458+
return HSSPublicKeyParameters.getInstance(keyEnc);
455459
}
456460
}
457461

@@ -495,7 +499,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje
495499
return new CMCEPublicKeyParameters(spParams, keyEnc);
496500
}
497501
catch (Exception e)
498-
{
502+
{
499503
byte[] keyEnc = keyInfo.getPublicKeyData().getOctets();
500504

501505
CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getAlgorithm().getAlgorithm());
@@ -506,13 +510,13 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje
506510
}
507511

508512
private static class SABERConverter
509-
extends SubjectPublicKeyInfoConverter
513+
extends SubjectPublicKeyInfoConverter
510514
{
511515
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
512-
throws IOException
516+
throws IOException
513517
{
514518
byte[] keyEnc = ASN1OctetString.getInstance(
515-
ASN1Sequence.getInstance(keyInfo.parsePublicKey()).getObjectAt(0)).getOctets();
519+
ASN1Sequence.getInstance(keyInfo.parsePublicKey()).getObjectAt(0)).getOctets();
516520

517521
SABERParameters saberParams = Utils.saberParamsLookup(keyInfo.getAlgorithm().getAlgorithm());
518522

@@ -533,10 +537,10 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje
533537
}
534538

535539
private static class FrodoConverter
536-
extends SubjectPublicKeyInfoConverter
540+
extends SubjectPublicKeyInfoConverter
537541
{
538542
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
539-
throws IOException
543+
throws IOException
540544
{
541545
byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets();
542546

@@ -547,10 +551,10 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje
547551
}
548552

549553
private static class PicnicConverter
550-
extends SubjectPublicKeyInfoConverter
554+
extends SubjectPublicKeyInfoConverter
551555
{
552556
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
553-
throws IOException
557+
throws IOException
554558
{
555559
byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets();
556560

@@ -566,7 +570,19 @@ private static class NtruConverter
566570
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
567571
throws IOException
568572
{
569-
byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets();
573+
byte[] keyEnc = keyInfo.getPublicKeyData().getOctets();
574+
byte[] data = Utils.readOctetString(keyEnc);
575+
576+
if (data != null)
577+
{
578+
return getNtruPublicKeyParameters(keyInfo, data);
579+
}
580+
581+
return getNtruPublicKeyParameters(keyInfo, keyEnc);
582+
}
583+
584+
private NTRUPublicKeyParameters getNtruPublicKeyParameters(SubjectPublicKeyInfo keyInfo, byte[] keyEnc)
585+
{
570586

571587
NTRUParameters ntruParams = Utils.ntruParamsLookup(keyInfo.getAlgorithm().getAlgorithm());
572588

@@ -640,7 +656,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje
640656
return new SNTRUPrimePublicKeyParameters(ntruLPRimeParams, keyEnc);
641657
}
642658
}
643-
659+
644660
static class DilithiumConverter
645661
extends SubjectPublicKeyInfoConverter
646662
{
@@ -720,10 +736,10 @@ static MLDSAPublicKeyParameters getPublicKeyParams(MLDSAParameters dilithiumPara
720736
}
721737

722738
private static class BIKEConverter
723-
extends SubjectPublicKeyInfoConverter
739+
extends SubjectPublicKeyInfoConverter
724740
{
725741
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
726-
throws IOException
742+
throws IOException
727743
{
728744
try
729745
{
@@ -745,10 +761,10 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje
745761
}
746762

747763
private static class HQCConverter
748-
extends SubjectPublicKeyInfoConverter
764+
extends SubjectPublicKeyInfoConverter
749765
{
750766
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
751-
throws IOException
767+
throws IOException
752768
{
753769
try
754770
{

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ else if (publicKey instanceof LMSPublicKeyParameters)
9191
byte[] encoding = Composer.compose().u32str(1).bytes(params).build();
9292

9393
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig);
94-
return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding));
94+
return new SubjectPublicKeyInfo(algorithmIdentifier, encoding);
9595
}
9696
else if (publicKey instanceof HSSPublicKeyParameters)
9797
{
@@ -100,7 +100,7 @@ else if (publicKey instanceof HSSPublicKeyParameters)
100100
byte[] encoding = Composer.compose().u32str(params.getL()).bytes(params.getLMSPublicKey()).build();
101101

102102
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig);
103-
return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding));
103+
return new SubjectPublicKeyInfo(algorithmIdentifier, encoding);
104104
}
105105
else if (publicKey instanceof SLHDSAPublicKeyParameters)
106106
{
@@ -215,7 +215,7 @@ else if (publicKey instanceof NTRUPublicKeyParameters)
215215
byte[] encoding = params.getEncoded();
216216

217217
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.ntruOidLookup(params.getParameters()));
218-
return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding));
218+
return new SubjectPublicKeyInfo(algorithmIdentifier, encoding);
219219
}
220220
else if (publicKey instanceof FalconPublicKeyParameters)
221221
{

0 commit comments

Comments
 (0)