package com.dangerousthings.aliro;

/**
 * Lazy holders for crypto objects shared between {@link AliroApplet} and
 * {@link StepUpApplet}. Both applets live in the same package and only one
 * is selected at a time, so the shared instances are safe — Java Card runs
 * one applet at a time and the JCRE serializes APDU dispatch.
 *
 * <p>Java Card forbids {@code new} in {@code <clinit>}, so the getter lazy-
 * creates on first call. Subsequent calls return the cached instance. The
 * combined transient footprint of one shared {@link AliroCrypto} is roughly
 * 352 B (kdfWorkbuf 64 + hkdfPrevT 32 + expandScratch 256); without this
 * sharing each applet would allocate its own.
 */
final class CryptoSingletons {

    private static AliroCrypto aliroCrypto;
    private static AliroGcm aliroGcm;

    private CryptoSingletons() { }

    /** Returns the process-wide {@link AliroCrypto} instance. Allocates on
     *  first call; cheap thereafter. */
    static AliroCrypto getAliroCrypto() {
        if (aliroCrypto == null) {
            aliroCrypto = new AliroCrypto();
        }
        return aliroCrypto;
    }

    /** Returns the process-wide {@link AliroGcm} instance. Same Java-Card
     *  {@code <clinit>}-cannot-{@code new} rationale as {@link #getAliroCrypto()}:
     *  lazy-allocate on first call so both {@link AliroApplet} and
     *  {@link StepUpApplet} share one userland-GCM machine. Each shared
     *  instance saves ~370 B of transient/EEPROM footprint that a per-applet
     *  duplicate would otherwise pay. The two applets are never selected
     *  simultaneously and the JCRE serializes APDU dispatch, so the shared
     *  scratch and {@code AESKey} slot don't race. */
    static AliroGcm getAliroGcm() {
        if (aliroGcm == null) {
            aliroGcm = new AliroGcm();
        }
        return aliroGcm;
    }
}
