mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-21 12:20:29 +00:00
8369917: LMS/HSS RFC 9858 Support
Reviewed-by: weijun
This commit is contained in:
parent
121165ec91
commit
531dad0cd7
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -242,4 +242,21 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable {
|
||||
padding = new byte[136];
|
||||
padding[0] = (byte)0x80;
|
||||
}
|
||||
|
||||
/**
|
||||
* Digest block-length bytes in a single operation.
|
||||
* Subclasses are expected to override this method. It is intended
|
||||
* for fixed-length short input where input includes padding bytes.
|
||||
* @param input byte array to be digested
|
||||
* @param inLen the length of the input
|
||||
* @param output the output buffer
|
||||
* @param outOffset the offset into output buffer where digest should be written
|
||||
* @param outLen the length of the output buffer
|
||||
* @throws UnsupportedOperationException if a subclass does not override this method
|
||||
*/
|
||||
void implDigestFixedLengthPreprocessed (
|
||||
byte[] input, int inLen, byte[] output, int outOffset, int outLen)
|
||||
throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException("should not be here");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,16 +24,22 @@
|
||||
*/
|
||||
package sun.security.provider;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.x509.AlgorithmId;
|
||||
import sun.security.x509.X509Key;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.*;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Implementation of the Hierarchical Signature System using the
|
||||
* Leighton-Micali Signatures (HSS/LMS) as described in RFC 8554 and
|
||||
@ -196,42 +202,94 @@ public final class HSS extends SignatureSpi {
|
||||
|
||||
static class LMSUtils {
|
||||
static final int LMS_RESERVED = 0;
|
||||
static final int LMS_SHA256_M32_H5 = 5;
|
||||
static final int LMS_SHA256_M32_H10 = 6;
|
||||
static final int LMS_SHA256_M32_H15 = 7;
|
||||
static final int LMS_SHA256_M32_H20 = 8;
|
||||
static final int LMS_SHA256_M32_H25 = 9;
|
||||
static final int LMS_SHA256_M32_H5 = 0x05;
|
||||
static final int LMS_SHA256_M32_H10 = 0x06;
|
||||
static final int LMS_SHA256_M32_H15 = 0x07;
|
||||
static final int LMS_SHA256_M32_H20 = 0x08;
|
||||
static final int LMS_SHA256_M32_H25 = 0x09;
|
||||
static final int LMS_SHA256_M24_H5 = 0x0a;
|
||||
static final int LMS_SHA256_M24_H10 = 0x0b;
|
||||
static final int LMS_SHA256_M24_H15 = 0x0c;
|
||||
static final int LMS_SHA256_M24_H20 = 0x0d;
|
||||
static final int LMS_SHA256_M24_H25 = 0x0e;
|
||||
static final int LMS_SHAKE_M32_H5 = 0x0f;
|
||||
static final int LMS_SHAKE_M32_H10 = 0x10;
|
||||
static final int LMS_SHAKE_M32_H15 = 0x11;
|
||||
static final int LMS_SHAKE_M32_H20 = 0x12;
|
||||
static final int LMS_SHAKE_M32_H25 = 0x13;
|
||||
static final int LMS_SHAKE_M24_H5 = 0x14;
|
||||
static final int LMS_SHAKE_M24_H10 = 0x15;
|
||||
static final int LMS_SHAKE_M24_H15 = 0x16;
|
||||
static final int LMS_SHAKE_M24_H20 = 0x17;
|
||||
static final int LMS_SHAKE_M24_H25 = 0x18;
|
||||
|
||||
static String lmsType(int type) {
|
||||
String typeStr;
|
||||
switch (type) {
|
||||
case LMS_RESERVED: typeStr = "LMS_RESERVED"; break;
|
||||
case LMS_SHA256_M32_H5: typeStr = "LMS_SHA256_M32_H5"; break;
|
||||
case LMS_SHA256_M32_H10: typeStr = "LMS_SHA256_M32_H10"; break;
|
||||
case LMS_SHA256_M32_H15: typeStr = "LMS_SHA256_M32_H15"; break;
|
||||
case LMS_SHA256_M32_H20: typeStr = "LMS_SHA256_M32_H20"; break;
|
||||
case LMS_SHA256_M32_H25: typeStr = "LMS_SHA256_M32_H25"; break;
|
||||
default: typeStr = "unrecognized";
|
||||
}
|
||||
String typeStr = switch (type) {
|
||||
case LMS_RESERVED -> "LMS_RESERVED";
|
||||
case LMS_SHA256_M32_H5 -> "LMS_SHA256_M32_H5";
|
||||
case LMS_SHA256_M32_H10 -> "LMS_SHA256_M32_H10";
|
||||
case LMS_SHA256_M32_H15 -> "LMS_SHA256_M32_H15";
|
||||
case LMS_SHA256_M32_H20 -> "LMS_SHA256_M32_H20";
|
||||
case LMS_SHA256_M32_H25 -> "LMS_SHA256_M32_H25";
|
||||
case LMS_SHA256_M24_H5 -> "LMS_SHA256_M24_H5";
|
||||
case LMS_SHA256_M24_H10 -> "LMS_SHA256_M24_H10";
|
||||
case LMS_SHA256_M24_H15 -> "LMS_SHA256_M24_H15";
|
||||
case LMS_SHA256_M24_H20 -> "LMS_SHA256_M24_H20";
|
||||
case LMS_SHA256_M24_H25 -> "LMS_SHA256_M24_H25";
|
||||
case LMS_SHAKE_M32_H5 -> "LMS_SHAKE_M32_H5";
|
||||
case LMS_SHAKE_M32_H10 -> "LMS_SHAKE_M32_H10";
|
||||
case LMS_SHAKE_M32_H15 -> "LMS_SHAKE_M32_H15";
|
||||
case LMS_SHAKE_M32_H20 -> "LMS_SHAKE_M32_H20";
|
||||
case LMS_SHAKE_M32_H25 -> "LMS_SHAKE_M32_H25";
|
||||
case LMS_SHAKE_M24_H5 -> "LMS_SHAKE_M24_H5";
|
||||
case LMS_SHAKE_M24_H10 -> "LMS_SHAKE_M24_H10";
|
||||
case LMS_SHAKE_M24_H15 -> "LMS_SHAKE_M24_H15";
|
||||
case LMS_SHAKE_M24_H20 -> "LMS_SHAKE_M24_H20";
|
||||
case LMS_SHAKE_M24_H25 -> "LMS_SHAKE_M24_H25";
|
||||
default -> "unrecognized";
|
||||
};
|
||||
return typeStr;
|
||||
}
|
||||
|
||||
static final int LMOTS_RESERVED = 0;
|
||||
static final int LMOTS_SHA256_N32_W1 = 1;
|
||||
static final int LMOTS_SHA256_N32_W2 = 2;
|
||||
static final int LMOTS_SHA256_N32_W4 = 3;
|
||||
static final int LMOTS_SHA256_N32_W8 = 4;
|
||||
static final int LMOTS_SHA256_N32_W1 = 0x01;
|
||||
static final int LMOTS_SHA256_N32_W2 = 0x02;
|
||||
static final int LMOTS_SHA256_N32_W4 = 0x03;
|
||||
static final int LMOTS_SHA256_N32_W8 = 0x04;
|
||||
static final int LMOTS_SHA256_N24_W1 = 0x05;
|
||||
static final int LMOTS_SHA256_N24_W2 = 0x06;
|
||||
static final int LMOTS_SHA256_N24_W4 = 0x07;
|
||||
static final int LMOTS_SHA256_N24_W8 = 0x08;
|
||||
static final int LMOTS_SHAKE_N32_W1 = 0x09;
|
||||
static final int LMOTS_SHAKE_N32_W2 = 0x0a;
|
||||
static final int LMOTS_SHAKE_N32_W4 = 0x0b;
|
||||
static final int LMOTS_SHAKE_N32_W8 = 0x0c;
|
||||
static final int LMOTS_SHAKE_N24_W1 = 0x0d;
|
||||
static final int LMOTS_SHAKE_N24_W2 = 0x0e;
|
||||
static final int LMOTS_SHAKE_N24_W4 = 0x0f;
|
||||
static final int LMOTS_SHAKE_N24_W8 = 0x10;
|
||||
|
||||
static String lmotsType(int type) {
|
||||
String typeStr;
|
||||
switch (type) {
|
||||
case LMOTS_RESERVED: typeStr = "LMOTS_RESERVED"; break;
|
||||
case LMOTS_SHA256_N32_W1: typeStr = "LMOTS_SHA256_N32_W1"; break;
|
||||
case LMOTS_SHA256_N32_W2: typeStr = "LMOTS_SHA256_N32_W2"; break;
|
||||
case LMOTS_SHA256_N32_W4: typeStr = "LMOTS_SHA256_N32_W4"; break;
|
||||
case LMOTS_SHA256_N32_W8: typeStr = "LMOTS_SHA256_N32_W8"; break;
|
||||
default: typeStr = "unrecognized";
|
||||
}
|
||||
String typeStr = switch (type) {
|
||||
case LMOTS_RESERVED -> "LMOTS_RESERVED";
|
||||
case LMOTS_SHA256_N32_W1 -> "LMOTS_SHA256_N32_W1";
|
||||
case LMOTS_SHA256_N32_W2 -> "LMOTS_SHA256_N32_W2";
|
||||
case LMOTS_SHA256_N32_W4 -> "LMOTS_SHA256_N32_W4";
|
||||
case LMOTS_SHA256_N32_W8 -> "LMOTS_SHA256_N32_W8";
|
||||
case LMOTS_SHA256_N24_W1 -> "LMOTS_SHA256_N24_W1";
|
||||
case LMOTS_SHA256_N24_W2 -> "LMOTS_SHA256_N24_W2";
|
||||
case LMOTS_SHA256_N24_W4 -> "LMOTS_SHA256_N24_W4";
|
||||
case LMOTS_SHA256_N24_W8 -> "LMOTS_SHA256_N24_W8";
|
||||
case LMOTS_SHAKE_N32_W1 -> "LMOTS_SHAKE_N32_W1";
|
||||
case LMOTS_SHAKE_N32_W2 -> "LMOTS_SHAKE_N32_W2";
|
||||
case LMOTS_SHAKE_N32_W4 -> "LMOTS_SHAKE_N32_W4";
|
||||
case LMOTS_SHAKE_N32_W8 -> "LMOTS_SHAKE_N32_W8";
|
||||
case LMOTS_SHAKE_N24_W1 -> "LMOTS_SHAKE_N24_W1";
|
||||
case LMOTS_SHAKE_N24_W2 -> "LMOTS_SHAKE_N24_W2";
|
||||
case LMOTS_SHAKE_N24_W4 -> "LMOTS_SHAKE_N24_W4";
|
||||
case LMOTS_SHAKE_N24_W8 -> "LMOTS_SHAKE_N24_W8";
|
||||
default -> "unrecognized";
|
||||
};
|
||||
return typeStr;
|
||||
}
|
||||
|
||||
@ -352,53 +410,65 @@ public final class HSS extends SignatureSpi {
|
||||
|
||||
static class LMSParams {
|
||||
final int m; // the number of bytes used from the hash output
|
||||
final int hashAlg_m = 32; // output length of the LMS tree hash function
|
||||
final int hashAlg_m; // output length of the LMS tree hash function
|
||||
final int h; // height of the LMS tree
|
||||
final int twoPowh;
|
||||
final String hashAlgStr;
|
||||
|
||||
LMSParams(int m, int h, String hashAlgStr) {
|
||||
private LMSParams(int m, int h, String hashAlgStr, int hashAlg_m) {
|
||||
this.m = m;
|
||||
this.h = h;
|
||||
this.hashAlgStr = hashAlgStr;
|
||||
this.hashAlg_m = hashAlg_m;
|
||||
twoPowh = 1 << h;
|
||||
}
|
||||
|
||||
static LMSParams of(int type) {
|
||||
int m;
|
||||
int h;
|
||||
String hashAlgStr;
|
||||
switch (type) {
|
||||
case LMSUtils.LMS_SHA256_M32_H5:
|
||||
m = 32;
|
||||
h = 5;
|
||||
hashAlgStr = "SHA-256";
|
||||
break;
|
||||
case LMSUtils.LMS_SHA256_M32_H10:
|
||||
m = 32;
|
||||
h = 10;
|
||||
hashAlgStr = "SHA-256";
|
||||
break;
|
||||
case LMSUtils.LMS_SHA256_M32_H15:
|
||||
m = 32;
|
||||
h = 15;
|
||||
hashAlgStr = "SHA-256";
|
||||
break;
|
||||
case LMSUtils.LMS_SHA256_M32_H20:
|
||||
m = 32;
|
||||
h = 20;
|
||||
hashAlgStr = "SHA-256";
|
||||
break;
|
||||
case LMSUtils.LMS_SHA256_M32_H25:
|
||||
m = 32;
|
||||
h = 25;
|
||||
hashAlgStr = "SHA-256";
|
||||
break;
|
||||
default:
|
||||
LMSParams params = switch (type) {
|
||||
case LMSUtils.LMS_SHA256_M32_H5 ->
|
||||
new LMSParams(32, 5, "SHA-256", 32);
|
||||
case LMSUtils.LMS_SHA256_M32_H10 ->
|
||||
new LMSParams(32, 10, "SHA-256", 32);
|
||||
case LMSUtils.LMS_SHA256_M32_H15 ->
|
||||
new LMSParams(32, 15, "SHA-256", 32);
|
||||
case LMSUtils.LMS_SHA256_M32_H20 ->
|
||||
new LMSParams(32, 20, "SHA-256", 32);
|
||||
case LMSUtils.LMS_SHA256_M32_H25 ->
|
||||
new LMSParams(32, 25, "SHA-256", 32);
|
||||
case LMSUtils.LMS_SHA256_M24_H5 ->
|
||||
new LMSParams(24, 5, "SHA-256", 32);
|
||||
case LMSUtils.LMS_SHA256_M24_H10 ->
|
||||
new LMSParams(24, 10, "SHA-256", 32);
|
||||
case LMSUtils.LMS_SHA256_M24_H15 ->
|
||||
new LMSParams(24, 15, "SHA-256", 32);
|
||||
case LMSUtils.LMS_SHA256_M24_H20 ->
|
||||
new LMSParams(24, 20, "SHA-256", 32);
|
||||
case LMSUtils.LMS_SHA256_M24_H25 ->
|
||||
new LMSParams(24, 25, "SHA-256", 32);
|
||||
case LMSUtils.LMS_SHAKE_M32_H5 ->
|
||||
new LMSParams(32, 5, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMS_SHAKE_M32_H10 ->
|
||||
new LMSParams(32, 10, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMS_SHAKE_M32_H15 ->
|
||||
new LMSParams(32, 15, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMS_SHAKE_M32_H20 ->
|
||||
new LMSParams(32, 20, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMS_SHAKE_M32_H25 ->
|
||||
new LMSParams(32, 25, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMS_SHAKE_M24_H5 ->
|
||||
new LMSParams(24, 5, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMS_SHAKE_M24_H10 ->
|
||||
new LMSParams(24, 10, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMS_SHAKE_M24_H15 ->
|
||||
new LMSParams(24, 15, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMS_SHAKE_M24_H20 ->
|
||||
new LMSParams(24, 20, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMS_SHAKE_M24_H25 ->
|
||||
new LMSParams(24, 25, "SHAKE256-512", 64);
|
||||
default ->
|
||||
throw new IllegalArgumentException("Unsupported or bad LMS type");
|
||||
}
|
||||
|
||||
return new LMSParams(m, h, hashAlgStr);
|
||||
};
|
||||
return params;
|
||||
}
|
||||
|
||||
boolean hasSameHash(LMSParams other) {
|
||||
@ -495,7 +565,7 @@ public final class HSS extends SignatureSpi {
|
||||
static class LMOTSParams {
|
||||
final int lmotSigType;
|
||||
final int n; // the number of bytes used from the hash output
|
||||
final int hashAlg_n = 32; // the output length of the hash function
|
||||
int hashAlg_n; // the output length of the hash function
|
||||
final int w;
|
||||
final int twoPowWMinus1;
|
||||
final int ls;
|
||||
@ -511,6 +581,7 @@ public final class HSS extends SignatureSpi {
|
||||
// back into the buffer. This way, we avoid memory allocations and some
|
||||
// computations that would have to be done otherwise.
|
||||
final byte[] hashBuf;
|
||||
|
||||
// Precomputed block for SHA256 when the message size is 55 bytes
|
||||
// (i.e. when SHA256 is used)
|
||||
private static final byte[] hashbufSha256_32 = {
|
||||
@ -523,10 +594,64 @@ public final class HSS extends SignatureSpi {
|
||||
0, 0, 0, 0, 0, 0, 0, (byte) 0x80,
|
||||
0, 0, 0, 0, 0, 0, 1, (byte) 0xb8
|
||||
};
|
||||
// Precomputed block for SHA256 when the message size is 47 bytes
|
||||
// (i.e. when SHA256-192 is used)
|
||||
private static final byte[] hashbufSha256_24 = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, (byte) 0x80,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 1, 0x78
|
||||
};
|
||||
// Precomputed block for SHAKE256 when the message size is 55 bytes
|
||||
// (i.e. when SHAKE256 is used)
|
||||
private static final byte[] hashbufShake256_32 = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, (byte) 0x1F,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, (byte) 0x80
|
||||
};
|
||||
// Precomputed block for SHAKE256 when the message size is 47 bytes
|
||||
// (i.e. when SHAKE256-192 is used)
|
||||
private static final byte[] hashbufShake256_24 = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, (byte) 0x1F,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, (byte) 0x80
|
||||
};
|
||||
|
||||
private LMOTSParams(
|
||||
int lmotSigType, int hLen, int w,
|
||||
int ls, int p, String hashAlgName) {
|
||||
int ls, int p, String hashAlgName, int hashAlg_n) {
|
||||
this.lmotSigType = lmotSigType;
|
||||
this.n = hLen;
|
||||
this.w = w;
|
||||
@ -534,32 +659,60 @@ public final class HSS extends SignatureSpi {
|
||||
this.p = p;
|
||||
twoPowWMinus1 = (1 << w) - 1;
|
||||
this.hashAlgName = hashAlgName;
|
||||
hashBuf = hashbufSha256_32;
|
||||
this.hashAlg_n = hashAlg_n;
|
||||
hashBuf = switch (hashAlgName) {
|
||||
case "SHAKE256-512" -> {
|
||||
yield this.n == 24 ?
|
||||
hashbufShake256_24 : hashbufShake256_32;
|
||||
}
|
||||
case "SHA-256" -> {
|
||||
yield this.n == 24 ?
|
||||
hashbufSha256_24 : hashbufSha256_32;
|
||||
}
|
||||
default ->
|
||||
throw new IllegalArgumentException(
|
||||
"Unknown hash algorithm "+hashAlgName);
|
||||
};
|
||||
}
|
||||
|
||||
static LMOTSParams of(int lmotsType) {
|
||||
LMOTSParams params;
|
||||
switch (lmotsType) {
|
||||
case LMSUtils.LMOTS_SHA256_N32_W1:
|
||||
params = new LMOTSParams(
|
||||
lmotsType, 32, 1, 7, 265, "SHA-256");
|
||||
break;
|
||||
case LMSUtils.LMOTS_SHA256_N32_W2:
|
||||
params = new LMOTSParams(
|
||||
lmotsType, 32, 2, 6, 133, "SHA-256");
|
||||
break;
|
||||
case LMSUtils.LMOTS_SHA256_N32_W4:
|
||||
params = new LMOTSParams(
|
||||
lmotsType, 32, 4, 4, 67, "SHA-256");
|
||||
break;
|
||||
case LMSUtils.LMOTS_SHA256_N32_W8:
|
||||
params = new LMOTSParams(
|
||||
lmotsType, 32, 8, 0, 34, "SHA-256");
|
||||
break;
|
||||
default:
|
||||
LMOTSParams params = switch (lmotsType) {
|
||||
case LMSUtils.LMOTS_SHA256_N32_W1 ->
|
||||
new LMOTSParams(lmotsType, 32, 1, 7, 265, "SHA-256", 32);
|
||||
case LMSUtils.LMOTS_SHA256_N32_W2 ->
|
||||
new LMOTSParams(lmotsType, 32, 2, 6, 133, "SHA-256", 32);
|
||||
case LMSUtils.LMOTS_SHA256_N32_W4 ->
|
||||
new LMOTSParams(lmotsType, 32, 4, 4, 67, "SHA-256", 32);
|
||||
case LMSUtils.LMOTS_SHA256_N32_W8 ->
|
||||
new LMOTSParams(lmotsType, 32, 8, 0, 34, "SHA-256", 32);
|
||||
case LMSUtils.LMOTS_SHA256_N24_W1 ->
|
||||
new LMOTSParams(lmotsType, 24, 1, 8, 200, "SHA-256", 32);
|
||||
case LMSUtils.LMOTS_SHA256_N24_W2 ->
|
||||
new LMOTSParams(lmotsType, 24, 2, 6, 101, "SHA-256", 32);
|
||||
case LMSUtils.LMOTS_SHA256_N24_W4 ->
|
||||
new LMOTSParams(lmotsType, 24, 4, 4, 51, "SHA-256", 32);
|
||||
case LMSUtils.LMOTS_SHA256_N24_W8 ->
|
||||
new LMOTSParams(lmotsType, 24, 8, 0, 26, "SHA-256", 32);
|
||||
case LMSUtils.LMOTS_SHAKE_N32_W1 ->
|
||||
new LMOTSParams(lmotsType, 32, 1, 7, 265, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMOTS_SHAKE_N32_W2 ->
|
||||
new LMOTSParams(lmotsType, 32, 2, 6, 133, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMOTS_SHAKE_N32_W4 ->
|
||||
new LMOTSParams(lmotsType, 32, 4, 4, 67, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMOTS_SHAKE_N32_W8 ->
|
||||
new LMOTSParams(lmotsType, 32, 8, 0, 34, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMOTS_SHAKE_N24_W1 ->
|
||||
new LMOTSParams(lmotsType, 24, 1, 8, 200, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMOTS_SHAKE_N24_W2 ->
|
||||
new LMOTSParams(lmotsType, 24, 2, 6, 101, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMOTS_SHAKE_N24_W4 ->
|
||||
new LMOTSParams(lmotsType, 24, 4, 4, 51, "SHAKE256-512", 64);
|
||||
case LMSUtils.LMOTS_SHAKE_N24_W8 ->
|
||||
new LMOTSParams(lmotsType, 24, 8, 0, 26, "SHAKE256-512", 64);
|
||||
default ->
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported or bad OTS Algorithm Identifier.");
|
||||
}
|
||||
};
|
||||
return params;
|
||||
}
|
||||
|
||||
@ -580,13 +733,6 @@ public final class HSS extends SignatureSpi {
|
||||
S[len + 1] = (byte) (sum & 0xff);
|
||||
}
|
||||
|
||||
void digestFixedLengthPreprocessed(
|
||||
SHA2.SHA256 sha256, byte[] input, int inLen,
|
||||
byte[] output, int outOffset, int outLen) {
|
||||
sha256.implDigestFixedLengthPreprocessed(
|
||||
input, inLen, output, outOffset, outLen);
|
||||
}
|
||||
|
||||
byte[] lmotsPubKeyCandidate(
|
||||
LMSignature lmSig, byte[] message, LMSPublicKey pKey)
|
||||
throws SignatureException {
|
||||
@ -625,7 +771,13 @@ public final class HSS extends SignatureSpi {
|
||||
|
||||
byte[] preZi = hashBuf.clone();
|
||||
int hashLen = hashBuf.length;
|
||||
SHA2.SHA256 sha256 = new SHA2.SHA256();
|
||||
|
||||
DigestBase db;
|
||||
if (hashAlgName.startsWith("SHAKE")) {
|
||||
db = new SHA3.SHAKE256Hash();
|
||||
} else {
|
||||
db = new SHA2.SHA256();
|
||||
}
|
||||
pKey.getI(preZi, 0);
|
||||
lmSig.getQArr(preZi, 16);
|
||||
|
||||
@ -643,11 +795,11 @@ public final class HSS extends SignatureSpi {
|
||||
for (int j = a; j < twoPowWMinus1; j++) {
|
||||
preZi[22] = (byte) j;
|
||||
if (j < twoPowWMinus2) {
|
||||
digestFixedLengthPreprocessed(
|
||||
sha256, preZi, hashLen, preZi, 23, n);
|
||||
db.implDigestFixedLengthPreprocessed(preZi,
|
||||
hashLen, preZi, 23, n);
|
||||
} else {
|
||||
digestFixedLengthPreprocessed(
|
||||
sha256, preZi, hashLen, preCandidate, 22 + i * n, n);
|
||||
db.implDigestFixedLengthPreprocessed(preZi,
|
||||
hashLen, preCandidate, 22 + i * n, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -117,6 +117,7 @@ abstract class SHA2 extends DigestBase {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void implDigestFixedLengthPreprocessed(
|
||||
byte[] input, int inLen, byte[] output, int outOffset, int outLen) {
|
||||
implReset();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -98,6 +98,15 @@ public abstract class SHA3 extends DigestBase {
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void implDigestFixedLengthPreprocessed(
|
||||
byte[] input, int inLen, byte[] output, int outOffset, int outLen) {
|
||||
implReset();
|
||||
|
||||
implCompress(input, 0);
|
||||
implDigest0(output, outOffset, outLen);
|
||||
}
|
||||
|
||||
private void implCompressCheck(byte[] b, int ofs) {
|
||||
Objects.requireNonNull(b);
|
||||
Preconditions.checkIndex(ofs + blockSize - 1, b.length, Preconditions.AIOOBE_FORMATTER);
|
||||
@ -136,9 +145,6 @@ public abstract class SHA3 extends DigestBase {
|
||||
* DigestBase calls implReset() when necessary.
|
||||
*/
|
||||
void implDigest(byte[] out, int ofs) {
|
||||
// Moving this allocation to the block where it is used causes a little
|
||||
// performance drop, that is why it is here.
|
||||
byte[] byteState = new byte[8];
|
||||
if (engineGetDigestLength() == 0) {
|
||||
// This is an XOF, so the digest() call is illegal.
|
||||
throw new ProviderException("Calling digest() is not allowed in an XOF");
|
||||
@ -146,8 +152,12 @@ public abstract class SHA3 extends DigestBase {
|
||||
|
||||
finishAbsorb();
|
||||
|
||||
implDigest0(out, ofs, engineGetDigestLength());
|
||||
}
|
||||
|
||||
void implDigest0(byte[] out, int ofs, int outLen) {
|
||||
int availableBytes = blockSize;
|
||||
int numBytes = engineGetDigestLength();
|
||||
int numBytes = outLen;
|
||||
|
||||
while (numBytes > availableBytes) {
|
||||
for (int i = 0; i < availableBytes / 8; i++) {
|
||||
@ -163,6 +173,10 @@ public abstract class SHA3 extends DigestBase {
|
||||
asLittleEndian.set(out, ofs, state[i]);
|
||||
ofs += 8;
|
||||
}
|
||||
|
||||
// Moving this allocation to the block where it is used causes a little
|
||||
// performance drop, that is why it is here.
|
||||
byte[] byteState = new byte[8];
|
||||
if (numBytes % 8 != 0) {
|
||||
asLittleEndian.set(byteState, 0, state[numLongs]);
|
||||
System.arraycopy(byteState, 0, out, ofs, numBytes % 8);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -444,15 +444,16 @@ public final class KeyUtil {
|
||||
// is the LMS public key for the top-level tree.
|
||||
// Section 5.3: LMS public key is u32str(type) || u32str(otstype) || I || T[1]
|
||||
// Section 8: type is the numeric identifier for an LMS specification.
|
||||
// This RFC defines 5 SHA-256 based types, value from 5 to 9.
|
||||
if (rawKey.length < 8) {
|
||||
throw new NoSuchAlgorithmException("Cannot decode public key");
|
||||
}
|
||||
int num = ((rawKey[4] & 0xff) << 24) + ((rawKey[5] & 0xff) << 16)
|
||||
+ ((rawKey[6] & 0xff) << 8) + (rawKey[7] & 0xff);
|
||||
return switch (num) {
|
||||
// RFC 8554 only supports SHA_256 hash algorithm
|
||||
// RFC 8554 only supports SHA_256 hash algorithms
|
||||
case 5, 6, 7, 8, 9 -> AlgorithmId.SHA256_oid;
|
||||
// RFC 9858 supports SHAKE_256 hash algorithms
|
||||
case 15, 16, 17, 18, 19 -> AlgorithmId.SHAKE256_512_oid;
|
||||
default -> throw new NoSuchAlgorithmException("Unknown LMS type: " + num);
|
||||
};
|
||||
} catch (IOException e) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8298127 8347596
|
||||
* @bug 8298127 8347596 8369917
|
||||
* @library /test/lib
|
||||
* @summary tests for HSS/LMS provider
|
||||
* @modules java.base/sun.security.util
|
||||
@ -194,6 +194,8 @@ public class TestHSS {
|
||||
static TestCase[] TestCases = new TestCase[] {
|
||||
// Test Case #1
|
||||
// RFC 8554 Test Case 1
|
||||
// LM_SHA256_M32_H5, LMOTS_SHA256_N32_W8
|
||||
// LM_SHA256_M32_H5, LMOTS_SHA256_N32_W8
|
||||
new TestCase(
|
||||
null, // exception
|
||||
true, // expected result
|
||||
@ -307,6 +309,8 @@ public class TestHSS {
|
||||
|
||||
// Test Case #2
|
||||
// RFC 8554 Test Case 2
|
||||
// LM_SHA256_M32_H10, LMOTS_SHA256_N32_W4
|
||||
// LM_SHA256_M32_H5, LMOTS_SHA256_N32_W8
|
||||
new TestCase(
|
||||
null, // exception
|
||||
true, // expected result
|
||||
@ -456,11 +460,11 @@ public class TestHSS {
|
||||
),
|
||||
|
||||
// Test Case #3
|
||||
// Additional Parameter sets for LMS Hash-Based Signatures (fluhrer)
|
||||
// This test should fail because SHA256_M24 is supported.
|
||||
// RFC 9858 A.1
|
||||
// LMS_SHA256_M24_H5, LMOTS_SHA256_N24_W8
|
||||
new TestCase(
|
||||
new InvalidKeySpecException(),
|
||||
false, // expected result
|
||||
null, // exception
|
||||
true, // expected result
|
||||
decode("""
|
||||
00000001
|
||||
0000000a
|
||||
@ -502,11 +506,11 @@ public class TestHSS {
|
||||
),
|
||||
|
||||
// Test Case #4
|
||||
// Additional Parameter sets for LMS Hash-Based Signatures (fluhrer)
|
||||
// This test should fail because SHAKE is not supported.
|
||||
// RFC 9858 A.2
|
||||
// LMS_SHAKE_M24_H5, LMOTS_SHAKE_N24_W8
|
||||
new TestCase(
|
||||
new InvalidKeySpecException(),
|
||||
false, // expected result
|
||||
null, // exception
|
||||
true, // expected result
|
||||
decode("""
|
||||
00000001
|
||||
00000014
|
||||
@ -549,11 +553,11 @@ public class TestHSS {
|
||||
),
|
||||
|
||||
// Test Case #5
|
||||
// Additional Parameter sets for LMS Hash-Based Signatures (fluhrer)
|
||||
// This test should fail because SHAKE is not supported.
|
||||
// RFC 9858 A.3
|
||||
// LMS_SHAKE_M32_H5, LMOTS_SHAKE_N32_W8
|
||||
new TestCase(
|
||||
new InvalidKeySpecException(),
|
||||
false, // expected result
|
||||
null, // exception
|
||||
true, // expected result
|
||||
decode("""
|
||||
00000001
|
||||
0000000f
|
||||
@ -611,6 +615,83 @@ public class TestHSS {
|
||||
),
|
||||
|
||||
// Test Case #6
|
||||
// RFC 9858 A.4
|
||||
// LMS_SHA256_M24_H20, LMOTS_SHA256_N24_W4
|
||||
new TestCase(
|
||||
null, // exception
|
||||
true, // expected result
|
||||
decode("""
|
||||
00000001
|
||||
0000000d
|
||||
00000007
|
||||
404142434445464748494a4b4c4d4e4f9c08a50d170406869892802ee4142fcd
|
||||
eac990f110c2460c"""),
|
||||
decode("""
|
||||
54657374206d65737361676520666f72205348413235362f31393220773d34
|
||||
"""),
|
||||
decode("""
|
||||
00000000
|
||||
00000064
|
||||
00000007
|
||||
853fa6e1a65fef076acd2485505b93be9aeb2641e3d3805c1887f26f4bcdb6ac
|
||||
0337b76fa5d6603834287e010b20516f7c336df2134c0a981f1ec2bb7baee516
|
||||
e91e67d3bd16c8d945a7f2be4fd84a604ae3743efc609ee0e69572e9c6d4a682
|
||||
50e877b75d3cae63e9d5c15a32bb3cd17045f6b3e195284fdd1ee3cfbe18f1cb
|
||||
d06ef3e7af34b1844d42dac453115a4507ed525cec120d054b403c61a7e5034f
|
||||
ac4be6ef5412d194d4b6bbc0ae6cd3fe9993d583ee06f4030bc832efec24d1f7
|
||||
13f5088731b91a98491fa3adf1b322bce26df24c8415e3a46bdfe07a6fd48e6d
|
||||
951515758cd6434991098bf6949249fca338ec235871dd564998d07d9b1b1b8d
|
||||
644e657fee8039da8fe195d129faddb12d543b86b0ab8cf6f26c121783f3b828
|
||||
d03f793b42909272f688e4ef6d46e82bdd1a02b1ff86c3b79920b2e6f19faf75
|
||||
c623242f1f2c549f84fb2f4c3ffead3120d97baea507467bb2da79f132bbe15b
|
||||
596fdfcb70983107ebca2597de9d55bd83bcae5c28a85259dadb354859986e60
|
||||
c8afa0b10bd08a8f9ed9b1ede3377075fe0ae36349f7d2ed7bfc9ece0d4cd697
|
||||
2059329419feaf3b9a1045b6cfa4ae89b1cea8950aea4af870d1a3a3909ebc5a
|
||||
3013d6deb927abc0f95093e83cb36a9c1d6f13add19268ac7a0371f8335b0952
|
||||
a57fdb0141d55d937dd6ebb08fee8a5cf426ac97d54ee7aa17e6c57be5e62a52
|
||||
a6b1b986730d3a3aad8a7d327ddf883e6bc7b636eb2a5c4f2a635ae5bada5418
|
||||
d43dfedb69c0a0209334fac89d420d6ad5a2e1df95d26a1bfeb99a5e8455061b
|
||||
fdf2d6e8394caf8a4be699b8afa38e524d4053330af478f85bf33d3ca3a35bc9
|
||||
6987282bd513a8f6a52db9ba36aa90882b3bf573fa275449d8d49eb30bed2bb1
|
||||
7a0ecc7d8a20807f2ea3dd37acd46c713cc2ac9d01a20a30d6832eef86a1e26d
|
||||
1cad7761bf4130a6565572766026509deeddaf46b605452b218a4e137a7ce063
|
||||
b546a35c52510f0ea2cac879192ec443e43b37c5ffa23da7a7fc254324a3de70
|
||||
5c771794f10ea356e5a747e5146fd804a47719803c185b380e34b8dcc8269c2b
|
||||
073d86b2307cf90c6c3ef9271f2d53df2579f0c4cfb632db37a9025965f70b46
|
||||
16673228e98644be6576417b7a97f104350259e7f697408cdf8cf81a3e774162
|
||||
6ccdb87ad8531264cb5ceb7c8c097cec505091a3ee3a826c54f78169abc2e7d0
|
||||
a318dac10250ba940e51e79a3f572fb32bf442be6fd81267946e6387f9a8c705
|
||||
d945c653f2684655e3fa6b9ee311d8a091bef9898292fa272fb8761f066c23d8
|
||||
7aa10d67871cc5419c843b796855c51ad1272e9264acd2035a82b12c2ddbc85a
|
||||
dfcd7c22366a36495349391dbf0001064b8f6b28365445d733e48f1b058a6cb3
|
||||
e71bbb8df3e90406299894f4ca682943ceeba410b33b07716ffc18d6eab75f2d
|
||||
6372f1133605fa3c3ed66f2d8f7c5abe59e87d4500965e347523d73cb356c144
|
||||
827aaa22b1c72a15293c7400e02aaefcf36f68a8246900e6e6228e7ad19d1450
|
||||
c23434f1e45043dc2b6db57f20d8f5b344d4162aa651333287cd8bf8fac41c78
|
||||
d61fe2929209bfe2dc5a2f80205c043b22e540a29f0ea0a5ff529e55bf1dfe42
|
||||
96fc4bb4ac2e875322ab115db479fe979d64f78409af4ec3ad3b758fff83af1b
|
||||
9c48e90ca39366f426c2fb921df55c72786a9217723945a1ac1a66af7def4f8b
|
||||
367001732cce0e5bac91ac9d603807f8bab105b46d315d4cb88feb1c8686884b
|
||||
0000000d
|
||||
13d1a8ef00c5811c15c4d774fdcf75155315aff53ebdff8fb6a54f12c165963d
|
||||
d5690cc9842b0e2190afc5443497584c832155599d00aced84bb3b59170396f7
|
||||
db4fa84aa8577f76cf9367d6e99d3d5be3555d7156b004f2002f505681b1ad22
|
||||
9b9b46a666672aa8ee662c3a0456a9adda7a44fbaca46789577dcd36dc5cdff3
|
||||
4b864d0a32492a0acbcaa6c011748f205b91ab2ab84f2333fb3e3b9acaecdac3
|
||||
8b58aa5f32e718e225631ed6674cccb8c119acbd4992ab3130a6e912deec5983
|
||||
5ab52fbc549430f8b403e4a2a51cc7f46fc143d365763aa1708fd25bcd657a79
|
||||
0e54718d970906242a3b8a97dff18e91a44c4ba818a8dd2d242251265b023b82
|
||||
6077eb740f6682e6c4ada2b85a67988d406132c2ad899099e44cfe610c3a5af7
|
||||
0b406224411a59597e5dda0f31cd16c914b67e96141661f0074f43eb02273481
|
||||
bc324ded26c64f2388559d8c8bd0ef8b34ca4afebfac2a689b4246c264241488
|
||||
dcf922350dc44f7bc09d57dc1126291b2318810e0f44801c071e572fd032c780
|
||||
f44c9503a4c03c37417dc96422ba0849c37956f9fd5d33ea4fcab84276effec6
|
||||
52ca77d7d47ac93c633d99e0a236f03d5587d1990ffaef737fced1f5cdd8f373
|
||||
844e9f316aad41a0b12302639f83a2d74c9fe30d305a942bc0c30352a5e44dfb
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #7
|
||||
// LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w8
|
||||
new TestCase(
|
||||
null, // exception
|
||||
@ -713,7 +794,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #7
|
||||
// Test Case #8
|
||||
// LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w8
|
||||
new TestCase(
|
||||
null, // exception
|
||||
@ -821,7 +902,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #8
|
||||
// Test Case #9
|
||||
// LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4
|
||||
new TestCase(
|
||||
null, // exception
|
||||
@ -957,7 +1038,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #9
|
||||
// Test Case #10
|
||||
// LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w4
|
||||
new TestCase(
|
||||
null, // exception
|
||||
@ -1098,7 +1179,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #10
|
||||
// Test Case #11
|
||||
// LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4
|
||||
// LMSigParameters.lms_sha256_m32_h10, LMOtsParameters.sha256_n32_w4
|
||||
new TestCase(
|
||||
@ -1320,7 +1401,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #11
|
||||
// Test Case #12
|
||||
// LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4
|
||||
// LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4
|
||||
new TestCase(
|
||||
@ -1547,7 +1628,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #12
|
||||
// Test Case #13
|
||||
// LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w4
|
||||
// LMSigParameters.lms_sha256_m32_h10, LMOtsParameters.sha256_n32_w4
|
||||
new TestCase(
|
||||
@ -1774,7 +1855,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #13
|
||||
// Test Case #14
|
||||
// LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w4
|
||||
// LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4
|
||||
new TestCase(
|
||||
@ -2006,7 +2087,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #14
|
||||
// Test Case #15
|
||||
// LMS signature length is incorrect
|
||||
new TestCase(
|
||||
new SignatureException(),
|
||||
@ -2119,7 +2200,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #15
|
||||
// Test Case #16
|
||||
// HSS signature and public key have different tree heights
|
||||
new TestCase(
|
||||
new SignatureException(),
|
||||
@ -2232,7 +2313,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #16
|
||||
// Test Case #17
|
||||
// bad signature
|
||||
new TestCase(
|
||||
null, // exception
|
||||
@ -2345,7 +2426,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #17
|
||||
// Test Case #18
|
||||
// Invalid key in HSS signature
|
||||
new TestCase(
|
||||
new SignatureException(),
|
||||
@ -2458,7 +2539,7 @@ public class TestHSS {
|
||||
""")
|
||||
),
|
||||
|
||||
// Test Case #18
|
||||
// Test Case #19
|
||||
// LMS signature is too short
|
||||
new TestCase(
|
||||
new SignatureException(),
|
||||
@ -2485,7 +2566,7 @@ public class TestHSS {
|
||||
965a25bfd37f196b9073f3d4a232feb6""")
|
||||
),
|
||||
|
||||
// Test Case #19
|
||||
// Test Case #20
|
||||
// bad signature
|
||||
new TestCase(
|
||||
null, // exception
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user