概述
chiavdf是chia.net开发的一个开源软件库,用于chia区块链(XCH币)。chiavdf是chia区块链的关键模块之一,功能是提供VDF接口函数,进而限制区块产生的速度。
本文分析了chiavdf的软件需求和主要代码,翻译了部分英文文献,并总结了文献中的概念与代码元素(函数、变量等)的对应关系。
本文使用1.0.2版本的代码,代码来源是github:
https://github.com/Chia-Network/chiavdf
本文首发于csdn.net,转载请注明。本文的原创性已经过OTS(https://opentimestamps.org/)和ipfs(ipfs.io)双重认证,CID=Qmbf5o6C9pyCN8RYyTGki4AA5LDBoHW633fmoN1CN1zKzs
准备工作
除了chiavdf源代码外,你还需要准备:
材料 | 下载地址 | 说明 |
CHIA主链模块源码 | 这个模块使用python编写,而chiavdf是用C++编写的。 | |
CHIA绿皮书 | 官方英文绿皮书 | |
VDF算法文档 | 这是CHIA绿皮书的参考文献之一。 | |
类群算法文档 | https://github.com/Chia-Network/chiavdf/blob/main/classgroups.pdf 这个文档和chiavdf源代码放在同一个github仓库中 | 如果已下载完整的chiavdf仓库则无需再下载。 |
gmp开发手册 | 这是在线阅读文档,无需下载。 | gmp是一个数学运算库,如果你很了解它可以跳过。 |
此外,你可能还需要一本高等代数的入门书,VDF算法中用到了很多群论、域论和二元二次型的概念。
chiavdf的软件需求
VDF的英文全称是“verifiable delay function”,本章翻译了一些VDF相关的英文文献,并分析了需求。本章并没有定义一个具体的VDF算法。
如果你只关注代码(对理论不感兴趣)可以跳过前2节直接看需求分析。
本文首发于csdn.net,转载请注明。本文的原创性已经过OTS(https://opentimestamps.org/)和ipfs(ipfs.io)双重认证,CID=Qmbf5o6C9pyCN8RYyTGki4AA5LDBoHW633fmoN1CN1zKzs
可验证单线程延时函数
(译者注:本节为翻译,节选自CHIA绿皮书2.3节)
(编者注:本章有大量希腊字母和公式,我偷个懒直接贴图片了o(^▽^)o )
(编者再注:笔者、作者、译者、编者其实都是我一个人)
强调一下攻击者只有顺序操作次数的限制,但可以有很高的并行运算能力。因此VDF无法通过并行运算加速,但允许通过并行运算来加速一次操作。
一些翻译问题
VDF的英文全称是“verifiable delay function”,中文直译是“可验证延时函数”。但单线程运算是VDF区别于一般延时函数的主要特征,故笔者将VDF译为“可验证单线程延时函数”。
我将“sequentialitiy”译作“抗并行能力”显然不是直译,但我认为这样更贴切。
CHIA绿皮书并不是学术论文,本身逻辑不甚严谨,再加上经过一次不专(◔‸◔)业的翻译,难免有逻辑不通之处。我会在剩余章节中理清这些逻辑,前后矛盾时以后者为准。
需求分析
VDF算法设计
本章翻译VDF算法文档的关键章节,描述核心算法,并给出了一些概念的中文译名。
一些子函数
计算π的值
(译者注:本节为翻译,节选自VDF算法文档4.1节)
存储优化
(译者注:本节为翻译,节选自VDF算法文档4.2节)
分段VDF算法
(译者注:本节为翻译,节选自VDF算法文档4.3节)
快速VDF算法
(译者注:本节为翻译,选自VDF算法文档最后一页。我严重怀疑原作者排版排错了,这段应该放在第4章)
(译者注:这段的英文注释没什么用,容我偷个懒o(^▽^)o )
类群算法设计
本章翻译类群算法文档的关键章节,描述核心算法,并给出了一些概念的中文译名。
二元二次型
(译者注:本节为翻译,节选自类群算法文档第2章)
我们将f写作f=(a,b,c),并称f是一个“型”(form)。这些是我们将在本文中讨论的对象。(译者注:显然(a,b,c)三元组可以准确唯一的表示f。form在代码中也表示二元二次型,而非表格或外表。)
定义2.2【整二次型】(Integral form):如果一个二元二次型的a、b、c全都是整数,则称之为“整二次型”。
整二次型是代数数论的重点研究领域,也是Chia VDF所使用的主要理论。本文的剩余部分将只讨论整二次型。
定义2.3【二次型的最大公约数】(Content of a form):用cont(f)表示,一个二次型的最大公约数cont(f)=gcd(a,b,c)。
定义2.4【素二次型】(Primitive form):如果cont(f)=1,则称f是一个“素二次型”。
判别式
(译者注:本节为翻译,节选自类群算法文档2.1节)
标准化算法
(译者注:本节为翻译,节选自类群算法文档5.1节)
标准化算法的性质
- 对标准型进行标准化,其值不变。
- 对a>0的非标准型进行标准化,其结果一定是标准型。
- 标准化算法保持判别式的值不变。
约化算法
(译者注:本节为翻译,节选自类群算法文档5.2节)
定义5.3【约化型】(Reduced form):对于一个正定的、标准的二次型f=(a,b,c),如果a≤c,且当a=c时b>0,则称f是“约化”的。
对二元二次型的约化对Chia VDF至关重要,因为连续的平方运算会使得a、b、c的值不断增大(译者注:每次平方之后进行一次约化可以避免a、b、c的绝对值无限增大),并且约化可以计算出等价类中的最简二次型(译者注:指等价类中唯一的约化型)。
对于任意Δ<0,每一个等价类里都有一个唯一的、约化的代表元。我们可以由此(指约化型)推出一些判别式的性质,比如等价类的数量。
本文首发于csdn.net,转载请注明。本文的原创性已经过OTS(https://opentimestamps.org/)和ipfs(ipfs.io)双重认证,CID=Qmbf5o6C9pyCN8RYyTGki4AA5LDBoHW633fmoN1CN1zKzs
平方运算
(译者注:本节为翻译,节选自类群算法文档6.3.1节)
解同余方程
(译者注:本节为翻译,节选自类群算法文档7.4.1节)
对外接口
chiavdf的(对外)接口函数定义在src/python_bindings/fastvdf.cpp中,共有4个,功能见下表:
函数名 | 功能 | 对应需求 | 主链模块调用 |
prove | 延时并计算一个延时证明 | VDF.solve | 无 |
verify_wesolowski | 验证一个证明是否合法 | VDF.verify | 无 |
verify_n_wesolowski | 验证分段VDF算法的证明是否合法 | VDF.verify | vdf.py |
create_discriminant | 构造一个伪随机的判别式 | vdf.py timelord.py |
除此之外,还有一个独立进程vdf_client,主函数定义在vdf_client.cpp中。vdf_client使用TCP套接字与其它进程通信。
prove实现了VDF延时算法。
verify_wesolowski实现了VDF验证算法。
prove和verify_wesolowski用于测试程序,它们在主链模块中不直接使用。
类型
本章列举一些关键的类型。
struct integer
自定义整数类,定义在integer_common.h中,提供大整数运算功能。内部使用gmp库实现。
struct form
描述一个二元二次型,定义在vdf_new.h中。
常量和变量
常量
本节列举一些关键的常量,包括由宏定义的常量。
#define BQFC_MAX_D_BITS 1024
/* Force all forms to have the same size (100 bytes). */
#define BQFC_FORM_SIZE ((BQFC_MAX_D_BITS + 31) / 32 * 3 + 4)//100
const int B_bits = 264;
const int B_bytes = (B_bits + 7) / 8;//33
const int checkpoint_interval=10000; //at each checkpoint, the slave thread is restarted and the master thread calculates c
变量
本节列举一些关键的变量,包括局部、全局和成员变量。
- D。类型通常为integer,存储判别式。
- L。类型通常为integer,存储-D的4次方根。
D和L在关键代码中多次传参,均使用相同的变量名。
关键代码
chiavdf的关键代码集中在以下文件中:
文件名 | 函数名/类名 | 对应需求 | 说明 |
vdf_client.cpp | SessionOneWeso | VDF.solve | 计算分段延时证明 |
SessionFastAlgorithm | VDF.solve | 计算分段延时证明 | |
vdf.h | repeated_square | VDF.solve | 反复进行平方运算 |
verifier.h | VerifyWesolowskiProof | VDF.verify | 验证一个延时证明 |
CheckProofOfTimeNWesolowski | VDF.verify | 验证分段延时证明 | |
proof_common.h | HashPrime | 生成一个特殊的哈希 | |
prover_slow.h | ProveSlow | VDF.solve | 延时并计算一个延时证明 |
vdf_fast.h | square_state_type | VDF.solve | 进行1次平方运算 |
nucomp.h | qfb_nudupl | VDF.solve | 进行1次平方运算 |
ProveSlow
std::vector<uint8_t> ProveSlow(integer& D, form& x, uint64_t num_iterations)
功能:延时并计算一个延时证明,返回序列化后的延时证明。使用VDF延时算法和快速VDF算法。
qfb_nudupl
void qfb_nudupl(qfb_t r, qfb_t f, mpz_t D, mpz_t L)
功能:计算r=f*f。
此函数实现了二元二次型的平方运算,并使用了一个类群算法文档中没有的变种算法,变种算法可以避免a的值不断增大且不必每次平方后都进行约化(虽然在ProveSlow中每次平方之后都进行了约化)。
VerifyWesolowskiProof
void VerifyWesolowskiProof(integer &D,form x,form y,form proof,uint64_t iters,bool &is_valid)
功能:验证一个延时证明是否合法,返回值存入is_valid。使用VDF验证算法。
CheckProofOfTimeNWesolowski
bool CheckProofOfTimeNWesolowski(integer D,const uint8_t* x_s,const uint8_t* proof_blob,int32_t proof_blob_len,uint64_t iterations,uint64 disc_size_bits,int32_t depth)
功能:验证一组分段延时证明是否合法。
x_s存储一个序列化后的二次型,proof_blob存储一组序列化后的分段延时证明。
HashPrime
integer HashPrime(std::vector<uint8_t> seed, int length, vector<int> bitmask)
功能:生成一个seed的哈希。与一般的哈希函数不同,此函数的返回值大概率是一个素数(小概率是一个没有小素因数的伪素数,但这个几率小到可以忽略)。
HashPrime主要有2个用途,一是生成判别式,二是用作 子函数。
SessionOneWeso
void SessionOneWeso(tcp::socket& sock)
功能:运行分段VDF算法。从sock接收数据,计算结果也从sock发出。
vdf_worker和th_prover对应分段VDF算法中的2个线程。
SessionFastAlgorithm
void SessionFastAlgorithm(tcp::socket& sock)
功能:运行分段VDF算法。从sock接收数据,计算结果也从sock发出。
SessionFastAlgorithm与SessionOneWeso的区别在于后者只接受一次iters,其余的全部作废。SessionFastAlgorithm可以循环执行多次VDF任务,但可读性差一些。
repeated_square
void repeated_square(form f,const integer& D,const integer& L,WesolowskiCallback* weso,FastStorage* fast_storage,std::atomic<bool>& stopped)
功能:反复进行平方运算,内部使用2个线程(square_state_type)加速单次平方运算。
square_state_type
在代码中square_state_type是一个结构体,但有成员函数,可以当作类使用。其功能是使用2个线程加速一次平方运算。
---未完待续---