1.0.4 • Published 12 months ago

@latticelabs/zkp-js v1.0.4

Weekly downloads
-
License
ISC
Repository
-
Last release
12 months ago

bulletproof-js

零知识范围证明Bulletproofs的js版本代码。

注:为了将bulletproof-js(js)源码与BulletProofLib(java)源码的计算方式和生成结果保持一致,并实现未来曲线的可扩展性,对bulletproof-js原始代码进行了部分修改,调用方式也有所不同,修改后的使用方式见本文档。

由于改动较多,原始版本的测试用例失效,原始版本的测试用例见test_original,原始说明文档见README_original.md。

原始版本链接:https://www.npmjs.com/package/bulletproof-js


零知识范围证明(Zero-Knowledge Range Proof)是零知识证明的一种特殊类型,用于证明一个秘密值在某一特定范围内,而不透露实际值。比如,零知识范围证明可以用来在保密交易中证明交易金额数量在规定范围内而无需透露实际金额,也可以用来证明一个人的年龄大于18岁而无需透露准确年龄。

Bulletproofs是一种简短的、非交互式的零知识证明协议,不需要可信设置(Trusted Setup),证明时间短,证明大小与证据大小呈对数关系。Bulletproofs提出的零知识范围证明协议,可以用来证明承诺的值在 [0, 2^n) 范围内且不透露实际值。

Bulletproofs使用的承诺方案是Pedersen承诺。

Pedersen承诺

承诺方案(Commitment Scheme)是一种密码学基本协议,允许一方在不透露的情况下承诺一个值,随后以一种使其他人相信承诺的值没有被改变的方式透露该值。公式为 Com(x, r),其中x是被承诺的秘密值,r是致盲因子。

Pedersen承诺是一种同态承诺协议,具有完美隐藏性和计算绑定性。

Pedersen承诺的同态性表现在: Com(x1+x2, r1+r2) = Com(x1, r1) + Com(x2, r2)

意味着,验证者可以在不知道x1, x2的情况下,通过将其承诺相加得出其总和 (x1+x2) 的承诺。

生成承诺

const bulletproofs = require('../bulletproof-js');

const CommitmentUtils = bulletproofs.CommitmentUtils;
const PedGeneratorParams = bulletproofs.PedGeneratorParams;
const Rand = bulletproofs.Rand;

// 选择曲线库,目前支持两种曲线库("elliptic"和"@noble/curves")
// 速度对比:
// Android:elliptic > noble > noble-safe
// iOS:noble > noble-safe > elliptic (elliptic在iOS的速度过慢,不建议使用)
const library = "elliptic";  // elliptic库
// const library = "noble";     // @noble/curves库,使用安全性较低的乘法运算,但速度比安全方式快
// const library = "noble-safe";   // @noble/curves库,使用安全的乘法运算,但速度较慢

// 设置曲线名,未来可扩展为其他曲线
const curveName = "secp256k1";

// 生成承诺的基础参数,包含 g、h、group
const pedGenParams = PedGeneratorParams.generateParams(library, curveName);
// 点运算方法
const PointFn = pedGenParams.PointFn;

// 被承诺的秘密值
const a = 333n;

// 随机数,用作承诺的致盲因子
const r = Rand.randUnder(pedGenParams.n);

// 计算Pedersen承诺
const V = CommitmentUtils.getPedersenCommitment(a, r, pedGenParams);

// 承诺转换成字符串
const V_str = PointFn.toHexString(V);
console.log("V = " + V_str);

// 字符串转换成承诺
const subV2 = PointFn.fromHexString(V_str, pedGenParams.CurveFn);

承诺的同态减法

const bulletproofs = require("../bulletproof");

const CommitmentUtils = bulletproofs.CommitmentUtils;
const PedGeneratorParams = bulletproofs.PedGeneratorParams;
const Rand = bulletproofs.Rand;

// 选择曲线库
// const library = "elliptic";
// const library = "noble";
const library = "noble-safe";

// 设置曲线名
const curveName = "secp256k1";

// 生成承诺的基础参数,包含 g、h、group
const pedGenParams = PedGeneratorParams.generateParams(library, curveName);
// 点运算方法
const PointFn = pedGenParams.PointFn;

// 计算承诺1
const a1 = 333n;
const r1 = Rand.randUnder(pedGenParams.n);
const V1 = CommitmentUtils.getPedersenCommitment(a1, r1, pedGenParams);

// 计算承诺2
const a2 = 111n;
const r2 = Rand.randUnder(pedGenParams.n);
const V2 = CommitmentUtils.getPedersenCommitment(a2, r2, pedGenParams);

// 承诺的同态减法,Com(x1-x2,r1-r2) = Com(x1,r1) - Com(x2,r2)
const subResult = CommitmentUtils.getPedersenCommitment(a1-a2, r1-r2, pedGenParams);
const subResult2 = CommitmentUtils.comSubCom(V1, V2, PointFn);

console.log("subResult = " + PointFn.toHexString(subResult));
console.log("subResult2 = " + PointFn.toHexString(subResult2));

承诺示例

049c6fd84cb3e37c890ad10827e49031656c71e625ab373483f0f9b5163796b0a682d60923594694db252496fa7ec2dcdd94ce8c1cd41c243df82b1009c2883a3c

Bulletproofs范围证明

Bulletproofs范围证明用来证明承诺的值在 [0, 2^n) 范围内且不透露实际值。配合承诺方案,可以实现某个秘密值处于某个范围 a, b 的零知识范围证明。

其非交互式对数范围证明,包含4步:

  1. 生成基础参数
  2. 生成承诺:证明者生成 v 的承诺 V。
  3. 生成范围证明:证明者生成 v 在 [0, 2^n) 范围内的范围证明,范围证明内容见示例。
  4. 验证范围证明:验证者验证范围证明的有效性,即验证承诺 V 和范围证明匹配且承诺 V 对应的值 v 在 [0, 2^n) 范围内。
const bulletproofs = require("../bulletproof");

const ProofFactory = bulletproofs.ProofFactory;
const CommitmentUtils = bulletproofs.CommitmentUtils;
const GeneratorParams = bulletproofs.GeneratorParams;
const PedGeneratorParams = bulletproofs.PedGeneratorParams;
const Rand = bulletproofs.Rand;
const CompressedBulletproof = bulletproofs.CompressedProofs;

// 选择曲线库,目前支持两种曲线库("elliptic"和"@noble/curves")
// 速度对比:
// Android:elliptic > noble > noble-safe
// iOS:noble > noble-safe > elliptic (elliptic在iOS的速度过慢,不建议使用)
const library = "elliptic";
// const library = "noble";
// const library = "noble-safe";

// 设置曲线名
const curveName = "secp256k1";

// 生成承诺的基础参数,包含 g、h、group
const pedGenParams = PedGeneratorParams.generateParams(library, curveName);
// 点运算方法
const PointFn = pedGenParams.PointFn;

// 秘密值
const a = 333n;
// 随机数,用作承诺的致盲因子
const r = Rand.randUnder(pedGenParams.n);
// 计算Pedersen承诺
const V = CommitmentUtils.getPedersenCommitment(a, r, pedGenParams);

// 设置范围证明的范围大小,表示后续生成“秘密值处于[0, 2^size)”的范围证明
const size = 64;
// 生成范围证明的基础参数,包含 gs、hs、g、h、group
const genParams = GeneratorParams.generateParams(size, library, curveName, pedGenParams);
// 设置范围证明的下界和上界(必须是2的指数)
// 该版本的范围证明目前只支持[0, 2^upper)范围,与size的作用类似,注意upper与size保持统一
const low = 0n;
const upper = 64n;

// 计算非压缩的范围证明
const uncompr_proof = ProofFactory.computeBulletproof(a, r, V, genParams, low, upper, false);
// 计算压缩的范围证明(即最后所终的范围证明)
const compr_proof = uncompr_proof.compressProof(genParams, false);

// 范围证明转json字符串
const proof_json = compr_proof.toJson(false, PointFn); // 常规输出json字符串
// const proof_json2 = compr_proof.toJson(true, PointFn); // 美观输出json字符串

// json字符串转范围证明
const proof2 = CompressedBulletproof.fromJsonString(
  proof_json, 
  genParams.pedGen.CurveFn, 
  PointFn
);

// 验证范围证明
console.log(
    proof2.verify(low, upper, V, genParams)
        ? 'Valid proof' 
        : 'Invalid Proof'
    );

注:为了将js版本与java版本的范围证明生成结果保持一致,修改了原始版本中范围证明与json字符串的转换方式,原始转换方式是CompressedBulletproof.toJsonOriginal(),修改后的转换方式是CompressedBulletproof.toJson()。

范围证明示例(修改后的转换方式)

{
    "A":"044d42bce744a705986a7446afaae2058d3d0cb07a976e407495e200a3ac1b72b624141fe8df1a16bbc71f3fce8e4914fea4baa9b16ab984bd84fa4896d741e5db",
    "S":"042ca1fde4f1a25ad4e61198db49b9d03bbda89bd2e252af2c401e13f867f89de0139fc58f0b79b2ff226b98f128bd20f59c9ff9bf664d89f7c06c2adb64772458",
    "T":[
        "04d5a5f3382303232eaea65d2b45431606dc0fdc2a86482eb78ef62255e1d48e5b718304ad259fb0520aabb2cb8156a0278bdc8015d8c0eb3c48d90aebdc7de463",
        "0425a2376830cdf3d3e2c94d04248a7a6b8910fc0d07889f15b2128d67ab93dc583ce408ed259f904a5877f0d4b9e7ec047e7e4e6728af131b06caeee2ffa1d80a"
    ],
    "tauX":"ef075e7e15187b42506cf559b4f972eb873e36a82d3560ed38120d087c8ce1a6",
    "mu":"88c670c39d7f4afe3193bc39383f54307c62dd64935d3b62373592958fa5197a",
    "tx":"1e5297bcfe3337f6b78d55b83c87096d50d49658149fd8736a0f2e1174b62049",
    "productProof":{
        "a":"af22d2067f625edaa5a59473d827b0ced46557be350cc90e6b8fb284b5ae7459",
        "b":"44a89f56bfe04fa5b47549c230fd8df491ed609def47f8a308cc25f36c31c886",
        "L":[
            "04b121ed8055d344607dbc8214ed1a57616345318531bc2d206edf1ca2bada19244e03e624f3a31322a2eb02ceef317d42c91d9a1c8e13726a40a983caa0d44c63",
            "0463aadb44671c8239603c495f01d3ae7397898df8e3fd61465665550d2052c38ff4d21d03ec74a03c9ffd6df085547f3d6950180a5d131265327d703bd75b346c",
            "045232a620086ea9332dba15cffd61759dfe9adaa9e485cb73864c1bf8a023b0a8601e931139dc42bc4ff3d5a70dd289811be172d7a6b79b0832552e288b0c67da",
            "045d9df613ef1f019a4502db1414aa4fa1e4408a9a2ef9a35e3019d3f4df55e45571ffabdae823c626c817fc30f86fe901c95c50c03d6490e3c1d2525f601ea675",
            "0467f3093f7bcd6169e13e4ecc3e478a656c06978befb51a6fa6211a57130655e7d3662f1bd4825c1d081e16ba8a7672d00b3237147af254e57428353bf5ae716b",
            "04ac475372ac0852ee8c8f274cd864ef3a1485aea8276175a6c8c565abaeeec59d4cdaadb4e5f7dbd3e11e66d17eb02cd6ac609eefb59f61439807cb143f642740"
        ],
        "R":[
            "04c955ae6ebd6d26b21bc1093f5575d23d18b13264204864f6f2d7d69a8dc1a4e2d2af1d8915c704b271edab0ada229266bacb6ab851ad3671dbe7f8decff41bae",
            "04cb1d2ecf195275b899b3be6958144b7a5d06e077322cdfaf737e06a935e91fdea5dd490f5e8d3d262060c97d23564fc17525c6b4890aa71cca28b6d72b07514a",
            "04c0ae814ea322f5636dac2037171f6089177b538377f22cf307e55dd101d73717cc4aea3615c974ac3673d5f7d364c94bbc93cc4c6b9c574b57c9d1ef9b9ba4dc",
            "044b19aff84387780ef00d74016c40c24edd0d11be3a39b46875a33529e2c439b0c8e3433179e6a3ef39a05c15abc31eca4f2e7d8b9db69cdb55df52b2af3c9594",
            "040cb145e073ce745197c97468a2f508c99a042321ffb44eb5386d48f68218a9c4620a36815747946680249760cc87fae1712b891ee08d91a44d6697721062b5d4",
            "04c5c48f728f5d24e69e3e6d7dc7c3e4d73d8c4f49a620fceb455725904d5b6d62e2a73dd3d939e2d1d6ac3f6e6024827a71dcc1b06e597ed87195eafd931d9d38"
        ]
    }
}