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/test/java/org/elasticsearch/index/store/StoreTests.java
}
        try {
            if (randomBoolean()) {
                store.getMetadata(null);
            } else {
                store.readLastCommittedSegmentsInfo();
            }
            fail("corrupted segments_N file");
        } catch (CorruptIndexException ex) {
            
        }
        assertTrue(store.isMarkedCorrupted());
        
        Lucene.cleanLuceneIndex(store.directory());
        store.close();
    }
    public void testCanOpenIndex() throws IOException {
        final ShardId shardId = new ShardId("index", "_na_", 1);
        IndexWriterConfig iwc = newIndexWriterConfig();
        Path tempDir = createTempDir();
        final BaseDirectoryWrapper dir = newFSDirectory(tempDir);
        assertFalse(StoreUtils.canOpenIndex(logger, tempDir, shardId, (id, l, d) -> new DummyShardLock(id)));
        IndexWriter writer = new IndexWriter(dir, iwc);
        Document doc = new Document();
        doc.add(new StringField("id", "1", random().nextBoolean() ? Field.Store.YES : Field.Store.NO));
        writer.addDocument(doc);
        writer.commit();
        writer.close();
        assertTrue(StoreUtils.canOpenIndex(logger, tempDir, shardId, (id, l, d) -> new DummyShardLock(id)));
        Store store = new Store(shardId, INDEX_SETTINGS, dir, new DummyShardLock(shardId));