Lattigo入门学习3

Lattigo之浮点数加解密

先简单回顾,CKKS(Cheon-Kim-Kim-Song)加密方案是一种在同态加密领域中广泛应用的方案,特别是在处理实数和复数上的计算时表现出了优异的性能。CKKS方案允许对编码后的近似实数或复数进行加密,然后进行同态加密操作(如加法和乘法),最后能够解密出一个近似的结果。这种加密方案特别适合用于需要处理大量实数数据的机器学习和数据分析场景。

CKKS方案的核心步骤是通过一系列复杂的代数和数论操作来实现的。下面是这个方案的关键步骤和相关公式的一个概览。请注意,实际的CKKS实现涉及更复杂的数学,并且这里的描述只是为了提供一个概念框架。

CKKS方案

1. 参数设置和密钥生成

首先,选择一个安全参数 λ λ λ,然后根据 λ λ λ 选择多项式的度数 N N N(通常是 2 2 2的幂)以及一系列模数 ( q 1 q_1 q1, q 2 q_2 q2, ..., q L q_L qL ) 来构建模数链。接下来,生成密钥对:

  • 私钥 sk: 随机选择一个小项多项式 ( s ∈ R ) ( s \in R ) (s∈R)。
  • 公钥 pk: 计算 ( ( p 0 , p 1 ) ) ( (p_0, p_1) ) ((p0,p1)) 其中 ( p 0 , p 1 ∈ R q ) ( p_0, p_1 \in R_q ) (p0,p1∈Rq) 并且 ( p 0 = − a s + e + Δ m ) ( p_0 = -as + e + \Delta m ) (p0=−as+e+Δm) (其中 ( a ) ( a ) (a) 是随机选择的, ( e ) ( e ) (e) 是一个小项误差多项式,( Δ \Delta Δ ) 是用来调整比例的大整数,以便于编码实数)。
2. 加密过程

加密一个复数向量 ( m ⃗ ) ( \vec{m} ) (m ) 的步骤如下:

  • 编码:首先,将复数向量 ( \\vec{m} ) 编码到一个多项式 ( m ( x ) ) ( m(x) ) (m(x)) 中。

  • 加密:然后计算密文 c = (c_0, c_1) 其中:

    c 0 = p 0 ⋅ r + e 0 + Δ ⋅ m ( x ) m o d    q \] \[ c_0 = p_0 \\cdot r + e_0 + \\Delta \\cdot m(x) \\mod q \] \[c0=p0⋅r+e0+Δ⋅m(x)modq

    c 1 = p 1 ⋅ r + e 1 m o d    q \] \[ c_1 = p_1 \\cdot r + e_1 \\mod q \] \[c1=p1⋅r+e1modq

    这里的 ( r r r ) 是随机选择的,( e 0 e_0 e0 ) 和 ( e_1 ) 是小项误差多项式。

3. 同态运算

CKKS方案支持同态加法和乘法:

  • 同态加法:给定两个密文 ( c\^{(1)} = (c_0\^{(1)}, c_1\^{(1)}) ) 和 ( c\^{(2)} = (c_0\^{(2)}, c_1\^{(2)}) ),它们的和为:

    c ( 1 + 2 ) = ( c 0 ( 1 ) + c 0 ( 2 ) , c 1 ( 1 ) + c 1 ( 2 ) ) \] \[ c\^{(1+2)} = (c_0\^{(1)} + c_0\^{(2)}, c_1\^{(1)} + c_1\^{(2)}) \] \[c(1+2)=(c0(1)+c0(2),c1(1)+c1(2))

  • 同态乘法:对于乘法,通常需要执行relinearization和rescaling步骤来保持密文的可管理大小。这里省略具体步骤的描述。

4. 解密过程

解密一个密文 ( c = ( c 0 , c 1 ) c = (c_0, c_1) c=(c0,c1) ),使用私钥 ( s ) 来计算:

m ( x ) = ( c 0 + c 1 ⋅ s ) m o d    q m o d    x N + 1 \] \[ m(x) = \\left( c_0 + c_1 \\cdot s \\right) \\mod q \\mod x\^N + 1 \] \[m(x)=(c0+c1⋅s)modqmodxN+1

然后从多项式 ( m(x) ) 中解码出原始的复数向量。

5. 解码

解码过程涉及到从多项式 ( m ( x ) m(x) m(x) ) 中恢复出编码前的向量 ( m ⃗ \vec{m} m )。这通常包括舍去多项式系数的缩放因子 ( Δ \Delta Δ ) 以及将多项式的系数转换回复数。

CKKS方案的详细实现比上述描述要复杂得多,在这里我只做简要回顾,有兴趣的还是读原文Homomorphic Encryption for Arithmetic of Approximate Numbers (iacr.org)

CKKS加解密浮点数实例

接下来我们具体实现一个CKKS加密的例子,我们随机生成 X X X向量和 Y Y Y向量,我们对两个变量执行 ( X − Y ) 2 (X-Y)^2 (X−Y)2并打印输出最终结果。

  • 声明参数和钥匙

    go 复制代码
    package main
    
    import (
    	"fmt"
    	"math/rand"
    
    	"github.com/tuneinsight/lattigo/v5/core/rlwe"
    	"github.com/tuneinsight/lattigo/v5/he/hefloat"
    )
    
    func main() {
    	//paramter
    	var err error
    	var params hefloat.Parameters
    
    	if params, err = hefloat.NewParametersFromLiteral(
    		hefloat.ParametersLiteral{
    			LogN:            14,                                    // log2(ring degree)
    			LogQ:            []int{55, 45, 45, 45, 45, 45, 45, 45}, // log2(primes Q) (ciphertext modulus)
    			LogP:            []int{61},                             // log2(primes P) (auxiliary modulus)
    			LogDefaultScale: 45,                                    // log2(scale)
    		}); err != nil {
    		panic(err)
    	}
    
    	// Key Generator
    	keygen := rlwe.NewKeyGenerator(params)
    	sk := keygen.GenSecretKeyNew()
    	encoder := hefloat.NewEncoder(params)
    	encryptor := rlwe.NewEncryptor(params, sk)
    	decryptor := rlwe.NewDecryptor(params, sk)
    
    	rlk := keygen.GenRelinearizationKeyNew(sk)
    	evk := rlwe.NewMemEvaluationKeySet(rlk)
    	evaluator := hefloat.NewEvaluator(params, evk)
  • 构造数据并加密

    go 复制代码
    // generate data
    	x := make([]float64, params.MaxSlots())
    	y := make([]float64, params.MaxSlots())
    
    	r1 := rand.New(rand.NewSource(0))
    	for i := range x {
    		x[i] = r1.Float64()
    	}
    
    	r2 := rand.New(rand.NewSource(1))
    	for i := range y {
    		y[i] = r2.Float64()
    	}
    
    	// encoder and encryptor
    	plaintext_x := hefloat.NewPlaintext(params, params.MaxLevel())
    	plaintext_y := hefloat.NewPlaintext(params, params.MaxLevel())
    	var ct_x *rlwe.Ciphertext
    	var ct_y *rlwe.Ciphertext
    
    	if err = encoder.Encode(x, plaintext_x); err != nil {
    		panic(err)
    	}
    	if err = encoder.Encode(y, plaintext_y); err != nil {
    		panic(err)
    	}
    
    	if ct_x, err = encryptor.EncryptNew(plaintext_x); err != nil {
    		panic(err)
    	}
    	if ct_y, err = encryptor.EncryptNew(plaintext_y); err != nil {
    		panic(err)
    	}
  • 进行密文计算

    go 复制代码
    	//(x-y)
    	var ct_sub *rlwe.Ciphertext
    	if ct_sub, err = evaluator.SubNew(ct_x, ct_y); err != nil {
    		panic(err)
    	}
    
    	//(x-y)^2
    	var ct_square *rlwe.Ciphertext
    	if ct_square, err = evaluator.MulRelinNew(ct_sub, ct_sub); err != nil {
    		panic(err)
    	}
  • 显示输出

    go 复制代码
    	//print x and y data
    	fmt.Printf("X: ")
    	for i := 0; i < 4; i++ {
    		fmt.Printf("%f ", x[i])
    	}
    	fmt.Println()
    
    	fmt.Printf("Y: ")
    	for i := 0; i < 4; i++ {
    		fmt.Printf("%f ", y[i])
    	}
    	fmt.Println()
    
    	//print x-y
    	pt_sub := decryptor.DecryptNew(ct_sub)
    	have := make([]float64, params.MaxSlots())
    	if err = encoder.Decode(pt_sub, have); err != nil {
    		panic(err)
    	}
    	fmt.Printf("X-Y: ")
    	for i := 0; i < 4; i++ {
    		fmt.Printf("%f ", have[i])
    	}
    	fmt.Println()
    
    	//print (x-y)^2
    	pt_square := decryptor.DecryptNew(ct_square)
    	if err = encoder.Decode(pt_square, have); err != nil {
    		panic(err)
    	}
    	fmt.Printf("(X-Y)^2: ")
    	for i := 0; i < 4; i++ {
    		fmt.Printf("%f ", have[i])
    	}
    	fmt.Println()
    }

通过这个例子,我们展现了一些基本的用法,当然基础的用法还包括一些操作比如evaluator.Add(),但其操作都比较类似,就不赘述了。

相关推荐
so2F32hj22 分钟前
一款Go语言Gin框架DDD脚手架,适合快速搭建项目
开发语言·golang·gin
LJianK127 分钟前
Java中的类、普通类,抽象类,接口的区别
java·开发语言
Dev7z28 分钟前
基于MATLAB的5G物理层文本传输系统仿真与性能分析
开发语言·5g·matlab
小智社群28 分钟前
贝壳获取小区的名称
开发语言·前端·javascript
lsx20240638 分钟前
Python3 OS模块详解
开发语言
LiLiYuan.1 小时前
【Java线程 vs 虚拟机线程】
java·开发语言
FlDmr4i281 小时前
.NET 10 & C# 14 New Features 新增功能介绍-扩展成员Extension Members
开发语言·c#·.net
原来是猿1 小时前
Linux进程信号详解(三):信号保存
开发语言·c++·算法
2402_881319301 小时前
跨服务通信兜底机制-Java 回传失败无持久重试队列,报告可能静默丢失。
java·开发语言·python
格林威1 小时前
SSD 写入速度测试命令(Linux)(基于工业相机高速存储)
linux·运维·开发语言·人工智能·数码相机·计算机视觉·工业相机