Files
ccoin/server/utils/crypto/main.go
2025-12-23 17:38:27 -05:00

132 lines
3.8 KiB
Go

package crypto
import (
"crypto/sha256"
"fmt"
"ccoin/utils"
"strings"
)
var words = []string{
"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
func GenerateWalletAddress() string {
randomWord := words[utils.RandInt(0, len(words))]
randomDigits := fmt.Sprintf("%06d", utils.RandInt(0, 1000000))
return fmt.Sprintf("%s:%s", randomWord, randomDigits)
}
// Validates if an address follows the correct format
func IsValidAddress(address string) bool {
parts := strings.Split(address, ":")
if len(parts) != 2 {
return false
}
word := parts[0]
digits := parts[1]
return len(word) > 0 &&
utils.IsAlpha(word) &&
len(digits) == 6 &&
utils.IsDigit(digits)
}
// Generates SHA-256 hash of input string
func SHA256(input string) string {
hash := sha256.New()
hash.Write([]byte(input))
return fmt.Sprintf("%x", hash.Sum(nil))
}
// Hashes password
func HashPassword(password string) string {
return SHA256(fmt.Sprintf("ccoin_password_%s", password))
}
// Generates a transaction hash
func GenerateTransactionHash(fromAddress *string, toAddress string, amount float64, timestamp int64, nonce int64) string {
from := "genesis"
if fromAddress != nil {
from = *fromAddress
}
input := fmt.Sprintf("%s:%s:%f:%d:%d", from, toAddress, amount, timestamp, nonce)
return SHA256(input)
}
// Generates a block hash
func GenerateBlockHash(previousHash string, merkleRoot string, timestamp int64, difficulty int, nonce int64) string {
input := fmt.Sprintf("%s:%s:%d:%d:%d", previousHash, merkleRoot, timestamp, difficulty, nonce)
return SHA256(input)
}
// Validates if a hash meets the mining difficulty requirement
func IsValidHash(hash string, difficulty int) bool {
target := strings.Repeat("0", difficulty)
return strings.HasPrefix(hash, target)
}
// Generates mining job id
func GenerateJobId() string {
return SHA256(fmt.Sprintf("job:%d:%d", utils.GetCurrentTimeMillis(), utils.RandInt(0, 1<<63-1)))[:16]
}
// Calculate merkle root from transaction hashes
func CalculateMerkleRoot(transactionHashes []string) string {
if len(transactionHashes) == 0 {
return SHA256("empty")
}
if len(transactionHashes) == 1 {
return transactionHashes[0]
}
hashes := transactionHashes
for len(hashes) > 1 {
var newHashes []string
for i := 0; i < len(hashes); i += 2 {
left := hashes[i]
right := left // Default to left if there's no right
if i+1< len(hashes) {
right = hashes[i+1]
}
newHashes = append(newHashes, SHA256(fmt.Sprintf("%s:%s", left, right)))
}
hashes = newHashes
}
return hashes[0]
}
// Generates a random nonce for mining
func GenerateNonce() int64 {
return int64(utils.RandInt(0, 1<<63-1))
}
// Validates transaction hash format
func IsValidTransactionHash(hash string) bool {
return len(hash) == 64 && utils.IsHex(hash)
}
// Validates block hash format
func IsValidBlockHash(hash string) bool {
return len(hash) == 64 && utils.IsHex(hash)
}
// Verifies password hash
func VerifyPassword(password string, storedHash string) bool {
return HashPassword(password) == storedHash
}