c915c2b883
Allocation audit from Android benchmark showed 19 allocs in signSchnorr and 4 in verifySchnorr. Most were intermediate ByteArray/LongArray that can be replaced with pre-allocated scratch buffers. Changes: - Add sha256Into() (expect/actual) that writes digest into existing buffer instead of allocating a new ByteArray(32) per call. Uses MessageDigest.digest(buf,off,len) on JVM/Android, CC_SHA256 on Apple. - Add scratch byte buffers to PointScratch: hashBuf(256), bytesTmp1/2(32), scalarTmp1/2/3 for intermediate scalar results. - Add ScalarN.reduceTo() allocation-free variant. - Rewrite signSchnorrInternal to reuse scratch buffers for: - dBytes serialization (bytesTmp1 instead of U256.toBytes alloc) - AUX_PREFIX+auxrand hash (hashBuf instead of array concatenation) - auxHash XOR (scalarTmp1/2/3 instead of U256.fromBytes allocs) - nonce/challenge hash inputs (hashBuf instead of ByteArray alloc) - nonce scalar (scalarTmp1 instead of ScalarN.reduce alloc) - challenge scalar (scalarTmp3 instead of allocs) - e*d and k+e*d (splitK1/entryTmp2 instead of ScalarN.mul/add allocs) - Rewrite verifySchnorr to use hashBuf and sha256Into for challenge hash. Only the 64-byte output signature is allocated per sign call. Verify allocates nothing for 32-byte messages (hashBuf is large enough). https://claude.ai/code/session_01EMY5RnXb9rnsyU2KbXrSaY