feat: added crypto utils

This commit is contained in:
darwincereska
2025-12-17 10:02:51 -05:00
parent 87d094e2f1
commit f818b38b3d

View File

@@ -0,0 +1,123 @@
package org.ccoin.utils
import java.security.MessageDigest
import java.security.SecureRandom
import kotlin.random.Random
object CryptoUtils {
private val secureRandom = SecureRandom()
// Word list for address generation
private val words = listOf(
"phoenix", "dragon", "tiger", "eagle", "wolf", "lion", "bear", "shark",
"falcon", "raven", "cobra", "viper", "panther", "jaguar", "leopard", "cheetah",
"thunder", "lightning", "storm", "blizzard", "tornado", "hurricane", "cyclone", "tempest",
"crystal", "diamond", "emerald", "ruby", "sapphire", "topaz", "amethyst", "opal",
"shadow", "ghost", "phantom", "spirit", "wraith", "specter", "demon", "angel",
"fire", "ice", "earth", "wind", "water", "metal", "wood", "void",
"star", "moon", "sun", "comet", "meteor", "galaxy", "nebula", "cosmos",
"blade", "sword", "arrow", "spear", "shield", "armor", "crown", "throne",
"mountain", "ocean", "forest", "desert", "valley", "river", "lake", "cave",
"knight", "warrior", "mage", "archer", "rogue", "paladin", "wizard", "sage"
)
/**
* Generates a wallet address in format: random_word:random_6_digits
* Example: "phoenix:123456", "dragon:654321"
*/
fun generateWalletAddress(): String {
val randomWord = words[secureRandom.nextInt(words.size)]
val randomDigits = String.format("%06d", secureRandom.nextInt(1000000))
return "$randomWord:$randomDigits"
}
/** Validates if an address follows the correct format */
fun isValidAddress(address: String): Boolean {
val parts = address.split(":")
if (parts.size != 2) return false
val word = parts[0]
val digits = parts[1]
return word.isNotEmpty() &&
word.all { it.isLetter() } &&
digits.length == 6 &&
digits.all { it.isDigit() }
}
/** Generates SHA-256 hash of input string */
fun sha256(input: String): String {
return MessageDigest.getInstance("SHA-256")
.digest(input.toByteArray())
.joinToString("") { "%02x".format(it) }
}
/** Generates a transaction hash */
fun generateTransactionHash(
fromAddress: String?,
toAddress: String,
amount: Double,
timestamp: Long,
nonce: Long = secureRandom.nextLong()
): String {
val input = "${fromAddress ?: "genesis"}:$toAddress:$amount:$timestamp:$nonce"
return sha256(input)
}
/** Generates a block hash */
fun generateBlockHash(
previousHash: String,
merkleRoot: String,
timestamp: Long,
difficulty: Int,
nonce: Long
): String {
val input = "$previousHash:$merkleRoot:$timestamp:$difficulty:$nonce"
return sha256(input)
}
/** Validates if a hash meets the mining difficulty requirement */
fun isValidHash(hash: String, difficulty: Int): Boolean {
val target = "0".repeat(difficulty)
return hash.startsWith(target)
}
/** Generates a mining job id */
fun generateJobId(): String = sha256("job:${System.currentTimeMillis()}:${secureRandom.nextLong()}").take(16)
/** Calculates a merkle root from transaction hashes */
fun calculateMerkleRoot(transactionHashes: List<String>): String {
if (transactionHashes.isEmpty()) {
return sha256("empty")
}
if (transactionHashes.size == 1) {
return transactionHashes[0]
}
var hashes = transactionHashes.toMutableList()
while (hashes.size > 1) {
val newHashes = mutableListOf<String>()
for (i in hashes.indices step 2) {
val left = hashes[i]
val right = if (i + 1 < hashes.size) hashes[i + 1] else left
newHashes.add(sha256("$left:$right"))
}
hashes = newHashes
}
return hashes[0]
}
/** Generates a random nonce for mining */
fun generateNonce(): Long = secureRandom.nextLong()
/** Validates transaction hash format */
fun isValidTransactionHash(hash: String): Boolean = hash.length == 64 && hash.all { it.isDigit() || it.lowercaseChar() in 'a'..'f' }
/** Validates block has format */
fun isValidBlockHash(hash: String): Boolean = hash.length == 64 && hash.all { it.isDigit() || it.lowercaseChar() in 'a'..'f' }
}