Obliv-C使用详解

前期说明

Obliv-C是一款GCC包装器,其作者在C语言的基础上对其进行了一定的类C处理,添加了一些规则限制,用于模拟实现混淆电路

Obliv-C不需要手动混淆,只需要调用其中的函数便可实现混淆电路,其不涉及真实硬件电路仿真,即无法导出函数对应的基本元电路(也可能是博主没有成功实现,但其提供的所有帮助文档论文中没有提及该方面的内容,若某位同僚有解决的方法,欢迎分享学习)

Obliv-C源码公开在GitHub中,可从中下载安装Obliv-C使用,因其自带的安装教程简单实用,在此不提及其安装的操作方法(GitHub网址:Obliv-C)

Obliv-C的设计团队为其编写了一个官方网站:Obliv-C
从中可获取Obliv-C的原著论文(PDF版)以及其帮助文档、实现项目等具体资料

倘若刚开始接触使用Obliv-C,建议仔细阅读其论文以及帮助文档,论文中详细说明了Obliv-C编程的规则,而帮助文档则提供了简单的案例分析

硬件平台

Obliv-C运行于Linux系统上,博主使用了Ubuntu系统,具体的系统支持可查看GitHub中提供的Obliv-C帮助手册

文件目录

Obliv-C的设计者并没有提供其各个文件的具体介绍,简单使用Obliv-C软件也仅需了解其如何编程、如何运行、如何调试即可

打开安装好的obliv-c文件夹,可在一级目录中找到一个名为 test 的文件夹,打开它

在这里插入图片描述
打开后,找到一个名为 oblivc 的文件夹,打开它

在这里插入图片描述
打开后所显示的文件目录即为设计者提供的一系列已完成案例,其中 README.txt 文件中详细说明了各个案例的功能实现,该文件位置也是Obliv-C编程的workspace(图中某些文件夹是博主自己创建的项目文件)

在这里插入图片描述
对于obliv-c的其他文件夹,可暂时忽略,如果之后需要查看某一文件内容,可直接在obliv-c文件夹中搜索该文件

案例分析

million 文件夹为例,该文件夹中包含了百万富翁问题的混淆电路实现

million文件目录如下(未编译过该程序不会有a.out文件):

在这里插入图片描述
其中 a.out 为可执行程序,相当于Windows系统中的exe文件;
million.c、million.h、million.oc 文件均为代码文件,可对其进行编程;
README.txt 介绍了该代码程序如何编译、运行的方法

代码编程

学习一个案例先从其程序代码开始,即图中的 million.c、million.h、million.oc 文件,因Obliv-C使用类C语言,所以要求使用者要有一定的C语言基础

million.c 文件:编程规则与C语言完全相同,用于获取命令行参数、设置混淆电路环境、输出混淆计算结果等

million.h 文件:编程规则与C语言完全相同,用于定义混淆电路相关结构体、声明函数等

million.oc 文件:编程规则与C语言类似,具体差别可查看Obliv-C论文内容,用于定义混淆计算函数

million.h 代码如下:

typedef struct protocolIO
{ int cmp; // -1,0, or 1
  int mywealth;
} protocolIO;

void millionaire(void* args);

protocolIO结构体中定义参与混淆计算的全部参数,包括各方的秘密输入(mywealth)以及最后的共享结果(cmp),特别地,各方的秘密输入可以定义为同一变量名,也可以定义为不同的变量

对于protocolIO结构体,其中的变量不能使用指针,需要用数组代替,否则编译可能不会报错,但最终运行结果错误

millionaire 函数为混淆计算函数的声明,具体的函数定义可在 million.oc 代码中查看编写

million.c 代码如下:

#include<stdio.h>
#include<obliv.h>

#include"million.h"

int main(int argc,char *argv[])
{
  ProtocolDesc pd;
  protocolIO io;
  if(argc<3)
  { if(argc<2) fprintf(stderr,"Party missing\n");
    else fprintf(stderr,"Wealth missing\n");
    fprintf(stderr,"Usage: %s <1|2> <wealth>\n",argv[0]);
    return 1;
  }

  // skip input sanitization
  sscanf(argv[2],"%d",&io.mywealth);
  protocolUseStdio(&pd);
  setCurrentParty(&pd,argv[1][0]=='1'?1:2);
  execYaoProtocol(&pd,millionaire,&io);
  cleanupProtocol(&pd);
  fprintf(stderr,"Result: %d\n",io.cmp);
  return 0;
}

头文件声明部分,包含了 stdio.h、obliv.h、million.h 三个头文件,stdio.h 为C语言编程必要的头文件,不过多描述;obliv.h 头文件声明了混淆电路相关的内容,若想查看其中详细内容,可通过搜索该文件直接打开阅读;million.h 头文件是自行定义的文件,因此需要使用 “” 声明

main函数需要从命令行中获得相关参数,因此固定 int main(int argc,char *argv[]) 写法,其中:
argc 统计程序运行时发送给main函数的命令行参数的个数
argv[0] 指向程序运行的全路径名
argv[1] 指向在DOS命令行中执行程序名后的第一个字符串
argv[2] 指向执行程序名后的第二个字符串
argv[3] 指向执行程序名后的第三个字符串

ProtocolDesc pd 该部分并未找到对其的具体说明,但涉及混淆电路的函数都将其作为自己的参数,特此注意

protocolIO io 为在 million.h 头文件中定义的结构体

以下代码用于判断命令行输入的格式是否正确,实际使用时可根据自身需求修改判断(argc 统计程序运行时发送给main函数的命令行参数的个数)

if(argc<3)
  { if(argc<2) fprintf(stderr,"Party missing\n");
    else fprintf(stderr,"Wealth missing\n");
    fprintf(stderr,"Usage: %s <1|2> <wealth>\n",argv[0]);
    return 1;
  }

sscanf(argv[2],"%d",&io.mywealth); 赋值语句,通过获取命令行输入,赋值给对应结构体中的变量

protocolUseStdio(&pd); 未找到对应的解释说明,博主后续的编程中从未使用过该函数,遂可忽略

setCurrentParty(&pd,argv[1][0]==‘1’?1:2); 设置混淆计算的各方,判断该程序是哪一方在使用,argv[1][0]==‘1’?1:2 判断语句,参数类型 int

execYaoProtocol(&pd,millionaire,&io); 执行混淆计算,millionaire 为混淆计算函数,&io 为存储有混淆计算输入输出的结构体

cleanupProtocol(&pd); 固定用法,清除 ProtocolDesc pd

fprintf(stderr,“Result: %d\n”,io.cmp); 混淆结果输出到命令行

million.oc 代码如下:

#include<obliv.oh>
#include"million.h"

void millionaire(void* args)
{
  protocolIO *io=args;
  obliv int v1,v2;
  bool eq,lt;
  
  v1 = feedOblivInt(io->mywealth,1);
  v2 = feedOblivInt(io->mywealth,2);
  revealOblivBool(&eq,v1==v2,0);
  revealOblivBool(&lt,v1<v2,0);
  io->cmp = (!eq?lt?-1:1:0);
}

头文件部分与 million.c 类似,不再描述

void millionaire(void* args) 为混淆计算函数,囊括该次混淆计算的具体计算过程

protocolIO *io=args; 混淆计算参数对应结构体获取

obliv int v1,v2; 随机值替换后的参数变量,注意 obliv 关键字

v1 = feedOblivInt(io->mywealth,1); 混淆数据获取,feedOblivInt 函数专用于 int 类型数据,第一个参数为数据,第二个参数为参与计算的某方,其余 feedObliv* 函数可查看 obliv.oh 头文件中的内容获取其声明用法

revealOblivBool(&eq,v1==v2,0); 解密计算,revealObliv* 函数与 feedObliv* 函数类似,都可在 obliv.oh 头文件中找到其具体的声明,该函数用于将混淆计算结果解密,在Obliv-C中,有且仅有该函数可以解密混淆数据

最后注意一下,虽然提供了 million.h 头文件,但写入该头文件中的头文件声明在 million.c 与 million.oc 中不起作用,因此,million.c 与 million.oc 需要的头文件必须在各自的代码中声明

编译运行

了解具体代码的功能实现后,便可编译运行,查看结果,此时可打开 README.txt 文件,按其中的步骤实现

文件中涉及程序编译的命令如下:

/path/to/oblivcc million.c million.oc -I .

其中 /path/to/oblivcc 要按照自身的 oblivcc 所在位置修改,可直接搜索该文件获取其位置目录,博主最后的编译命令如下:

../../../bin/oblivcc million.c million.oc -I .

命令行编译结果如下:

在这里插入图片描述
编译成功后,会产生 a.out 文件,而后找到运行命令:

cycle './a.out 1 15 | ./a.out 2 10'

若没有 cycle 命令,直接回车,将会报错:

在这里插入图片描述
此时可查看文件中的描述,它提供了一个网址,可下载该命令:cycle
下载完成后,修改命令所在的位置,再回车运行,便可获得结果:

在这里插入图片描述
该部分使用了million作为案例进行详细分析,对于Obliv-C的初学者而言,仅仅掌握一个案例是远远不够的,建议将全部的范例都浏览试运行一遍,再入手编写自己的混淆电路程序,会更加明了

实战编程

该部分不会涉及具体的代码编写,代码函数的解释学习在案例分析中已经描述得足够详尽,因此,该部分主要介绍如何创建自己的项目、编译、运行

创建项目

推荐将自己的项目创建在与案例相同的位置,项目的创建其实就是文件夹与文件的建立过程
(1)在oblivc文件目录下新建文件夹,自主命名
(2)在新建的文件夹中建立三个文件,分别为 .c、.h、.oc 类型文件,文件命名自定,推荐命名相同便于使用
至此,便可编写 .c、.h、.oc 类型文件,实现自己的混淆电路(可复制某一案例的代码,修改其中的函数变量等,实现自己所需的功能)

编译

除去million案例的编译方法,在某些案例中,提供有 Makefile 文件,该文件中说明了项目的具体编译操作

Obliv-C大多案例中提供的 Makefile 文件内容如下:

testName=editdist
include ../common/Makefile.simple

这是一个简易的 Makefile 文件,基于 …/common/Makefile.simple 实现,可以打开 …/common/Makefile.simple 文件查看内部内容:

$(if $(testName),,$(error 'testName' must be defined before Makefile.simple is used))
CILPATH=../../../
REMOTE_HOST=localhost
CFLAGS += -DREMOTE_HOST=$(REMOTE_HOST) -O3
./a.out: $(testName).oc $(testName).c ../common/util.c $(CILPATH)/_build/libobliv.a
	$(CILPATH)/bin/oblivcc $(CFLAGS) -I . $(testName).oc $(testName).c ../common/util.c
clean:
	rm -f a.out

很明显可以将这两个 Makefile 文件内容合并,修改一下其中涉及的文件位置即可

testName=editdist 为项目名称,若 .c、.h、.oc 类型文件命名相同,可使用该方法,若不同,则需手动修改命令中涉及的相关文件名

以下为错误提示,可直接复制使用:

$(if $(testName),,$(error 'testName' must be defined before Makefile.simple is used))

以下可以看做一些变量的赋值,可直接复制,修改一下文件位置便可:

CILPATH=../../../
REMOTE_HOST=localhost
CFLAGS += -DREMOTE_HOST=$(REMOTE_HOST) -O3

以下为编译命令,一般可直接复制使用,同样可能需要修改文件位置,若有特殊编译要求,可在其基础上按需修改:

./a.out: $(testName).oc $(testName).c ../common/util.c $(CILPATH)/_build/libobliv.a
	$(CILPATH)/bin/oblivcc $(CFLAGS) -I . $(testName).oc $(testName).c ../common/util.c

以下为清除命令:

clean:
	rm -f a.out

Makefile 文件的编译只需在对应的文件目录打开命令行终端,输入 make 回车,清除命令输入 make clean 即可

编译成功,同样产生一个 a.out 可执行程序文件

运行

一般运行,打开终端,执行 a.out 文件,不同的案例会有不同的参数要求,按提供的格式输入便可,同样,某些案例在一个终端中输入命令便可运行,某些案例可能会需求打开两个终端,进行连接通信后,才可运行,具体的运行方法案例中都会说明,试运行所有案例后便可寻求一个最适合自己代码的运行方法

备注

Obliv-C实现了混淆电路,也有许多成功的项目,但其也存在一定的缺陷,例如,无法使用常用库、不能真正实现电路、仅支持C语言而不能使用C++等

对于Obliv-C的更多使用方法,如果某些同僚更为了解,欢迎分享,大家互相学习互相进步!

热门文章

暂无图片
编程学习 ·

Shell编程_echo/printf

目录一、Shell echo/printf 命令1、Shell显示命令-echo2、printf 命令操作常用的一些格式化字符二、test命令一、Shell echo/printf 命令Shell echo/printf 命令1、Shell显示命令-echo打印普通字符串[root@master ~]# echo "hello shell" hello shell创建和清空文件1…
暂无图片
编程学习 ·

MapReduce详细分析

一、MapReduce概述 1、定义 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群 上。 2、MR进程 一个完整的MapR educe程序在分布式运行时有三类实例进程:**Mr AppMaster:**负责整个程序的过程调度及状态协调…
暂无图片
编程学习 ·

创新实训(10)-提取式文本摘要之bert聚类

创新实训(10)-提取式文本摘要之bert聚类 1. 思路 使用bert作为预训练模型,利用bert生成的词向量进行下游任务的处理,在这篇论文中使用的是k-means计算词向量分布的重心作为文本摘要的候选句子。可以看作是聚类的一种形式。 2.代码分析 基于Pytorch的Transformers框架,使用预…
暂无图片
编程学习 ·

工科中的设计思维

超星学习通app工科中的设计思维网课答案,工科中的设计思维尔章节测验网课答案1.1 走近设计思维1【单选题】本门课程讲述的主要内容不包括()。A、设计思维这一学习形式和思维方式B、一系列有用的创新工具和创造技法C、工科学生需要用到的专业设计软件D、系统化的设计流程和与众…
暂无图片
编程学习 ·

【数据结构与算法】排序算法之冒泡排序(C++、Python)

原理介绍: 假设有长度为n的数组a,按照从小到大的顺序进行排序。冒泡排序的思路为:首先从数组的第一个元素开始,对数组中相邻的两个元素进行比较大小。如果左边(即索引数字小的)元素的值大于右边的元素,则交换这两个元素在数组中的位置,一直到最后一个元素为止。此时数组…
暂无图片
编程学习 ·

【论文阅读报告】Visualizing and Understanding Convolutional Networks

背景 众所周知,卷积神经网络在图像处理方面表现突出,但是在很多情况下,我们在调神经网络的参数时只是依靠运气,并不知道自己对参数和网络结构的调整会影响神经网络的哪一部分。因此这篇文献的目的就是让我们通过一种可视化的方法来了解卷积神经网络如何工作,以及每一层的特…
暂无图片
编程学习 ·

AttributeError: ‘list‘ object has no attribute ‘value‘

AttributeError: ‘list’ object has no attribute ‘value’需要注意self.session.run输出的格式,如下代码会报错 precise_summary = self.session.run([ts.precise_summary],{ts.x: xs, ts.y: ys}) writer.add_summary(precise_summary, epoch)AttributeError: ‘list’ ob…
暂无图片
编程学习 ·

Android Studio报错Error while merging dex archives

今天在编译代码时候出现这个报错,首先谈几句关于学习,其实刚开始新手时候什么都不懂,一遇到错误就慌得很,其实严格意义上这些所谓的报错都不是本身的错误,都只是我们不会用或者用错了导致的问题,就好像买了一辆车去水上开,结果沉了,还质问厂家问什么沉了。 所以这种所谓…
暂无图片
编程学习 ·

nginx 通过域名代理tcp端口

碰到一种场景,使用nginx进行反向代理tcp端口,网上大部门的设置都是一个端口代理一个端口,没有一个端口通过域名代理后端多个端口的情况。 在sf上面看到一个设置教程,记录下 只需要修改nginx.conf,添加如下配置即可, stream {map $ssl_preread_server_name $name {mysql.t…
暂无图片
编程学习 ·

缓存雪崩,缓存穿透,缓存击穿出现的原因及解决方案

缓存雪崩 出现过程假设有如下一个系统,高峰期请求为5000次/秒,4000次走了缓存,只有1000次落到了数据库上,数据库每秒1000的并发是一个正常的指标,完全可以正常工作,但如果缓存宕机了,或者缓存设置了相同的过期时间,导致缓存在同一时刻同时失效,每秒5000次的请求会全部…
暂无图片
编程学习 ·

每日一题 -- LeetCode (八)

JavaScript / TypeScript for LeetCode 当前进程:开始时间:2020.6.27 结束时间:undefinedGitHub仓库:https://github.com/Cundefined/JavaScript-or-TypeScript-for-LeetCode 参考视频:https://www.bilibili.com/video/BV1wA411b7qZ 1、题目要求 ( LeetCode-第53题 ) 最大…
暂无图片
编程学习 ·

Spring Boot + RabbitMQ 配置参数解释

application.properties配置文件写法#rabbitmq spring.rabbitmq.virtual-host=/ spring.rabbitmq.host=192.168.124.20 spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest spring.rabbitmq.listener.concurrency=10 spring.rabbitmq.l…
暂无图片
编程学习 ·

Kotlin上手(一)

标准函数with with函数接收两个参数,第一个参数是任意类型的对象,第二个是Lambda表达式。with函数会在Lambda表达式中提供第一个参数的上下文,并使用Lambda表达式中的最后一行代码作为返回值返回。 fun test() {val list = listOf("Apple", "Banana", &…
暂无图片
编程学习 ·

Linux命令21天打卡

1)给文件 isTester.ini 赋予 只读权限1. 创建文件 isTester.inivi isTester.ini2. 更新文件内容为“21 day Linux Learn ,Im Idolaoxu,in shenzhen ."输入 i ,进入编辑模式,输入内容,esc进入命令模式 :wq 保存 。chmod +R isTester.ini2)给文件 isTester.ini 赋予 读…
暂无图片
编程学习 ·

海思NNIE开发系列文章--转载

https://blog.csdn.net/zh8706/article/details/94554337海思NNIE开发系列文章:海思NNIE开发(一):海思Hi3559AV100/Hi3519AV100 NNIE深度学习模块开发与调试记录海思NNIE开发(二):FasterRCNN在海思NNIE平台上的执行流程(一)海思NNIE开发(三):FasterRCNN在海思NNIE平…
暂无图片
编程学习 ·

mysql5.7安装

本篇文章介绍的是mysql5.7安装教程! 环境:Windows 类型:msi Mysql安装包可以去官网下载 mysql官网下载 也可以加入我们群聊下载(群文件mysql文件夹下) 另外,加入群聊也可以远程安装 文章目录mysql 5.7安装 准备安装包安装步骤第一步同意协议第二步选择手动安装第三步选择…
暂无图片
编程学习 ·

Java设计模式及应用场景之《模板方法模式》

文章目录一、模板方法模式定义二、模板方法模式的结构和说明三、模板方法模式示例四、钩子方法五、模板方法模式的优缺点六、模板方法模式的应用场景及案例 一、模板方法模式定义Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Te…
暂无图片
编程学习 ·

Mybatis直接写sql与使用association映射性能比较

最近在公司发现前辈写多表查询时使用mybatis并未使用等标签封装数据 这引发我对mybatis=有无使用标签进行数据查询的性能比较产生了兴趣,于是乎~~~做了个小小的测试 首先建立两个表:student 和 teacher teacher表结构:student表结构:用java分表为两个表写了个120万的循环…
暂无图片
编程学习 ·

typescript学习笔记

typescript是微软开发的一个javascript的一个超集。支持es6规范。它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。es是客户端脚本的规范,es5,es6是这些规范的不同版本。JavaScript与typescript是两种客户端脚本语言,JavaScript实现了es5规范,t…