Skip to content

Commit c71f93e

Browse files
committed
Merge branch 'main' of gitlab.cryptoworkshop.com:root/bc-java
# Conflicts: # CONTRIBUTORS.md # docs/releasenotes.md
2 parents fcb5a4a + 7ae5ac9 commit c71f93e

15 files changed

Lines changed: 483 additions & 123 deletions

File tree

‎CONTRIBUTORS.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,3 +550,4 @@ We also wish to acknowledge financial and collaborative support from [CISCO](htt
550550
- Rob Augustinus \<rob&#064;opensolutions.nl\> - a constant-time analysis of the elliptic-curve and AES code paths, with proof-of-concept code, which independently reached the variable-point scalar multiplication exposure addressed in 1.86.
551551
- Radim Dejmek \<dejmekr&#064;seznam.cz\> - initial implementation of the rebuild of the ERS hash lists around a single sort, which had been finding the insertion point for each hash by walking a LinkedList (PR #2457).
552552
- sfeng-c \<https://github.com/sfeng-c\> - initial implementation of the CRMF protocolEncrKey control (RFC 4211 sec. 6.6), with round-trip test coverage (PR #2443).
553+
- Carsten Hammer \<https://github.com/carstenartur\> - deriving the c6 and c7 constants of the generic RFC 9380 sqrt_ratio calculator from a shared z^c3, saving a modular exponentiation per instance, with tests comparing the stored constants against the direct powers (PR #2455).

‎core/src/main/java/org/bouncycastle/crypto/hash2curve/impl/GenericSqrtRatioCalculator.java‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
* RFC 9380 defines optimized sqrt_ratio formulas for certain curves where the field prime p
2121
* satisfies special congruences (e.g. p ≡ 3 mod 4 or p ≡ 5 mod 8). However, those optimizations are
2222
* curve-specific and do not apply to all hash-to-curve suites. This implementation instead follows
23-
* the fully generic algorithm from Section 5.6.3 of RFC 9380, which is valid for any elliptic curve
23+
* the fully generic algorithm from Appendix F.2.1.1 of RFC 9380, which is valid for any elliptic curve
2424
* defined over a prime field Fp.
2525
* </p>
2626
*
2727
* <p>
28-
* This generic version supports all curves used in the RFC 9830 test vectors, including the NIST
28+
* This generic version supports all curves used in the RFC 9380 test vectors, including the NIST
2929
* P-256 / P-384 / P-521 curves, Curve25519, Edwards25519 (Ristretto255), Curve448, and Edwards448
3030
* (Decaf448). It provides a single uniform implementation suitable for all supported hash-to-curve
3131
* suites.
@@ -62,8 +62,10 @@ public GenericSqrtRatioCalculator(final ECCurve curve, final BigInteger z)
6262
this.c3 = this.c2.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
6363
this.c4 = BigInteger.valueOf(2).pow(this.c1).subtract(BigInteger.ONE);
6464
this.c5 = BigInteger.valueOf(2).pow(this.c1 - 1);
65-
this.c6 = z.modPow(this.c2, this.q);
66-
this.c7 = z.modPow(this.c2.add(BigInteger.ONE).divide(BigInteger.valueOf(2)), q);
65+
// c2 = 2*c3 + 1: share z^c3 between the two constants (RFC 9380, F.2.1.1).
66+
BigInteger zToC3 = z.modPow(this.c3, this.q);
67+
this.c7 = zToC3.multiply(z).mod(this.q);
68+
this.c6 = zToC3.multiply(this.c7).mod(this.q);
6769
}
6870

6971
private int calculateC1()

‎core/src/main/java/org/bouncycastle/crypto/params/HSSPrivateKeyParameters.java‎

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ List<LMSSignature> getSigList()
8686
return sigList;
8787
}
8888

89+
LMSParameters[] getLMSParameters()
90+
{
91+
LMSParameters[] parms = new LMSParameters[keys.length];
92+
93+
for (int i = 0; i < keys.length; i++)
94+
{
95+
parms[i] = keys[i].getLMSParameters();
96+
}
97+
98+
return parms;
99+
}
100+
89101
LMSPrivateKeyParameters[] copyKeys()
90102
{
91103
return (LMSPrivateKeyParameters[])keys.clone();
@@ -439,19 +451,7 @@ public synchronized long getIndex()
439451

440452
public LMSParameters[] getLMSParameters()
441453
{
442-
Hierarchy hierarchy = this.hierarchy;
443-
int len = hierarchy.size();
444-
445-
LMSParameters[] parms = new LMSParameters[len];
446-
447-
for (int i = 0; i < len; i++)
448-
{
449-
LMSPrivateKeyParameters lmsPrivateKey = hierarchy.getKey(i);
450-
451-
parms[i] = lmsPrivateKey.getLMSParameters();
452-
}
453-
454-
return parms;
454+
return hierarchy.getLMSParameters();
455455
}
456456

457457
synchronized void incIndex()
@@ -709,30 +709,36 @@ private void rangeTestKeys()
709709
{
710710
if (index >= indexLimit)
711711
{
712-
throw new ExhaustedPrivateKeyException(
713-
"hss private key" +
714-
((isShard) ? " shard" : "") +
715-
" is exhausted");
712+
throw new ExhaustedPrivateKeyException("hss private key" + (isShard ? " shard" : "") +
713+
" is exhausted");
716714
}
717715

718-
719716
int L = l;
720717
int d = L;
721-
Hierarchy prv = hierarchy;
722-
// >= rather than ==: an index above 2^h steps straight over an equality test
723-
// (github #2414). Decode now rejects such a q, so this is belt and braces.
724-
while (prv.getKey(d - 1).getIndex() >= 1 << (prv.getKey(d - 1).getSigParameters().getH()))
718+
Hierarchy currentHierarchy = this.hierarchy;
719+
while (true)
725720
{
726-
d = d - 1;
727-
if (d == 0)
721+
LMSPrivateKeyParameters key = currentHierarchy.getKey(d - 1);
722+
723+
// The whole tree, not the key's own maxQ: a component key given a narrower usage limit is
724+
// left to refuse for itself once it reaches it. Judging it by maxQ would replace the level
725+
// with a fresh full tree, lifting a limit the caller set and spending a one-time key of the
726+
// level above to sign it (testNarrowedComponentKeyIsNotReplaced).
727+
int keyIndexLimit = 1 << key.getSigParameters().getH();
728+
729+
// < rather than !=: an index above 2^h steps straight over an equality test
730+
// (github #2414). Decode now rejects such a q, so this is belt and braces.
731+
if (key.getIndex() < keyIndexLimit)
728732
{
729-
throw new ExhaustedPrivateKeyException(
730-
"hss private key" +
731-
((isShard) ? " shard" : "") +
732-
" is exhausted the maximum limit for this HSS private key");
733+
break;
733734
}
734-
}
735735

736+
if (--d == 0)
737+
{
738+
throw new ExhaustedPrivateKeyException("hss private key" + (isShard ? " shard" : "") +
739+
" has no one-time keys left at any level");
740+
}
741+
}
736742

737743
if (d < L)
738744
{

‎core/src/main/java/org/bouncycastle/crypto/params/LMSKeyParameters.java‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import java.io.ByteArrayOutputStream;
44
import java.io.IOException;
55

6-
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
76
import org.bouncycastle.util.Encodable;
87
import org.bouncycastle.util.Pack;
98

0 commit comments

Comments
 (0)