Zhuang's Diary

言之有物,持之以恒

2017年6月,大神 Andrej Karpathy 刚从现在如日中天的 OpenAI 离职加入了 Tesla,跟着Elon Musk干自动驾驶。半年后的2017年11月13日,Andrej 写了一篇文章「Software 2.0」,提出了一个新的软件范式,一个以神经网络为主体、其他代码为辅助的 Software 2.0。具体文章见 https://karpathy.medium.com/software-2-0-a64152b37c35

2017: Software 1.0 vs Software 2.0

  1. Software 1.0 中的规则(也就是我们常说的业务逻辑)是设计好的,由程序员把设计好的业务规则,通过一种编程语言写给机器执行。可以是Python或者Java、C++等;Software 2.0 的核心是一个神经网络、是无法被人理解的一种代码。
  2. Software 1.0 是程序员写代码;Software 2.0 是程序员搞训练、调整训练数据集等。开发范式发生了非常大的变化。

2021: 进一步

『The Rise of Software 2.0』https://pub.towardsai.net/the-rise-of-software-2-0-you-dont-want-to-be-left-behind-cbaa75f6d19 ,加上更多的AI 产品已经可以看到了,Software 2.0 的轮廓逐渐清晰了,尤其作者提到的中间态 Data Products,就是我们目前看到的大多数产品的形态。

2023: ChatGPT

2023年,chatGPT 持续火爆,尤其是 GPT 4.0 的 plugin 机制,让 GPT 插上了翅膀,无所不能的画面呈现在我们眼前。6年后,Software 2.0 是这样子,但跟之前Andrej 说的还是有一些不同:

  1. 软件的核心是神经网络,但 LLM 这个怪兽让我们大多数开发者没有机会去训练模型,而是通过 Prompt 自然语言,充其量做一些 Embedings,fine-tuning 都是奢侈的
  2. 还是因为LLM大模型的存在,『The Rise of Software 2.0』中提到的Software 2.0 的高研发投入不存在了,大家都是围绕着LLM 基础大模型做。但反过来想,大家的护城河在哪里呢?

还有吗?也许有。Microsoft 最近开放出一个 Semantic Kernel 的开发框架,把基于大语言模型开发抽象成了几个模块:Kernel、Planner、Skills、Memory和Connectors,这简直就是当年写Web 程序的时候提出了一个 MVC 框架一样,方便大家快速基于LLM 大语言模型构建自己的应用,简直就是LLM时代的 Spring。

https://github.com/microsoft/semantic-kernel

https://devblogs.microsoft.com/semantic-kernel/

https://learn.microsoft.com/en-us/semantic-kernel/

BIAN ( The Banking Industry Architecture Network) 是一个业界多方协作的非营利性组织,由全球领先银行、技术提供商、顾问和学者组成,定义了一个用以简化和标准化核心银行体系结构的银行技术框架。这一框架基于面向服务的架构 (SOA) 原则,银行可以借助 BIAN 参考模型建立起业务能力“积木块”,通过与现有系统进行映射和对接,理清应用之间的边界,从而达成面向服务的、松耦合的未来银行架构。从架构及技术角度看, BIAN 融汇了业界关于银行业务模型和技术体系的积累、结合 SOA 架构和微服务架构理念,基于业务能力、组件及服务而形成的银行应用之间互联互通的技术标准。

BIAN 的业务能力

从业务架构的角度来看,BIAN 提供了两个重要的企业架构工件,一个是业务能力地图 Business Capability Map,一个是价值链 Value Chain。

BIAN 的业务能力地图构建方式与普通企业架构实践是有区别的。一般情况下,业务架构设计过程中会集中业务和分析师等人员,采用自上而下逐步分解的方式构建业务能力地图。而 BIAN 的业务能力地图,是由一系列已经构建完成的原子级能力,通过映射的方式汇总为业务能力地图。主要的目的是为了与业务架构进行对齐,以适配主流的业务架构分析方法。

服务域(BIAN 称为 Service Domain,俺称为原子能力)代表一组离散的、原子的(唯一/不重叠的)业务功能,它们构成了任何银行的功能构建块 (Functional Building Blocks),用于为解决方案的开发提供业务功能框架。服务域和业务能力为明显不同的目的而将业务区分开来。服务域是一种功能细分,旨在提供一个开发/部署框架。业务能力代表了不同的业务所拥有的能力,目的是制定和实施业务战略。

BIAN 服务域可以被认为是 “对某物做某事的能力”,专注于对一个业务对象所执行的操作。BIAN 服务域是原子性的,这意味着 “代表了可以被服务化的最小实际能力或功能分区。” 换句话讲,一个服务域将封装适合(被封装到) IT 服务中的最小实际业务功能 Business Functionality 。在某些情况下,服务域直接(或几乎)与业务能力相一致;然而,由于服务域是面向功能的,它们通常与价值流 Value Stream 有关,或者更经常地与价值流阶段 Value Stream Stage(或其一部分)有关。

BIAN 的价值链

BIAN 的价值链并不是真正的价值链,因为价值链是要进行更下一步分解的,但是 BIAN 仅分解到第 2 层就戛然而止。BIAN 使用价值链视图的真正目的,是给银行另外一个看待原子业务能力的视角。

BIAN 到底是什么

经过多年积累,BIAN 为银行业务构建了一批原子业务能力,使银行在信息化建设的过程中可以利用 BIAN 的行业框架,依据自身实际情况进行调优后,便捷高效地实施数字化战略。BIAN 构建了便于业务侧理解的业务能力地图与价值链,将原子业务能力通过映射的方式与两个业务架构中的关键工件进行关联,从而实现银行的业务与 IT 对齐。原子能力便于组装的特性,极大地促进了业务侧的创新与调整;通过统一规范的接口,为银行铺就了一条互联互通的开放之路。

  1. 业务颗粒度(业务价值),架构颗粒度(UML建模),API,都已经是一套完整的设计,作为架构师可以开箱即用。
  2. 原本BIAN只是解决银行间互操作的问题,目前已经远远超过了这样子的范围,成为核心银行的架构标杆。
  3. BIAN的设计基于开放银行,充分考虑SaaS模式,这样子的设计架构下,第三方服务可以很容易融入核心银行。例如,salesforce的产品可以很容易地融入核心银行,以完成CRM的功能。

参考链接:

  1. 官网地址 - https://bian.org/
  2. BIAN PORTAL - https://portal.bian.org/dashboard/
  3. 最新版servicelandscape(20230403) - https://bian.org/servicelandscape-11-0-0/

本实例,将实现一个在区块链用例中非常典型的操作:证明给定哈希摘要的原像知识。 特别是,假设证明者Peggy)向验证者Victor)毫无疑问地证明她知道摘要的哈希原像 ,但没有透露原像是什么。

  1. 本实例以zokrates为ZKP工具(iden3亦可)。

1. 计算hash

我们将通过使用 ZoKrates 计算任意选择的原像的哈希值来开始本教程,在本例中,原像内容为数字 5

首先,我们创建一个名为 hashexample.zok 的新文件,内容如下:

1
2
3
4
5
6
import "hashes/sha256/512bitPacked" as sha256packed;

def main(private field a, private field b, private field c, private field d) -> field[2] {
field[2] h = sha256packed([a, b, c, d]);
return h;
}

第一行从 ZoKrates 标准库导入 sha256packed 函数。

sha256packed 是一个 SHA256 的实现。它是这样工作的:我们想将 512 位的输入传递给 SHA256。 但是,由于其背后使用的基础字段的原因,Zokrates中字段值只能容纳 254 位,无法容纳256位的输入。因此,我们使用四个字段元素,每个元素编码 128 位,来表示我们的输入。然后这四个元素在 ZoKrates 中连接起来并传递给 SHA256。 鉴于生成的散列长度为 256 位,我们将其一分为二并将每个值作为 128 位数字返回。

如上,代码实际上只是使用 sha256packed,返回计算出的哈希值。

1.1 首先,我们使用编译命令将程序编译成一个运算电路。

1
zokrates compile -i hashexample.zok

1.2 第二步,我们可以使用以下命令创建见证文件

1
zokrates compute-witness -a 0 0 0 5

使用标志 -a 我们将参数传递给程序。 回想一下,我们的目标是计算数字 5 的哈希值。因此我们将 a、b 和 c 设置为 0,将 d 设置为 5

此时,我们可以检查 witness 文件中的返回值:

1
2
3
grep '~out' witness
~out_0 263561599766550617289250058199814760685
~out_1 65303172752238645975888084098459749904

因此,通过将输出连接为 128 位数字,我们得到以下值作为我们选择的原像的哈希值:

1
2
3
4
5
6
7
8
9
10
11
// 计算5的sha256
import hashlib

preimage = bytes.fromhex('00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05')

bin(int(preimage.hex(), 16)) //binary representation of pre-image
//output is '0b101'

hashlib.sha256(preimage).hexdigest() //compute hash
//output is
//'c6481e22c5ff4164af680b8cfaa5e8ed3120eeff89c4f307c4a6faaae059ce10'

此处,愿像的hash值‘c6481e22c5ff4164af680b8cfaa5e8ed3120eeff89c4f307c4a6faaae059ce10’ 与 witness中out_0 out_1拼接后的hash内容是一致的。

2. 证明原像知识

现在,我们已经看到我们可以使用 ZoKrates 计算哈希值。

让我们回顾一下我们的目标:Peggy 想证明她知道 Victor 选择的摘要的原像,但不透露原像是什么。 现在让我们假设 Victor 选择摘要作为我们在上面的示例中找到的摘要。

为了让它发挥作用,双方必须遵循他们在协议中的角色:

2.1 Victor 必须指定他感兴趣的哈希

因此,我们必须调整由 ZoKrates 编译的 zkSNARK 电路,这样除了计算摘要外,它还根据 Victor 提供的感兴趣的摘要对其进行验证。 这导致 hashexample.zok 的以下更新:

1
2
3
4
5
6
7
8
import "hashes/sha256/512bitPacked" as sha256packed;

def main(private field a, private field b, private field c, private field d) {
field[2] h = sha256packed([a, b, c, d]);
assert(h[0] == 263561599766550617289250058199814760685);
assert(h[1] == 65303172752238645975888084098459749904);
return;
}

请注意,现在将 sha256packed 的结果与 Victor 定义的硬编码正确解决方案进行比较。 我们添加的行被视为断言:验证者不会接受不满足这些约束的证明。 显然,如果所有计算的位都相等,则此程序仅返回 1。

2.2 Victor 现在可以编译代码

1
2
3
4
5
zokrates compile -i hashexample.zok

zokrates setup

zokrates export-verifier

setup创建一个 verification.key 文件和一个 proving.key 文件。 Victor把证明钥匙给了Peggy

2.3 Peggy 提供正确的原像作为程序的参数

1
zokrates compute-witness -a 0 0 0 5

2.4 Peggy 可以运行命令来构建证明

1
zokrates generate-proof

由于输入在程序中被声明为私有,因此由于协议的零知识属性,它们不会出现在证明中。

ZoKrates 创建一个文件 proof.json,由构成 zkSNARKs 证明的三个椭圆曲线点组成。 Victor 部署的智能合约中的 verifyTx 函数接受这三个值以及一系列公共输入。公共输入数组包括:

  • main 函数的任何公共输入,声明时没有使用 private 关键字
  • ZoKrates 函数的返回值

在本示例中,所有输入都是私有的,并且只有一个返回值 1。

2.5 然后 Peggy 可以通过调用 verifyTx 提交她的证明

2.6 Victor 监控验证智能合约以获取 Peggy 交易的返回值

一旦Victor观察到来自 Peggy 的公共地址的具有真实返回值的交易,Victor就可以确定Peggy拥有他在智能合约中设置的哈希值的有效原像。

3.延伸

在此示例中只涉及两方。这种特殊情况使得处理 zkSNARKs 的信任假设变得容易:只有 Victor 对验证 Peggy 的声明感兴趣,因此他可以信任他对设置阶段的执行。

一般来说,多方可能有兴趣验证Peggy声明的正确性。例如,在基于零知识的加密货币 Zcash 中,每个节点都需要能够验证交易的正确性。为了将设置阶段推广到这些多方用例,需要执行一个通常称为“可信设置”或“仪式”的过程。

即可以实现 - https://willzhuang.github.io/2020/06/23/%E4%BD%93%E9%AA%8Czksync-2/

4.结论

这可能算做一个知识证明,但是题目中的应用实例,是什么呢?

参考链接 - circom - https://willzhuang.github.io/2021/05/06/circom%E8%AF%95%E7%94%A8/

来自中科大校友,粤港澳大湾区数字经济研究院工程总监,曾任微软(中国)操作系统工程院院长,微软亚洲互联网工程院副院长,谢育涛,在2月19日的分享。