

全同态加密(FHE)是一个强大的加密基元,可以在不接触到秘密密钥的情况下对加密数据进行计算。OpenFHE 是一个开源的 FHE 库,包括所有常见 FHE 方案的有效实现:
OpenFHE 还包括以下 FHE 的多方扩展:
OpenFHE 实现了高效的剩余数系统 (RNS) 算法以实现高性能。

https://eprint.iacr.org/2020/086.pdf
FHEW 和 TFHE 是完全同态加密 (FHE) 密码系统,可以在每次门评估后通过自举来评估加密数据上的任意布尔电路。 FHEW 密码系统最初是基于标准(环形、循环安全)LWE 假设设计的,其初始实现能够在不到 1 秒的时间内运行自举。 TFHE 密码系统使用了一些更强的假设,例如(环,循环安全)LWE 在具有二进制秘密分布的环上,并应用了一些其他优化来将引导运行时间减少到小于 0.1 秒。
我们提出了一个统一的框架,包括 FHEW 和 TFHE 密码系统的原始和扩展变体,并在开源的 PALISADE 格密码学库中使用模块化算术来实现它。我们的分析表明,这些密码系统之间的主要区别在于所使用的引导程序。FHEW 的 Alperin-Sherif-Peikert(AP)与 TFHE 的 Gama-Izabachene-Nguyen-Xie(GINX)。TFHE 的所有其他算法优化同样适用于两个密码系统。GINX 的引导方法必须使用二进制秘密,不能直接应用于其他秘密分布。在比较这两种方案的过程中,我们提出了一种简单、轻量级的方法,将 GINX 引导法(例如 TFHE 所采用的方法)扩展到三元均匀和高斯秘密分布,这些秘密分布包括在 HE 社区安全标准中。我们对不同秘密分布的 AP 和 GINX 引导方法的比较表明,TFHE/GINX 密码系统对二元和三元秘密提供了更好的性能,而 FHEW/AP 对高斯秘密更快。我们建议考虑基于三元和高斯秘密的 FHEW 和 TFHE 密码系统的变体,以便由 HE 社区进行标准化。
虚拟机运行(4 核 4gb 内存)


// First plaintext vector is encoded
std::vector<int64_t> vectorOfInts1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
Plaintext plaintext1 = cryptoContext->MakePackedPlaintext(vectorOfInts1);
// The encoded vectors are encrypted
std::stringstream s2;
//Serial::Serialize(plaintext1, s1, SerType::BINARY);
Serial::Serialize(ciphertext1, s2, SerType::BINARY);
//std::cout <<"good"<<std::endl;
std::cout <<"The extended times is "<<(double)(sizeof(s2)/sizeof(plaintext1))<<std::endl; //24
std::cout <<sizeof(s2)<<std::endl; //392
//std::cout <<(double)(sizeof(s2)/sizeof(vectorOfInts1))<<std::endl;













安全系数:TOY, MEDIUM, STD128, STD192, and STD256





void RunBGVrnsAdditive() {
CCParams<CryptoContextBGVRNS> parameters;
parameters.SetPlaintextModulus(65537);
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
// Enable features that you wish to use
//启动模块
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
cc->Enable(ADVANCEDSHE);
cc->Enable(MULTIPARTY);
// Set-up of parameters
// Print out the parameters
//输出参数
std::cout << "p = " << cc->GetCryptoParameters()->GetPlaintextModulus() << std::endl;
std::cout << "n = " << cc->GetCryptoParameters()->GetElementParams()->GetCyclotomicOrder() / 2 << std::endl;
std::cout << "log2 q = " << log2(cc->GetCryptoParameters()->GetElementParams()->GetModulus().ConvertToDouble())
<< std::endl;
// Initialize Public Key Containers for 3 parties
//初始化三个密钥
KeyPair<DCRTPoly> kp1;
KeyPair<DCRTPoly> kp2;
KeyPair<DCRTPoly> kp3;
KeyPair<DCRTPoly> kpMultiparty;
// Perform Key Generation Operation
std::cout << "Running key generation (used for source data)..." << std::endl;
// generate the public key for first share
//生成第一个密钥kp1
kp1 = cc->KeyGen();
// generate the public key for two shares
//利用kp1的公钥生成密钥kp2
kp2 = cc->MultipartyKeyGen(kp1.publicKey);
// generate the public key for all three secret shares
//利用kp2的公钥生成密钥kp3
kp3 = cc->MultipartyKeyGen(kp2.publicKey);
if (!kp1.good()) {
std::cout << "Key generation failed!" << std::endl;
exit(1);
}
if (!kp2.good()) {
std::cout << "Key generation failed!" << std::endl;
exit(1);
}
if (!kp3.good()) {
std::cout << "Key generation failed!" << std::endl;
exit(1);
}
// Encode source data
std::vector<int64_t> vectorOfInts1 = {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
std::vector<int64_t> vectorOfInts2 = {1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0};
std::vector<int64_t> vectorOfInts3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0};
Plaintext plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
Plaintext plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
Plaintext plaintext3 = cc->MakePackedPlaintext(vectorOfInts3);
// Encryption
//加密
Ciphertext<DCRTPoly> ciphertext1;
Ciphertext<DCRTPoly> ciphertext2;
Ciphertext<DCRTPoly> ciphertext3;
//全部都用kp3来加密明文
ciphertext1 = cc->Encrypt(kp3.publicKey, plaintext1);
ciphertext2 = cc->Encrypt(kp3.publicKey, plaintext2);
ciphertext3 = cc->Encrypt(kp3.publicKey, plaintext3);
// EvalAdd Operation on Re-Encrypted Data
Ciphertext<DCRTPoly> ciphertextAdd12;
Ciphertext<DCRTPoly> ciphertextAdd123;
ciphertextAdd12 = cc->EvalAdd(ciphertext1, ciphertext2);
ciphertextAdd123 = cc->EvalAdd(ciphertextAdd12, ciphertext3);
// Decryption after Accumulation Operation on Encrypted Data with Multiparty
Plaintext plaintextAddNew1;
Plaintext plaintextAddNew2;
Plaintext plaintextAddNew3;
DCRTPoly partialPlaintext1;
DCRTPoly partialPlaintext2;
DCRTPoly partialPlaintext3;
Plaintext plaintextMultipartyNew;
const std::shared_ptr<CryptoParametersBase<DCRTPoly>> cryptoParams = kp1.secretKey->GetCryptoParameters();
const std::shared_ptr<typename DCRTPoly::Params> elementParams = cryptoParams->GetElementParams();
//部分解密
// partial decryption by first party
//kp1用kp1私钥解密part1(kp1解密叫Lead,kp2\kp3解密叫Main)
auto ciphertextPartial1 = cc->MultipartyDecryptLead({ciphertextAdd123}, kp1.secretKey);
// partial decryption by second party
//kp2用kp2私钥解密part2
auto ciphertextPartial2 = cc->MultipartyDecryptMain({ciphertextAdd123}, kp2.secretKey);
// partial decryption by third party
//kp3用kp3私钥解密part3
auto ciphertextPartial3 = cc->MultipartyDecryptMain({ciphertextAdd123}, kp3.secretKey);
std::vector<Ciphertext<DCRTPoly>> partialCiphertextVec;
partialCiphertextVec.push_back(ciphertextPartial1[0]);
partialCiphertextVec.push_back(ciphertextPartial2[0]);
partialCiphertextVec.push_back(ciphertextPartial3[0]);
// partial decryptions are combined together
// 合并所有的part
cc->MultipartyDecryptFusion(partialCiphertextVec, &plaintextMultipartyNew);
std::cout << "\n Original Plaintext: \n" << std::endl;
std::cout << plaintext1 << std::endl;
std::cout << plaintext2 << std::endl;
std::cout << plaintext3 << std::endl;
plaintextMultipartyNew->SetLength(plaintext1->GetLength());
std::cout << "\n Resulting Fused Plaintext adding 3 ciphertexts: \n" << std::endl;
std::cout << plaintextMultipartyNew << std::endl;
std::cout << "\n";
}





void RunCKKS() {
usint batchSize = 16;
CCParams<CryptoContextCKKSRNS> parameters;
parameters.SetMultiplicativeDepth(3);
parameters.SetScalingModSize(50);
parameters.SetBatchSize(batchSize);
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
// enable features that you wish to use
//启动模块
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
cc->Enable(ADVANCEDSHE);
cc->Enable(MULTIPARTY);
// Set-up of parameters
// 设置参数
// Output the generated parameters
std::cout << "p = " << cc->GetCryptoParameters()->GetPlaintextModulus() << std::endl;
std::cout << "n = " << cc->GetCryptoParameters()->GetElementParams()->GetCyclotomicOrder() / 2 << std::endl;
std::cout << "log2 q = " << log2(cc->GetCryptoParameters()->GetElementParams()->GetModulus().ConvertToDouble())
<< std::endl;
// Initialize Public Key Containers
KeyPair<DCRTPoly> kp1;
KeyPair<DCRTPoly> kp2;
KeyPair<DCRTPoly> kpMultiparty;
// Perform Key Generation Operation
// 密钥生成
std::cout << "Running key generation (used for source data)..." << std::endl;
// Round 1 (party A)
// 第一轮(A产生)
std::cout << "Round 1 (party A) started." << std::endl;
// 生成 kp1
kp1 = cc->KeyGen();
// Generate evalmult key part for A
// 由kp1的secretKey生成evalMultKey
auto evalMultKey = cc->KeySwitchGen(kp1.secretKey, kp1.secretKey);
// Generate evalsum key part for A
// 由kp1的secretKey生成evalsum key——evalsum表示向量求后面所有值的和
cc->EvalSumKeyGen(kp1.secretKey);
auto evalSumKeys =
std::make_shared<std::map<usint, EvalKey<DCRTPoly>>>(cc->GetEvalSumKeyMap(kp1.secretKey->GetKeyTag()));
std::cout << "Round 1 of key generation completed." << std::endl;
// Round 2 (party B)
// 第二轮(B产生)
std::cout << "Round 2 (party B) started." << std::endl;
std::cout << "Joint public key for (s_a + s_b) is generated..." << std::endl;
// 由kp1的publicKey生成kp2
kp2 = cc->MultipartyKeyGen(kp1.publicKey);
// 由kp2的secretKey生成 evalMultKey2
auto evalMultKey2 = cc->MultiKeySwitchGen(kp2.secretKey, kp2.secretKey, evalMultKey);
std::cout << "Joint evaluation multiplication key for (s_a + s_b) is generated..." << std::endl;
// 由kp2的evalMultKey2和kp1的evalMultKey生成 evalMultAB
auto evalMultAB = cc->MultiAddEvalKeys(evalMultKey, evalMultKey2, kp2.publicKey->GetKeyTag());
std::cout << "Joint evaluation multiplication key (s_a + s_b) is transformed "
"into s_b*(s_a + s_b)..."
<< std::endl;
//由kp2的secretKey和publickey把evalMultAB 转换为 evalMultBAB
auto evalMultBAB = cc->MultiMultEvalKey(kp2.secretKey, evalMultAB, kp2.publicKey->GetKeyTag());
//由kp2的secretKey和publickey 由kp1的evalSumKeys 生成 evalSumKeysB
auto evalSumKeysB = cc->MultiEvalSumKeyGen(kp2.secretKey, evalSumKeys, kp2.publicKey->GetKeyTag());
std::cout << "Joint evaluation summation key for (s_a + s_b) is generated..." << std::endl;
//由kp2的evalSumKeysB和publickey 以及 kp1的evalSumKeys 生成最终的 evalSumKeysJoin key
auto evalSumKeysJoin = cc->MultiAddEvalSumKeys(evalSumKeys, evalSumKeysB, kp2.publicKey->GetKeyTag());
cc->InsertEvalSumKey(evalSumKeysJoin);
std::cout << "Round 2 of key generation completed." << std::endl;
// 第三轮(A产生)
std::cout << "Round 3 (party A) started." << std::endl;
std::cout << "Joint key (s_a + s_b) is transformed into s_a*(s_a + s_b)..." << std::endl;
//由kp1的secretKey和kp2的publickey把evalMultAB 转换为 evalMultAAB
auto evalMultAAB = cc->MultiMultEvalKey(kp1.secretKey, evalMultAB, kp2.publicKey->GetKeyTag());
std::cout << "Computing the final evaluation multiplication key for (s_a + "
"s_b)*(s_a + s_b)..."
<< std::endl;
//由kp1的evalMultAAB和kp2的evalMultBAB 以及公开的evalMultAB 转换为 evalMultFinal
auto evalMultFinal = cc->MultiAddEvalMultKeys(evalMultAAB, evalMultBAB, evalMultAB->GetKeyTag());
cc->InsertEvalMultKey({evalMultFinal});
std::cout << "Round 3 of key generation completed." << std::endl;
// Encode source data
std::vector<double> vectorOfInts1 = {1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 0};
std::vector<double> vectorOfInts2 = {1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0};
std::vector<double> vectorOfInts3 = {2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0};
Plaintext plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
Plaintext plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
Plaintext plaintext3 = cc->MakeCKKSPackedPlaintext(vectorOfInts3);
// Encryption
Ciphertext<DCRTPoly> ciphertext1;
Ciphertext<DCRTPoly> ciphertext2;
Ciphertext<DCRTPoly> ciphertext3;
// 用kp2.publickey加密
ciphertext1 = cc->Encrypt(kp2.publicKey, plaintext1);
ciphertext2 = cc->Encrypt(kp2.publicKey, plaintext2);
ciphertext3 = cc->Encrypt(kp2.publicKey, plaintext3);
// EvalAdd Operation on Re-Encrypted Data
Ciphertext<DCRTPoly> ciphertextAdd12;
Ciphertext<DCRTPoly> ciphertextAdd123;
ciphertextAdd12 = cc->EvalAdd(ciphertext1, ciphertext2);
ciphertextAdd123 = cc->EvalAdd(ciphertextAdd12, ciphertext3);
auto ciphertextMultTemp = cc->EvalMult(ciphertext1, ciphertext3);
auto ciphertextMult = cc->ModReduce(ciphertextMultTemp);
auto ciphertextEvalSum = cc->EvalSum(ciphertext3, batchSize);
// Decryption after Accumulation Operation on Encrypted Data with Multiparty
Plaintext plaintextAddNew1;
Plaintext plaintextAddNew2;
Plaintext plaintextAddNew3;
DCRTPoly partialPlaintext1;
DCRTPoly partialPlaintext2;
DCRTPoly partialPlaintext3;
Plaintext plaintextMultipartyNew;
const std::shared_ptr<CryptoParametersBase<DCRTPoly>> cryptoParams = kp1.secretKey->GetCryptoParameters();
const std::shared_ptr<typename DCRTPoly::Params> elementParams = cryptoParams->GetElementParams();
// distributed decryption
//各自用自己的secretkey解密(kp1解密叫Lead,kp2解密叫Main)
auto ciphertextPartial1 = cc->MultipartyDecryptLead({ciphertextAdd123}, kp1.secretKey);
auto ciphertextPartial2 = cc->MultipartyDecryptMain({ciphertextAdd123}, kp2.secretKey);
std::vector<Ciphertext<DCRTPoly>> partialCiphertextVec;
partialCiphertextVec.push_back(ciphertextPartial1[0]);
partialCiphertextVec.push_back(ciphertextPartial2[0]);
//合并密钥
cc->MultipartyDecryptFusion(partialCiphertextVec, &plaintextMultipartyNew);
std::cout << "\n Original Plaintext: \n" << std::endl;
std::cout << plaintext1 << std::endl;
std::cout << plaintext2 << std::endl;
std::cout << plaintext3 << std::endl;
plaintextMultipartyNew->SetLength(plaintext1->GetLength());
std::cout << "\n Resulting Fused Plaintext: \n" << std::endl;
std::cout << plaintextMultipartyNew << std::endl;
std::cout << "\n";
Plaintext plaintextMultipartyMult;
//(kp1解密叫Lead,kp2解密叫Main)
ciphertextPartial1 = cc->MultipartyDecryptLead({ciphertextMult}, kp1.secretKey);
ciphertextPartial2 = cc->MultipartyDecryptMain({ciphertextMult}, kp2.secretKey);
std::vector<Ciphertext<DCRTPoly>> partialCiphertextVecMult;
partialCiphertextVecMult.push_back(ciphertextPartial1[0]);
partialCiphertextVecMult.push_back(ciphertextPartial2[0]);
cc->MultipartyDecryptFusion(partialCiphertextVecMult, &plaintextMultipartyMult);
plaintextMultipartyMult->SetLength(plaintext1->GetLength());
std::cout << "\n Resulting Fused Plaintext after Multiplication of plaintexts 1 "
"and 3: \n"
<< std::endl;
std::cout << plaintextMultipartyMult << std::endl;
std::cout << "\n";
Plaintext plaintextMultipartyEvalSum;
ciphertextPartial1 = cc->MultipartyDecryptLead({ciphertextEvalSum}, kp1.secretKey);
ciphertextPartial2 = cc->MultipartyDecryptMain({ciphertextEvalSum}, kp2.secretKey);
std::vector<Ciphertext<DCRTPoly>> partialCiphertextVecEvalSum;
partialCiphertextVecEvalSum.push_back(ciphertextPartial1[0]);
partialCiphertextVecEvalSum.push_back(ciphertextPartial2[0]);
cc->MultipartyDecryptFusion(partialCiphertextVecEvalSum, &plaintextMultipartyEvalSum);
plaintextMultipartyEvalSum->SetLength(plaintext1->GetLength());
std::cout << "\n Fused result after the Summation of ciphertext 3: "
"\n"
<< std::endl;
std::cout << plaintextMultipartyEvalSum << std::endl;
}






?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
目录H2数据库入门以及实际开发时的使用1.H2数据库的初识1.1H2数据库介绍1.2为什么要使用嵌入式数据库?1.3嵌入式数据库对比1.3.1性能对比1.4技术选型思考2.H2数据库实战2.1H2数据库下载搭建以及部署2.1.1H2数据库的下载2.1.2数据库启动2.1.2.1windows系统可以在bin目录下执行h2.bat2.1.2.2同理可以通过cmd直接使用命令进行启动:2.1.2.3启动后控制台页面:2.1.3spring整合H2数据库2.1.3.1引入依赖文件2.1.4数据库通过file模式实际保存数据的位置2.2H2数据库操作2.2.1Mysql兼容模式2.2.2Mysql模式
为什么需要服务网关传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网关,客户端只能在本地记录每个微服务的调用地址,当需要调用的微服务数量很多时,它需要了解每个服务的接口,这个工作量很大。有了网关之后,网关作为系统的唯一流量入口,封装内部系统的架构,所有请求都先经过网关,由网关将请求路由到合适的微服务。使用网关的好处1)简化客户端的工作。网关将微服务封装起来后,客户端只需同网关交互,而不必调用各个不同服务;(2)降低函数间的耦合度。一旦服务接口修改,只需修改网关的路由策略,不必修改每个调用该函数的客户端,从而减少了程序间的耦合性(3)解放开发
我发现python的细节自动完成很好RubyonRails有类似的方法描述吗? 最佳答案 有篇不错的文章"UsingVIMasacompleteRubyonRailsIDE"其中引用rails.vim.这似乎是RailsforVIM的实际标准。(不过,我还没有使用过它,但很快就会尝试。)这允许你做很多与Rails相关的任务,但对自动完成没有帮助。还有一篇"RubyAutocompleteinVim"(遗憾的是不再可用)这就是您要搜索的内容。我不知道,理解Rails的所有插件魔法和元编程的东西是否足够聪明。它至少在vim的配置中提到了
防火墙防火墙分类第一代防火墙:包过滤防火墙包过滤防火墙的缺点第二代防火墙:代理防火墙第三代防火墙:状态防火墙第四代防火墙:UTM防火墙第五代防火墙:下一代防火墙华为防火墙介绍安全策略防火墙的会话表防火墙分类第一代防火墙:包过滤防火墙属于第一代防火墙技术,在没有专用防火墙设备时,一般由路由器实现该功能。将网络上传送数据包的IP首部以及TCP/UDP首部,获取发送源的IP地址和端口号,以及目的地的IP地址和端口号,并将这些信息作为过滤条件,决定是否将该分组转发至目的地网络分组过滤的执行需要设置访问控制列表。访问控制列表也可以称为安全策略(简称策略)或安全规则(简称规则)。类似于进站检票的做法,符合
内容来自Qt样式表之QSS语法介绍-3YL的博客Qt样式表是一个可以自定义部件外观的十分强大的机制,可以用来美化部件。Qt样式表的概念、术语和语法都受到了HTML的层叠样式表(CascadingStyleSheets, CSS教程)的启发,不过与CSS不同的是,Qt样式表应用于部件的世界。类型选择器QPushButton匹配QPushButton及其子类的实例ID选择器QPushButton#okButton匹配所有objectName为okButton的QPushButton实例。 CSS常用样式1CSS文字属性注:px:相对长度单位,像素(Pixel)。pt:绝对长度单位,点(Point
简介:我们都知道在Android开发中,当我们的程序在与用户交互时,用户会得到一定的反馈,其中以对话框的形式的反馈还是比较常见的,接下来我们来介绍几种常见的对话框的基本使用。前置准备:(文章最后附有所有代码)我们首先先写一个简单的页面用于测试这几种Dialog(对话框)代码如下,比较简单,就不做解释了一、提示对话框(即最普通的对话框)首先我们给普通对话框的按钮设置一个点击事件,然后通过AlertDialog.Builder来构造一个对象,为什么不直接Dialog一个对象,是因为Dialog是一个基类,我们尽量要使用它的子类来进行实例化对象,在实例化对象的时候,需要将当前的上下文传过去,因为我这
作者:郭斌斌爱可生DBA团队成员,负责项目日常问题处理及公司平台问题排查。本文来源:原创投稿*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。OceanBase集群界面会展示Observer的资源水位,今天简单了解一下资源水位的数值代表的含义以及关联参数现有test_1集群,只有一个sys租户Sys租户的资源配置:Cpu:2.5-5Memory:3G-3GUnit:1集群的资源水位信息以10.186.63.198为例,浅看一下cpu、内存、磁盘的含义以及相关联参数cpu:2.5/17核2.5代表observer上已经分配给租户的cpu核数,该数值是租户的MinCPU
快捷目录前言一、涉及到的相关技术简介二、具体实现过程及踩坑杂谈1.安卓手机改造成linux系统实现方案2.改造后的手机Linux中软件的安装3.手机Linux中安装MySQL5.7踩坑实录4.手机Linux中安装软件的正确方法三、Linux服务器部署前后端分离项目流程1.前提准备(安装必要软件,搭建环境):2.前后端分离项目的详细部署过程:总结前言总体概述:本篇文章隶属于“手机改造服务器部署前后端分离项目”系列专栏,该专栏将分多个板块,每个板块独立成篇来详细记录:手机(安卓)改造成个人服务器(Linux)、Linux中安装软件、配置开发环境、部署JAVA+VUE+MySQL5.7前后端分离项目
涡旋光束及其MATLAB实现前言涡旋光束的基本概念常见的涡旋涡旋光束涡旋光束的产生方法前言笔者新开一块专栏,专门用于讨论整理总结涡旋光束的相关内容,从基本的概念出发,推导相关的公式,并结合MATLAB进行相关的仿真,不清楚这个专栏会更新多少期,我会分享部分的代码,全部的代码有需要的话可以私聊我。当然大家对这个专栏感兴趣的话,欢迎积极交流。涡旋光束的基本概念涡旋光束(vortexbeam)是指携带光学涡旋,具有exp(imϕ)exp(im\phi)exp(imϕ)相位分布的光束,其中mmm表示相位拓扑电荷数,ϕ\phiϕ是柱坐标下的方位角。之前的分享中笔者已经说明了部分的激光光束的表达式,想要