refactor(quartz): FsLayout.sha256Hex routes through Quartz utils
Replace the inline MessageDigest + hand-rolled hex converter with quartz.utils.sha256.sha256 + quartz.utils.Hex.encode. Same output (deterministic algorithm), but we stop duplicating primitives that already exist in the codebase. One fewer JCA dependency, one fewer hex-conversion implementation to audit. All 113 fs tests still green, including FsParityTest vs the SQLite reference — the d-tag slot paths are byte-identical to before.
This commit is contained in:
@@ -22,11 +22,12 @@ package com.vitorpamplona.quartz.nip01Core.store.fs
|
|||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Kind
|
import com.vitorpamplona.quartz.nip01Core.core.Kind
|
||||||
|
import com.vitorpamplona.quartz.utils.Hex
|
||||||
|
import com.vitorpamplona.quartz.utils.sha256.sha256
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
import java.security.MessageDigest
|
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import kotlin.io.path.exists
|
import kotlin.io.path.exists
|
||||||
|
|
||||||
@@ -195,20 +196,15 @@ internal class FsLayout(
|
|||||||
const val SEED_FILE = ".seed"
|
const val SEED_FILE = ".seed"
|
||||||
const val JSON_EXT = ".json"
|
const val JSON_EXT = ".json"
|
||||||
|
|
||||||
/** Lowercase hex SHA-256 of the given UTF-8 string. Used for d-tag slots. */
|
/**
|
||||||
fun sha256Hex(s: String): String {
|
* Lowercase hex SHA-256 of the given UTF-8 string. Used for
|
||||||
val md = MessageDigest.getInstance("SHA-256")
|
* addressable d-tag slots and d-tag-scoped tombstones — needs
|
||||||
val bytes = md.digest(s.encodeToByteArray())
|
* cryptographic collision resistance because the filename IS the
|
||||||
val sb = StringBuilder(bytes.size * 2)
|
* NIP-01 `UNIQUE(kind, pubkey, d)` constraint. Reuses the shared
|
||||||
for (b in bytes) {
|
* Quartz primitives ([sha256], [Hex.encode]) so behaviour matches
|
||||||
val v = b.toInt() and 0xff
|
* the rest of the codebase on every KMP target.
|
||||||
sb.append(HEX[v ushr 4])
|
*/
|
||||||
sb.append(HEX[v and 0x0f])
|
fun sha256Hex(s: String): String = Hex.encode(sha256(s.encodeToByteArray()))
|
||||||
}
|
|
||||||
return sb.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val HEX = "0123456789abcdef".toCharArray()
|
|
||||||
|
|
||||||
/** zero-padded to 10 digits so lex order == chronological order through year 2286. */
|
/** zero-padded to 10 digits so lex order == chronological order through year 2286. */
|
||||||
fun tsPad(ts: Long): String = ts.toString().padStart(TS_PAD_WIDTH, '0')
|
fun tsPad(ts: Long): String = ts.toString().padStart(TS_PAD_WIDTH, '0')
|
||||||
|
|||||||
Reference in New Issue
Block a user