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. * *

Java Card forbids {@code new} in {@code }, 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 }-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; } }