MP-SPDZ的学习与运用

news2024/11/15 11:34:25

目录

    • MP-SPDZ 的介绍
      • 主要功能
      • 典型应用场景
    • MP-SPDZ 的安装
      • 实验环境准备
      • 环境安装
      • MP-SPDZ 下载和编译
    • MP-SPDZ 的使用
      • 测试程序
      • 第三方求和
      • 三方计算
      • 测试
      • 冒泡排序
      • 比较运算函数
      • 语法详解——Sint
      • 语法详解——Array
      • 基于AES电路实现OPRF
      • ORAM
      • 隐私集合求交实现
      • 两台虚拟机之间进行MPC简单实例
      • 基础OT的用法

MP-SPDZ 的介绍

MP-SPDZ 是一个开源框架,用于实现各种安全多方计算协议。它由多个安全协议和优化组成,旨在提供高效的、安全的多方计算功能,适用于学术研究和实际应用。

主要功能

  1. 多种协议支持

    • SPDZSPDZ2k:基于同态加密和秘密共享的协议。
    • MASCOT:高效的秘密共享协议,适用于大规模计算。
    • Overdrive:增强的 SPDZ 协议,提供更高效的离线预处理。
    • Yao’s Garbled Circuits:适用于两方计算。
    • GMW:基于加密电路的协议。
    • BMR:用于安全电路计算的协议。
    • Shamir’s Secret SharingReplicated Secret Sharing:适用于诚实多数的协议。
    • Threshold ECDSA:用于门限签名的协议。
  2. 高效的编译和执行

    • 支持将高层次的程序编译为高效的字节码,并在虚拟机上执行。
    • 提供多线程支持和协议特定的优化选项。
    • 支持本地和远程执行模式。
  3. 机器学习支持

    • 支持逻辑回归和线性回归的梯度下降(SGD)训练。
    • 集成 PyTorch 和 Keras 模型,支持常见的深度学习功能。
    • 支持决策树的训练和预测。
  4. 数学和线性代数操作

    • 支持整数、浮点数和定点数的基本运算和复杂操作。
    • 支持矩阵运算,包括矩阵乘法、转置等。
  5. 输入输出操作

    • 支持从文件、套接字等多种渠道输入和输出数据。
    • 支持秘密输入和输出,确保数据的隐私性。

典型应用场景

  1. 隐私保护数据分析

    • 在不泄露各方数据隐私的前提下,进行联合数据分析和统计。
  2. 安全机器学习

    • 在多方协作下训练机器学习模型,确保训练数据的隐私。
  3. 金融数据共享

    • 银行和金融机构之间进行安全的数据交换和计算,防止数据泄露。

MP-SPDZ 的安装

实验环境准备

Ubuntu 22.04.3 LTS

环境安装

sudo apt-get install automake build-essential git libboost-dev libboost-thread-dev libntl-dev libsodium-dev libssl-dev libtool m4 python3 texinfo yasm libboost-all-dev cmake clang libgmp-dev

MP-SPDZ 下载和编译

git clone https://github.com/data61/MP-SPDZ.git
cd MP-SPDZ
make setup
Scripts/tldr.sh
make -j 8 tldr # 对spdz库进行编译

MP-SPDZ 的使用

测试程序

官方提供了一个测试程序,这个代码内容就是各种运算的小测试。

Scripts/tldr.sh
echo 1 2 3 4 > Player-Data/Input-P0-0
echo 1 2 3 4 > Player-Data/Input-P1-0
Scripts/compile-run.py -E mascot tutorial

请添加图片描述
请添加图片描述

第三方求和

在Programs/Source文件夹内新建一个源代码文件testgp.mpc(后缀名是.mpc)

vim Programs/Source/testgp.mpc

编辑内容如下:

a = sint.get_input_from(0)
b = sint.get_input_from(1)
c = sint.get_input_from(2)
sum = a + b + c
print_ln('Results =%s',sum.reveal())

运行程序

./compile.py -B 32 Programs/Source/testgp.mpc

在这里插入图片描述

三方计算

生成证书文件,3代表三方计算。

Scripts/setup-ssl.sh 3

请添加图片描述
写入三方数据

echo 11 > Player-Data/Input-P0-0
echo 12 > Player-Data/Input-P1-0
echo 13 > Player-Data/Input-P2-0

开三个新终端模拟三方计算,进行运算,得到结果:

./shamir-bmr-party.x -N 3 0 testgp
./shamir-bmr-party.x -N 3 1 testgp
./shamir-bmr-party.x -N 3 2 testgp

请添加图片描述
请添加图片描述

请添加图片描述

测试

介绍一个命令

./emulate.x <program>

可以用来执行编译好的程序。

对于一个测试样例testgp.mpc

  1. 首先编译程序:
./compile.py testgp
  1. 编译成功后直接执行:
./emulate.x testgp

就可以跑程序。

冒泡排序

  1. 编写冒泡排序算法
vim Programs/Source/merge_and_sort.mpc

from util import if_else
from Compiler import types
 
def maopao(a):
	n = len(a)
	@for_range(n)
	def _(i):
		@for_range(n)
		def _(j):
			@if_((a[i] > a[j]).reveal())
			def _():
				# print_ln("!!!")
				tmp = a[i]
				a[i] = a[j]
				a[j] = tmp
	return a
 
n = 5
 
a = Array(n, sfix)
 
@for_range_opt(n)
def _(i):
    a[i] = sfix.get_input_from(0)
 
d = maopao(a) 
print_ln('Data receive success !!')
  1. 程序解释
    首先定义了一个函数,都是python语法,实现冒泡排序

然后指定数组大小n=5。定义一个sfix类型的数组a。sfix指安全的定点数(Secret fixed-point number represented as secret integer.)。

通过for循环将参与方的数据写入数组a。其中,get_input_from(0),0代表参与方的编号(ID)(这里是0号)。

注意for循环的写法,跟python语法还是有区别的。
3. 程序编译与执行
程序编译:merge_and_sort是程序文件名,源代码放在Programs/Source/中

./compile.py -B 32 merge_and_sort

请添加图片描述
4. 生成证书与密钥文件,建立安全的通道:在这个程序里只有一方参与计算。

Scripts/setup-ssl.sh 1

请添加图片描述

  1. 输入参与方的数据:数据存储在d0.dat文件里,这里是五个数,代表一个数组。
echo 8 9 7 4 6 > Player-Data/Input-P0-0
  1. 执行程序
./emulate.x merge_and_sort

请添加图片描述

比较运算函数

小于:less_than = lt()

大于:greater_than = gt()

小于等于: less_equal = le()

大于等于: greater_equal = ge()

等于: equal = eq()

不等于: not_equal = ne()

  1. 编写程序
vim Programs/Source/compare.mpc
a = sfix(12)
b = sfix(13)
print_ln("a: %s",a.reveal())
print_ln("b: %s",b.reveal())
print_ln("less_than: %s", sfix.__lt__(a,b).reveal())
print_ln("greater_than: %s", sfix.__gt__(a,b).reveal())
print_ln("less_equal: %s", sfix.__le__(a,b).reveal())
print_ln("greater_equal: %s", sfix.__ge__(a,b).reveal())
print_ln("equal: %s", sfix.__eq__(a,b).reveal())
print_ln("not_equal: %s", sfix.__ne__(a,b).reveal())  
  1. 运行程序
./compile.py -R 128 compare
./emulate.x compare

请添加图片描述

语法详解——Sint

原博客链接

语法详解——Array

原博客链接

基于AES电路实现OPRF

  1. 生成数据脚本,该脚本会生成127比特(可以改,生成任意比特的)的随机数(十六进制表示),也就是key和plaintext。并将这些数据写入对应的数据文件。
vim gen_data.py
import random
import os,sys
 
base = [str(x) for x in range(10)] + [ chr(x) for x in range(ord('A'),ord('A')+6)]
 
# hex2dec
def hex2dec(string_num):
    return str(int(string_num.upper(), 16))
 
# dec2hex
def dec2hex(string_num):
    num = int(string_num)
    mid = []
    while True:
        if num == 0: break
        num,rem = divmod(num, 16)
        mid.append(base[rem])
 
    return '0x'+''.join([str(x) for x in mid[::-1]])
 
def gen_random_hex(n_bit):
    b = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
    s = "0x"
    n = n_bit/4
    for i in range(n):
        t = random.randint(0,15)
        s = s + b[t]
    return s
 
bit = 127
a = gen_random_hex(bit)
ha = hex2dec(a)
b = gen_random_hex(bit)
hb = hex2dec(b)
print("############ gen_data.py #############")
print("a = " + a)
print("Dec(a) = " + ha)
print("b = " + b)
print("Dec(b) = " + hb)
 
f1 = open("Player-Data/Input-P0-0", "w")
f2 = open("Player-Data/Input-P1-0", "w")
print("Write a to Player-Data/Input-P0-0...")
f1.write(str(a))
print("Write b to Player-Data/Input-P1-0...")
f2.write(str(b))
f1.close()
f2.close()
print("################ End #################")
  1. 编写程序
vim Programs/Source/aes_circuit.mpc
from circuit import Circuit
sb128 = sbits.get_type(128)
key = sb128(0x2b7e151628aed2a6abf7158809cf4f3c)
plaintext = sb128(0x6bc1bee22e409f96e93d7e117393172a)
n = 1000
aes128 = Circuit('aes_128')
ciphertexts = aes128(sbitvec([key] * n), sbitvec([plaintext] * n))
ciphertexts.elements()[n - 1].reveal().print_reg()                                               
  1. 编写脚本
#! /bin/bash
./compile.py -B 128 aes_circuit
Scripts/setup-ssl.sh 2
python3 gen_data.py
echo "Player-Data/Input-P0-0:" $(cat Player-Data/Input-P0-0)
echo "Player-Data/Input-P1-0:" $(cat Player-Data/Input-P1-0)
echo "########### Execute aes_circuit... #############"
Scripts/yao.sh aes_circuit
  1. 运行脚本
    运行报错,尚未解决
    请添加图片描述

ORAM

oram_tutorial.mpc

from oram import OptimalORAM
 
array = OptimalORAM(10000)
array[1] = 123
print_ln('%s', array[1].reveal())

编译:

./compile.py -D -R 64 oram_tutorial

运行:

./emulate.x oram_tutorial

请添加图片描述
请添加图片描述

隐私集合求交实现

vim Programs/Source/psi.mpc
from util import if_else
from Compiler import types
from Compiler import mpc_math
program.bit_length = 128
def compute_intersection(a, b):
    n = len(a)
    intersection = Array(n, sfix)
    is_match_at = Array(n, sfix)
    @for_range(n)
    def _(i):
        @for_range(n)
        def _(j):
            match = a[i] == b[j]
            is_match_at[i] += match
            intersection[i] = if_else(match, a[i], intersection[i]) 
    return intersection, is_match_at
def set_intersection_example(a,b):
    print_ln('Running PSI example')
    intersection, is_match_at = compute_intersection(a,b)
    print_ln('Printing set intersection (0: not in intersection)')
    size = MemValue(sfix(0))
    total = MemValue(sfix(0))
    @for_range(n)
    def _(i):
        size.write(size + is_match_at[i])
        total.write(total + intersection[i])
        print_str('%s ', intersection[i].reveal())
    print_ln('\nIntersection size: %s', size.reveal())
 
n = 10
a = Array(n, sfix)
b = Array(n, sfix)
@for_range_opt(n)
def _(i):
    a[i] = sfix.get_input_from(0)
@for_range_opt(n)
def _(j):
    b[j] = sfix.get_input_from(1)
print_ln('data is ok')
set_intersection_example(a,b)

编译、生成证书、写数据

./compile.py -B 64 psi
Scripts/setup-ssl.sh 2
echo 44 76 14 45 31 4 67 39 78 84 > Player-Data/Input-P0-0
echo 1864 14 44 7335 2791 564 39 9085 4 7220 > Player-Data/Input-P1-0

执行程序,要在两个终端运行:

./semi-bmr-party.x -N 2 0 psi
./semi-bmr-party.x -N 2 1 psi

请添加图片描述
请添加图片描述
请添加图片描述

两台虚拟机之间进行MPC简单实例

需要两台服务器,未完待续。。。。

基础OT的用法

useOT.cpp

#include <iostream>

#include "OT/BaseOT.h"  
#include "Networking/Player.h"
#include "Tools/octetStream.h"

using namespace std;

int main()
{
	
	
	int player = 0;
	int nplayers = 2;
	const char* servername = "127.0.0.1";
	int pnb = 8000;
	int my_port = 8001;
	Names n = Names(player,nplayers,servername,pnb,my_port);
	//Names n = Names(player,nplayers,servername,pnb,Names::DEFAULT_PORT);
	RealTwoPartyPlayer tp = RealTwoPartyPlayer(n,1,101);
	//PlainPlayer p = PlainPlayer(n,10);

	OT_ROLE ot_role = SENDER;
	//int mynum = 8000;
	
	RealTwoPartyPlayer *s;
	s = &tp;
	BaseOT send = BaseOT(8,128,s, ot_role);
	send.exec_base();

	cout<< "Success !!" <<endl; 
	return 0;
}

BaseOT.h 写了两个测试程序。第一个是OT里的发送者,第二个是接受者。

程序详解:

实例化类Names用来开启并监听端口,进行通信。
实例化类RealTwoPartyPlaye 用来模拟两个参与方。
第一个参数是Names类
第二个参数:other_player,表示另一个参与者的编号
第三个参数:唯一标志id
实例化一个BaseOT类
第一个参数nOT,表示执行OT的数量,这里我设置为8,注意必须为4的倍数,要不会报错。
第二参数表示消息的长度,这里我设置为128比特。
第三个参数,参与方的类指针
第四个参数,ot的角色,这里有三个角色:发送者(SENDER),接收者(RECEIVER),两者都是(BOTH)。
实例化时候,也可以只给第三四个参数,这时候nOT和ot_length都默认为128
调用类方法exec_base()。运行的时候只需要这些参数,所有消息和选择比特都随机生成了。
useOTRec.cpp

#include <iostream>

#include "OT/BaseOT.h"  
#include "Networking/Player.h"
#include "Tools/octetStream.h"

using namespace std;

int main()
{
	int player = 1;
	int nplayers = 2;
	const char* servername = "127.0.0.1";
	int pnb = 8000;
	int my_port = 8002;
	Names n = Names(player,nplayers,servername,pnb,my_port);
	//Names n = Names(player,nplayers,servername,pnb,Names::DEFAULT_PORT);
	RealTwoPartyPlayer tp = RealTwoPartyPlayer(n,0,101);
	//PlainPlayer p = PlainPlayer(n,10);

	OT_ROLE ot_role = RECEIVER;
	//int mynum = 8000;
	
	RealTwoPartyPlayer *s;
	s = &tp;
	BaseOT rec = BaseOT(8,128,s, ot_role);
	rec.exec_base();

	cout<< "Success !!" <<endl; 
	return 0;
}

makefile文件

# objs_SimpleOT = ../SimpleOT/ot_sender.o ../SimpleOT/ot_receiver.o ../SimpleOT/sc25519_random.o ../SimpleOT/ge25519_pack.o ../SimpleOT/ge25519_double.o ../SimpleOT/fe25519_pack.o
objs_SimpleOT = ../SimpleOT/*.o
all: useOT useOTRec
useOT: useOT.o
	g++ -o useOT useOT.o ../OT/*.o $(objs_SimpleOT) ../libSPDZ.so -lntl -lmpirxx -lmpir -lsodium -lboost_system -lssl -lcrypto -lrt

useOTRec: useOTRec.o
	g++ -o useOTRec useOTRec.o ../OT/*.o $(objs_SimpleOT) ../libSPDZ.so -lntl -lmpirxx -lmpir -lsodium -lboost_system -lssl -lcrypto -lrt

useOT.o: useOT.cpp ../Networking/Player.h ../OT/BaseOT.h
	g++ -c useOT.cpp -I ~/spdz029 -march=native -g -Wextra -Wall -O3 -I. -pthread    -DUSE_GF2N_LONG '-DPREP_DIR="Player-Data/"'  -std=c++11 -Werror -fPIC -MMD -MP -c

useOTRec.o: useOTRec.cpp ../Networking/Player.h ../OT/BaseOT.h
	g++ -c useOTRec.cpp -I ~/spdz029 -march=native -g -Wextra -Wall -O3 -I. -pthread    -DUSE_GF2N_LONG '-DPREP_DIR="Player-Data/"'  -std=c++11 -Werror -fPIC -MMD -MP -c

clean:
	rm -f *.o main *.out useOT useOTRec *.d

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1789160.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视觉SLAM十四讲:从理论到实践(Chapter8:视觉里程计2)

前言 学习笔记&#xff0c;仅供学习&#xff0c;不做商用&#xff0c;如有侵权&#xff0c;联系我删除即可 一、目标 1.理解光流法跟踪特征点的原理。 2.理解直接法是如何估计相机位姿的。 3.实现多层直接法的计算。 特征点法存在缺陷&#xff1a; 二、光流(Optical Flow) …

SEO之关键词扩展(二)

初创企业搭建网站的朋友看1号文章&#xff1b;想学习云计算&#xff0c;怎么入门看2号文章谢谢支持&#xff1a; 1、我给不会敲代码又想搭建网站的人建议 2、新手上云 &#xff08;接上一篇。。。&#xff09; 5、各种形式的变体 1.同义词 假设核心关键词是酒店&#xff0c;…

Python版《消消乐》,附源码

曾经风靡一时的消消乐&#xff0c;至今坐在地铁上都可以看到很多人依然在玩&#xff0c;想当年我也是大军中的一员&#xff0c;那家伙&#xff0c;吃饭都在玩&#xff0c;进入到高级的那种胜利感还是很爽的&#xff0c;连续消&#xff0c;无限消&#xff0c;哈哈&#xff0c;现…

Kotlin中的StateFlow和SharedFlow有什么区别?

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 在Kotlin的协程库kotlinx.coroutines中&#xff0c;StateFlow和SharedFlow是两种用于处理事件流的API&#xff0c;它们有相似之处&#xff0c;但…

MySQL中获取时间的方法

大家好&#xff0c;在MySQL数据库开发中&#xff0c;获取时间是一个常见的需求。MySQL提供了多种方法来获取当前日期、时间和时间戳&#xff0c;并且可以对时间进行格式化、计算和转换。 以下是一些常用的MySQL时间函数及其示例&#xff1a; 1、NOW()&#xff1a;用于获取当前…

GPT-4与GPT-4O的区别详解:面向小白用户

1. 模型介绍 在人工智能的语言模型领域&#xff0c;OpenAI的GPT-4和GPT-4O是最新的成员。这两个模型虽然来源于相同的基础技术&#xff0c;但在功能和应用上有着明显的区别。 GPT-4&#xff1a;这是一个通用型语言模型&#xff0c;可以理解和生成自然语言。无论是写作、对话还…

MySQL 关键特性一:插入缓冲、双写缓冲

前言 ​ 本文主要介绍 mysql 的几大特性之几&#xff0c;如&#xff1a;双写缓冲和插入缓存。 双写缓冲 基本概念 ​ 双写缓冲&#xff08;doublewrite buffer&#xff09;是MySQL/InnoDB中用于支持原子页面更新的一种机制。在传统的数据库系统中&#xff0c;为了保证数据的…

小米商城格式化检测点

小米商城格式化检测点&#xff1a; var a function () {var x !0;return function (a, t) {var e x ? function () {if (t) {var x t.apply(a, arguments);t null;return x;}} : function () {};x !1;return e;};}();var t {};function e(n) {var r a(this, function…

数据持久化第七课-URL重写与Ajax

数据持久化第七课-URL重写与Ajax 一.预习笔记 1.URL重写(对网页地址进行保护) 首先编写module,实现对网络地址的处理 其次就是module的配置 最后验证url重写技术 2.Ajax数据交互 编写后端响应数据 处理跨域的配置问题 运行项目得到后端响应数据的地址 编写前端ajax进行数据请…

珈和科技携手浙江省气候中心,打造农业气象数字化服务新标杆!

古谚有云&#xff1a;春耕夏种秋收冬藏&#xff0c;皆在天时。可天有不测风云&#xff0c;农有“旦夕祸福”。寒潮、干旱、洪涝等气象灾害频繁发生&#xff0c;给农业生产带来了巨大挑战。 气候变化直接影响着农业生产&#xff0c;数字化时代&#xff0c;如何依靠科技手段降低…

解决 clickhouse jdbc 偶现 failed to respond 问题

背景 Clickhouse集群版本为 Github Clickhouse 22.3.5.5&#xff0c; clickhouse-jdbc 版本为 0.2.4。 问题表现 随着业务需求的扩展&#xff0c;基于Clickhouse 需要支持更多任务在期望的时效内完成&#xff0c;于是将业务系统和Clickhouse交互的部分都提交给可动态调整核心…

【面试笔记】单片机软件工程师,工业控制方向(储能)

文章目录 1. 基础知识1.1 C语言笔试题1.1.1 用宏定义得到一个数组所含的元素个数1.1.2 定义函数指针从程序固定地址(0)开始执行1.1.3 volatile的含义及作用1.1.4 32位系统&#xff0c;整数7和-7&#xff0c;分别以大端和小端存储&#xff0c;请示意说明 1.2 嵌入式基础1.2.1 简…

知识图谱应用---智慧金融

文章目录 智慧金融典型应用 智慧金融 智慧金融作为一个有机整体&#xff0c;知识图谱提供了金融领域知识提取、融合、分析、推断、决策等功能&#xff0c;如下图所示。在场景方面&#xff0c;智慧金融涵盖智慧支付、智慧财富管理、智慧银行、智慧证券、智慧保险、智慧风控等诸多…

【教程】使用 Tailchat 搭建团队内部聊天平台,Slack 的下一个替代品!

前言 多人协作&#xff0c;私有聊天一直是团队协作的关键点&#xff0c;现在有很多专注于团队协作的应用和平台&#xff0c;比如飞书、企业微信和Slack等。这期教程将带你手把手的搭建一个在线的团队协作向聊天室&#xff0c;希望对你有所帮助! 本期聊天室使用TailChat作为服务…

Rust 第三方库创建和导入(cargo --lib)

前言 日常开发过程中&#xff0c;难免会有一些工具方法&#xff0c;多个项目之间可能会重复使用。 所以将这些方法集成到一个第三方包中方便后期维护和管理&#xff0c; 比如工具函数如果需要修改&#xff0c;多个项目可能每个都需要改代码&#xff0c; 抽离到单独的包中只需要…

esp32-c6所有配套教程

1.介绍 本文是esp32-c6所有资料的介绍 如果需要详细代码的话请访问下面这个链接 esp32-c6使用教程wifi&#xff08;espidf修改成arduino&#xff09;附带代码websocket&#xff0c;舵机&#xff0c;点灯【2024年】-CSDN博客 配置环境 视频教程 0-2设置开发环境_哔哩哔哩_bi…

【python】成功解决“ImportError: cannot import name ‘triu’ from ‘scipy.linalg’”错误的全面指南

成功解决“ImportError: cannot import name ‘triu’ from ‘scipy.linalg’”错误的全面指南 在Python编程中&#xff0c;尤其是在使用scipy这个科学计算库时&#xff0c;可能会遇到ImportError错误&#xff0c;提示无法从scipy.linalg模块中导入名为triu的函数。这个错误通…

Linux入门教程笔记(一文带你了解Linux并精通)

文章目录 一、Linux概述二、Linux目录结构&#xff08;重点&#xff09;2.1 Linux文件系统的类型2.2 Linux文件系统的结构2.3 具体的目录结构2.3.1 Linux 根目录2.3.2 Linux /usr目录2.3.3 Linux /var 目录2.3.4 tar包存放目录:crossed_swords: 三、vi和vim编辑器四、Lnux开机&…

SpringMVC接收数据

SpringMVC接收数据 SpringMVC处理请求流程 SpringMVC涉及组件理解&#xff1a; DispatcherServlet : SpringMVC提供&#xff0c;我们需要使用web.xml配置使其生效&#xff0c;它是整个流程处理的核心&#xff0c;所有请求都经过它的处理和分发&#xff01;[ CEO ]HandlerMappi…

16个常用的思维模型

01.机会成本 02.沉没成本 03.直觉思维 04.决策树 05.非SR模型 06.确认性偏差 07.易得性偏差 08.逆向思维 09.六顶思考帽 10.101010旁观思维 11.升级思维 11.笛卡尔模型 13.第一性原理 14.奥卡姆剃刀理论 15.马斯洛需求层次理论 16.反脆弱思维 来源&#xff1a;16个常用的思维模…