As mentioned in https://github.com/elastic/elasticsearch/pull/96216, `LuceneVerifyingIndexOutput` always copies the last chunk byte-by-byte. This might be a pretty big chunk. We should be able to copy all the bytes up to the start of the checksum in bulk (and then I guess bulk-copy the checksum too not that this matters so much).

In the same area, `LuceneVerifyingIndexOutput` is the only subclass of `VerifyingIndexOutput` and there's no need for it to be an inner class of `Store`. `VerifyingIndexInput` also doesn't need to be an inner class.
server/src/main/java/org/elasticsearch/index/store/Store.java
final int index = Math.toIntExact(writtenBytes - checksumPosition);
                if (index < footerChecksum.length) {
                    footerChecksum[index] = b;
                    if (index == footerChecksum.length - 1) {
                        verify(); 
                    }
                } else {
                    verify(); 
                    throw new AssertionError("write past EOF expected length: " + metadata.length() + " writtenBytes: " + writtenBytes);
                }
            }
            out.writeByte(b);
        }
        private void readAndCompareChecksum() throws IOException {
            actualChecksum = digestToString(getChecksum());
            if (metadata.checksum().equals(actualChecksum) == false) {
                throw new CorruptIndexException(
                    "checksum failed (hardware problem?) : expected="
                        + metadata.checksum()
                        + " actual="
                        + actualChecksum
                        + " (resource="
                        + metadata.toString()
                        + ")",
                    "VerifyingIndexOutput(" + metadata.name() + ")"
                );
            }
        }
        @Override
        public void writeBytes(byte[] b, int offset, int length) throws IOException {