区块链 - 涉及的密码学基础

219 阅读8分钟

让我从基础开始,详细讲解每个密码学知识的原理:

一、哈希函数原理

原理: 将任意长度的输入转换为固定长度的输出 单向性:无法从哈希值反推原始数据 抗碰撞性:很难找到两个不同的输入产生相同的哈希值 区块链应用: 区块头的计算 交易ID的生成 工作量证明(PoW)中的计算

哈希函数 - 就像"榨果汁机"

想象你有一台特殊的"榨果汁机":

  • 无论你放入什么水果(苹果、橙子、一篮子水果),最后都会得到固定大小的一杯果汁
  • 一旦果汁榨出来,你永远无法还原出原来的水果
  • 即使只改变一小点原料,得到的果汁味道也会完全不同
# 简单示例
import hashlib

# 可以理解为往榨汁机放入苹果
message = "苹果"
# 开始榨汁
hash_value = hashlib.sha256(message.encode()).hexdigest()
print(f"果汁的味道是:{hash_value}")
/**
 * 1. SHA-256哈希原理
 */
object HashPrinciple {
    /*
    工作原理:
    1. 消息填充:将消息填充到512位的倍数
    2. 分块处理:将消息分成512位的块
    3. 压缩函数:对每个块进行多轮压缩运算
    4. 输出结果:生成256位(32字节)的哈希值
    */
    
    fun sha256Example() {
        // 1. 消息预处理
        val message = "Hello"
        val binaryMsg = message.toBinary()
        val paddedMsg = pad(binaryMsg)
        
        // 2. 分块
        val blocks = paddedMsg.chunked(512)
        
        // 3. 压缩函数处理
        var hash = INITIAL_HASH
        blocks.forEach { block ->
            hash = compress(block, hash)
        }
        
        // 4. 最终哈希值
        println("Hash: ${hash.toHex()}")
    }
}

/**
 * 哈希函数的数学原理
 */
class HashMath {
    // 压缩函数
    private fun compress(block: ByteArray, prevHash: ByteArray): ByteArray {
        // 1. 消息扩展
        val words = expandMessage(block)
        
        // 2. 轮函数
        var a = prevHash[0]
        var b = prevHash[1]
        // ... 进行64轮运算
        
        // 3. 返回新的哈希值
        return combineHash(a, b /*, ...*/)
    }
}

二、非对称加密原理

原理: 使用一对密钥:公钥和私钥 公钥加密,私钥解密 私钥签名,公钥验证 区块链应用: 数字签名 地址生成 身份认证

非对称加密 - 就像"特殊的锁和钥匙"

想象你有一个特殊的锁和钥匙系统:

  • 你有两把钥匙:一把是公开的(公钥),一把是私密的(私钥)
  • 公钥就像是一个可以分发给所有人的开锁盒子
  • 私钥就像是只有你自己知道的开锁密码
  • 任何人都可以用公钥加锁,但只有你用私钥才能解锁

生活中的例子:

  • 就像你的微信支付二维码(公钥),所有人都可以向你转账
  • 但只有你自己的密码(私钥)才能取钱
/**
 * 2. RSA加密原理
 */
object RSAPrinciple {
    /*
    基本原理:
    1. 密钥生成:
       - 选择两个大素数 p 和 q
       - 计算 n = p * q
       - 计算欧拉函数 φ(n) = (p-1)(q-1)
       - 选择公钥 e,满足 gcd(e, φ(n)) = 1
       - 计算私钥 d,满足 ed ≡ 1 (mod φ(n))
    
    2. 加密:c = m^e mod n
    3. 解密:m = c^d mod n
    */
    
    fun demonstrateRSA() {
        // 简化版RSA示例
        val p = 61L
        val q = 53L
        val n = p * q  // 3233
        val phi = (p - 1) * (q - 1)  // 3120
        val e = 17L  // 公钥
        val d = multiplicativeInverse(e, phi)  // 私钥
        
        // 加密消息
        val message = 65L
        val encrypted = fastModularExponentiation(message, e, n)
        
        // 解密消息
        val decrypted = fastModularExponentiation(encrypted, d, n)
        
        println("原始消息: $message")
        println("加密后: $encrypted")
        println("解密后: $decrypted")
    }
    
    // 快速模幂运算
    private fun fastModularExponentiation(
        base: Long,
        exponent: Long,
        modulus: Long
    ): Long {
        var result = 1L
        var b = base % modulus
        var exp = exponent
        
        while (exp > 0) {
            if (exp and 1L == 1L) {
                result = (result * b) % modulus
            }
            b = (b * b) % modulus
            exp = exp shr 1
        }
        return result
    }
}

三、数字签名原理

原理: 使用私钥对消息进行签名 任何人都可以使用公钥验证签名 确保消息完整性和不可否认性 区块链应用: 交易签名 智能合约执行确认

数字签名 - 就像"个人印章"

想象这是一个特殊的印章:

  • 这个印章只有你能盖(用私钥签名)
  • 但所有人都能验证这个印章是不是你盖的(用公钥验证)
  • 一旦盖上,任何人都无法修改文件内容

生活场景:

# 类似于在合同上盖章
document = "我同意转账100元给张三"
# 用私钥"盖章"
signature = sign_with_private_key(document)
# 任何人都可以验证这个"印章"是否真实
is_valid = verify_with_public_key(document, signature)
/**
 * 3. 数字签名原理
 */
object DigitalSignaturePrinciple {
    /*
    基本原理:
    1. 生成消息摘要(使用哈希函数)
    2. 使用私钥加密摘要生成签名
    3. 接收方使用公钥解密签名
    4. 比较解密后的摘要和原始消息的摘要
    */
    
    class SignatureProcess {
        fun sign(message: String, privateKey: PrivateKey): String {
            // 1. 生成消息摘要
            val messageDigest = MessageDigest.getInstance("SHA-256")
            val digest = messageDigest.digest(message.toByteArray())
            
            // 2. 使用私钥加密摘要
            val cipher = Cipher.getInstance("RSA")
            cipher.init(Cipher.ENCRYPT_MODE, privateKey)
            val signature = cipher.doFinal(digest)
            
            return Base64.getEncoder().encodeToString(signature)
        }
        
        fun verify(
            message: String,
            signature: String,
            publicKey: PublicKey
        ): Boolean {
            // 1. 解密签名
            val cipher = Cipher.getInstance("RSA")
            cipher.init(Cipher.DECRYPT_MODE, publicKey)
            val decryptedDigest = cipher.doFinal(
                Base64.getDecoder().decode(signature)
            )
            
            // 2. 计算原始消息的摘要
            val messageDigest = MessageDigest.getInstance("SHA-256")
            val calculatedDigest = messageDigest.digest(
                message.toByteArray()
            )
            
            // 3. 比较摘要
            return decryptedDigest.contentEquals(calculatedDigest)
        }
    }
}

四、Merkle树原理

原理: 所有交易的哈希值组成叶子节点 相邻节点配对并哈希,形成新的层级 最终得到一个根哈希值

默克尔树 - 就像"组织架构图"

想象一个公司的组织架构:

  • 最底层是普通员工(交易数据)
  • 中间是各级主管(中间哈希值)
  • 最顶层是总经理(根哈希值)

特点:

  • 如果有一个员工信息变化,会影响到他的主管,一直影响到总经理
  • 可以快速确认某个员工是否属于这个公司
/**
 * 4. Merkle树原理
 */
object MerkleTreePrinciple {
    /*
    基本原理:
    1. 叶子节点:数据块的哈希值
    2. 非叶子节点:子节点哈希值的组合哈希
    3. 根节点:整个树的根哈希值
    */
    
    class MerkleTreeImpl {
        data class Node(
            val hash: String,
            val left: Node? = null,
            val right: Node? = null
        )
        
        fun buildTree(data: List<String>): Node {
            // 1. 创建叶子节点
            val leaves = data.map { 
                Node(sha256Hash(it)) 
            }
            
            // 2. 构建树层
            return buildTreeLevels(leaves)
        }
        
        private fun buildTreeLevels(nodes: List<Node>): Node {
            if (nodes.size == 1) return nodes[0]
            
            val parents = mutableListOf<Node>()
            
            // 两两配对构建父节点
            for (i in nodes.indices step 2) {
                val left = nodes[i]
                val right = if (i + 1 < nodes.size) {
                    nodes[i + 1]
                } else {
                    left // 奇数个节点时复制最后一个
                }
                
                val parentHash = sha256Hash(left.hash + right.hash)
                parents.add(Node(parentHash, left, right))
            }
            
            return buildTreeLevels(parents)
        }
        
        // 验证数据是否在树中
        fun verifyProof(
            rootHash: String,
            data: String,
            proof: List<ProofNode>
        ): Boolean {
            var currentHash = sha256Hash(data)
            
            proof.forEach { node ->
                currentHash = if (node.isLeft) {
                    sha256Hash(node.hash + currentHash)
                } else {
                    sha256Hash(currentHash + node.hash)
                }
            }
            
            return currentHash == rootHash
        }
    }
}

五、零知识证明原理

原理: 证明者向验证者证明某个声明是真实的 不泄露任何除了声明真实性之外的信息 满足完整性、可靠性和零知识性 区块链应用: 隐私交易 身份验证 zk-SNARKs技术

零知识证明 - 就像"证明你有钱但不说具体多少"

生活例子:

  • 你要证明自己有能力买一辆车
  • 但你不想告诉别人具体有多少钱
  • 你可以向银行出示证明,银行确认后告诉车商:"是的,这个人有能力买车"
  • 整个过程中没人知道你具体有多少钱
/**
 * 5. 零知识证明原理
 */
object ZKProofPrinciple {
    /*
    基本原理(以Schnorr协议为例):
    1. 证明者知道离散对数
    2. 通过交互证明知道该值,但不泄露值本身
    */
    
    class SchnorrProtocol {
        // 系统参数
        val p = BigInteger("...") // 大素数
        val g = BigInteger("...") // 生成元
        
        fun prove(secretX: BigInteger): Proof {
            // 1. 承诺阶段
            val r = generateRandomNumber()
            val commitment = g.modPow(r, p)
            
            // 2. 挑战阶段
            val challenge = generateChallenge()
            
            // 3. 响应阶段
            val response = r.add(challenge.multiply(secretX))
                .mod(p.subtract(BigInteger.ONE))
            
            return Proof(commitment, challenge, response)
        }
        
        fun verify(
            publicKey: BigInteger,
            proof: Proof
        ): Boolean {
            // 验证等式:g^response = commitment * publicKey^challenge
            val left = g.modPow(proof.response, p)
            val right = proof.commitment.multiply(
                publicKey.modPow(proof.challenge, p)
            ).mod(p)
            
            return left == right
        }
    }
}

六、环签名原理

原理: 签名者可以代表一个群组进行匿名签名 无法确定具体是哪个成员进行的签名 保护交易隐私

环签名 - 就像"匿名投票"

想象一个班级投票:

  • 30个学生都可以投票
  • 每个人都知道投票是来自这个班
  • 但没人知道具体是谁投的票
/**
 * 6. 环签名原理
 */
object RingSignaturePrinciple {
    /*
    基本原理:
    1. 签名者使用自己的私钥和其他人的公钥
    2. 生成一个签名,无法确定是环中哪个人签的
    */
    
    class RingSignatureImpl {
        fun sign(
            message: String,
            publicKeys: List<PublicKey>,
            privateKey: PrivateKey,
            signerIndex: Int
        ): RingSignature {
            // 1. 为其他成员生成随机值
            val randomValues = generateRandomValues(publicKeys.size)
            
            // 2. 计算自己的签名片段
            val myFragment = calculateFragment(
                message,
                privateKey,
                randomValues[signerIndex]
            )
            
            // 3. 计算环签名
            val ringSignature = combineFragments(
                message,
                publicKeys,
                randomValues,
                myFragment,
                signerIndex
            )
            
            return RingSignature(ringSignature, randomValues)
        }
        
        fun verify(
            message: String,
            signature: RingSignature,
            publicKeys: List<PublicKey>
        ): Boolean {
            // 验证环签名的有效性
            return verifyRingSignature(
                message,
                signature,
                publicKeys
            )
        }
    }
}

七、同态加密原理

/**
 * 7. 同态加密原理
 */
object HomomorphicEncryptionPrinciple {
    /*
    基本原理:
    1. 加法同态:E(a) + E(b) = E(a + b)
    2. 乘法同态:E(a) * E(b) = E(a * b)
    */
    
    class PaillierCrypto {
        // Paillier加密系统实现
        fun keyGen(): KeyPair {
            // 1. 选择两个大素数
            val p = generateLargePrime()
            val q = generateLargePrime()
            
            // 2. 计算n和λ
            val n = p.multiply(q)
            val lambda = lcm(p.subtract(ONE), q.subtract(ONE))
            
            // 3. 选择生成元g
            val g = n.add(ONE)
            
            // 4. 计算μ
            val mu = lambda.modInverse(n)
            
            return KeyPair(
                PublicKey(n, g),
                PrivateKey(lambda, mu)
            )
        }
        
        fun encrypt(m: BigInteger, publicKey: PublicKey): BigInteger {
            // 选择随机数r
            val r = generateRandomNumber(publicKey.n)
            
            // 计算密文:c = g^m * r^n mod n^2
            return publicKey.g.modPow(m, publicKey.nSquared)
                .multiply(r.modPow(publicKey.n, publicKey.nSquared))
                .mod(publicKey.nSquared)
        }
        
        fun decrypt(
            c: BigInteger,
            privateKey: PrivateKey,
            publicKey: PublicKey
        ): BigInteger {
            // 解密:m = L(c^λ mod n^2) * μ mod n
            val x = c.modPow(privateKey.lambda, publicKey.nSquared)
            val L = x.subtract(ONE).divide(publicKey.n)
            return L.multiply(privateKey.mu).mod(publicKey.n)
        }
        
        // 加法同态
        fun add(
            c1: BigInteger,
            c2: BigInteger,
            publicKey: PublicKey
        ): BigInteger {
            return c1.multiply(c2).mod(publicKey.nSquared)
        }
    }
}

八、实际应用示例

/**
 * 8. 区块链中的综合应用
 */
class BlockchainCrypto {
    // 交易结构
    data class Transaction(
        val sender: String,
        val recipient: String,
        val amount: Double,
        val timestamp: Long
    ) {
        // 计算交易哈希
        fun calculateHash(): String {
            return sha256Hash("$sender$recipient$amount$timestamp")
        }
        
        // 签名交易
        fun sign(privateKey: PrivateKey): String {
            val hash = calculateHash()
            return signData(hash, privateKey)
        }
    }
    
    // 区块结构
    data class Block(
        val transactions: List<Transaction>,
        val previousHash: String,
        val timestamp: Long,
        val nonce: Long
    ) {
        // 计算区块哈希
        fun calculateHash(): String {
            val merkleRoot = calculateMerkleRoot(transactions)
            return sha256Hash(
                "$previousHash$merkleRoot$timestamp$nonce"
            )
        }
        
        // 构建默克尔树
        private fun calculateMerkleRoot(
            transactions: List<Transaction>
        ): String {
            val merkleTree = MerkleTree()
            return merkleTree.buildTree(
                transactions.map { it.calculateHash() }
            ).hash
        }
    }
    
    // 挖矿(工作量证明)
    fun mineBlock(block: Block, difficulty: Int): Block {
        var nonce = 0L
        var hash = block.calculateHash()
        
        while (!hash.startsWith("0".repeat(difficulty))) {
            nonce++
            hash = block.copy(nonce = nonce).calculateHash()
        }
        
        return block.copy(nonce = nonce)
    }
}

更生活化的例子:

  1. 比特币转账过程:
1. 小明想给小红转账
2. 小明用自己的私钥"盖章"(签名)
3. 所有人都可以用小明的公钥验证这笔转账是他发起的
4. 这笔转账被"榨成果汁"(计算哈希值)存入区块链
  1. 加密聊天:
小红想给小明发私密消息:
1. 用小明的公钥"锁上"消息
2. 只有小明用自己的私钥才能"解锁"看到消息

安全建议(大白话版):

  1. 私钥就像你的身份证,千万不能给别人
  2. 使用正规的加密方法,不要自己发明
  3. 定期更换密码,就像定期换锁一样
  4. 使用可靠的随机密码生成器
  5. 备份重要信息,但要安全存储

这些密码学原理在区块链中的应用:

  1. 交易安全性
  • 使用非对称加密保护交易内容
  • 数字签名确保交易真实性
  • 哈希函数维护交易历史完整性
  1. 区块链完整性
  • Merkle树验证交易集合
  • 哈希链接保证不可篡改
  • 工作量证明实现共识
  1. 隐私保护
  • 零知识证明实现匿名交易
  • 环签名保护身份隐私
  • 同态加密支持隐私计算
  1. 智能合约安全
  • 验证签名
  • 检查交易有效性
  • 保护合约状态

通过这些密码学技术的组合,区块链实现了:

  1. 去中心化信任
  2. 数据不可篡改
  3. 交易匿名性
  4. 系统透明性
  5. 网络安全性

记住:密码学就像我们生活中的锁、印章、保险箱,只是用数学的方式实现得更安全、更可靠!