689 lines
20 KiB
C
689 lines
20 KiB
C
/*
|
|
* Copyright 2023 The Tongsuo Project Authors. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
* in the file LICENSE in the source distribution or at
|
|
* https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt
|
|
*/
|
|
|
|
#include <openssl/opensslconf.h>
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include "apps.h"
|
|
#include "progs.h"
|
|
#include <openssl/bio.h>
|
|
#include <openssl/err.h>
|
|
#include <openssl/pem.h>
|
|
#include <openssl/rand.h>
|
|
#include <openssl/bulletproofs.h>
|
|
#include <openssl/ec.h>
|
|
#include <internal/cryptlib.h>
|
|
|
|
#define MAX_NUM 64
|
|
#define BULLETPROOFS_BITS_DEFAULT 32
|
|
#define BULLETPROOFS_AGG_MAX_DEFAULT 1
|
|
#define BULLETPROOFS_CURVE_DEFAULT "secp256k1"
|
|
#define _STR(x) #x
|
|
#define STR(x) _STR(x)
|
|
|
|
static int verbose = 0, noout = 0;
|
|
|
|
typedef enum OPTION_choice {
|
|
OPT_COMMON,
|
|
OPT_PPGEN, OPT_PP, OPT_WITNESS, OPT_PROOF, OPT_PROVE, OPT_VERIFY,
|
|
OPT_CURVE_NAME, OPT_GENS_CAPACITY, OPT_PARTY_CAPACITY, OPT_R1CS, OPT_R1CS_CONSTRAINT,
|
|
OPT_IN, OPT_PP_IN, OPT_WITNESS_IN, OPT_OUT, OPT_NOOUT,
|
|
OPT_TEXT, OPT_VERBOSE,
|
|
OPT_PROV_ENUM
|
|
} OPTION_CHOICE;
|
|
|
|
const OPTIONS bulletproofs_options[] = {
|
|
{OPT_HELP_STR, 1, '-', "Usage: %s [action options] [input/output options] [arg1] [arg2]\n"},
|
|
|
|
OPT_SECTION("General"),
|
|
{"help", OPT_HELP, '-', "Display this summary"},
|
|
|
|
OPT_SECTION("Action"),
|
|
{"ppgen", OPT_PPGEN, '-', "Generate a bulletproofs public parameter, usage: -ppgen -curve_name secp256k1 -gens_capacity 32 -party_capacity 8"},
|
|
{"pp", OPT_PP, '-', "Display/Parse a bulletproofs public parameter"},
|
|
{"witness", OPT_WITNESS, '-', "Generate/Display a bulletproofs witness"},
|
|
{"proof", OPT_PROOF, '-', "Display/Parse a bulletproofs proof"},
|
|
{"prove", OPT_PROVE, '-', "Bulletproofs prove operation: proof of generating at least one number with bulletproofs public parameters, "
|
|
"usage: -prove secret1 secret2 ... secret64, secretx is an example number"},
|
|
{"verify", OPT_VERIFY, '-', "Bulletproofs verify operation: verifies that the supplied proof is a valid proof, "
|
|
"usage: -verify -in file, file is the proof file path"},
|
|
|
|
OPT_SECTION("PPGEN"),
|
|
{"curve_name", OPT_CURVE_NAME, 's', "The curve name of the bulletproofs public parameter, default: " STR(BULLETPROOFS_CURVE_DEFAULT) ""},
|
|
{"gens_capacity", OPT_GENS_CAPACITY, 'N', "The number of generators to precompute for each party. "
|
|
"For range_proof, it is the maximum bitsize of the range_proof,"
|
|
"maximum value is 64. For r1cs_proof, the capacity must be greater "
|
|
"than the number of multipliers, rounded up to the next power of two."
|
|
", default: " STR(BULLETPROOFS_GENS_CAPACITY_DEFAULT) ""},
|
|
{"party_capacity", OPT_PARTY_CAPACITY, 'N', "The maximum number of parties that can produce on aggregated range proof."
|
|
"For r1cs_proof, set to 1. default: 1"},
|
|
|
|
OPT_SECTION("R1CS Witness"),
|
|
{"r1cs", OPT_R1CS, '-', "Switch for R1CS witness."},
|
|
|
|
OPT_SECTION("R1CS Prove/Verify"),
|
|
{"r1cs_constraint", OPT_R1CS_CONSTRAINT, 's', "R1CS constraint"},
|
|
|
|
OPT_SECTION("Input"),
|
|
{"in", OPT_IN, 's', "Input file"},
|
|
{"pp_in", OPT_PP_IN, 's', "Input is a bulletproofs public parameter file used to generate proof or verify proof"},
|
|
{"witness_in", OPT_WITNESS_IN, 's', "Input is a bulletproofs witness file used to generate proof or verify proof"},
|
|
|
|
OPT_SECTION("Output"),
|
|
{"out", OPT_OUT, '>', "Output the bulletproofs key to specified file"},
|
|
{"noout", OPT_NOOUT, '-', "Don't print bulletproofs action result"},
|
|
{"text", OPT_TEXT, '-', "Print the bulletproofs key in text"},
|
|
{"verbose", OPT_VERBOSE, '-', "Verbose output"},
|
|
|
|
OPT_PARAMETERS(),
|
|
{"arg...", 0, 0, "Additional parameters for bulletproofs operations"},
|
|
|
|
{NULL}
|
|
};
|
|
|
|
static int bulletproofs_pub_param_gen(const char *curve_name, int gens_capacity,
|
|
int party_capacity, const char *out_file,
|
|
int text)
|
|
{
|
|
int ret = 0;
|
|
BIO *bio = NULL;
|
|
BP_PUB_PARAM *pp = NULL;
|
|
|
|
if (!(pp = BP_PUB_PARAM_new_by_curve_name(curve_name, gens_capacity, party_capacity)))
|
|
goto err;
|
|
|
|
if (!(bio = bio_open_owner(out_file, FORMAT_PEM, 1)))
|
|
goto err;
|
|
if (text && !BP_PUB_PARAM_print(bio, pp, 0))
|
|
goto err;
|
|
|
|
if (!PEM_write_bio_BULLETPROOFS_PublicParam(bio, pp))
|
|
goto err;
|
|
|
|
ret = 1;
|
|
|
|
err:
|
|
BIO_free(bio);
|
|
BP_PUB_PARAM_free(pp);
|
|
return ret;
|
|
}
|
|
|
|
static int bulletproofs_pub_param_print(const BP_PUB_PARAM *pp,
|
|
ZKP_TRANSCRIPT *transcript,
|
|
const char *out_file, int text)
|
|
{
|
|
int ret = 0;
|
|
BIO *bio = NULL;
|
|
|
|
if (pp == NULL || !(bio = bio_open_owner(out_file, FORMAT_PEM, 1)))
|
|
goto err;
|
|
|
|
if (text && !BP_PUB_PARAM_print(bio, pp, 0))
|
|
goto err;
|
|
|
|
if (!noout) {
|
|
if (!PEM_write_bio_BULLETPROOFS_PublicParam(bio, pp))
|
|
goto err;
|
|
}
|
|
|
|
ret = 1;
|
|
|
|
err:
|
|
BIO_free(bio);
|
|
return ret;
|
|
}
|
|
|
|
static int bulletproofs_range_proof_print(const BP_RANGE_PROOF *proof,
|
|
const char *out_file, int text)
|
|
{
|
|
int ret = 0;
|
|
BIO *bio = NULL;
|
|
|
|
if (proof == NULL || !(bio = bio_open_owner(out_file, FORMAT_PEM, 1)))
|
|
goto err;
|
|
|
|
if (text && !BP_RANGE_PROOF_print(bio, proof, 0))
|
|
goto err;
|
|
|
|
if (!noout) {
|
|
if (!PEM_write_bio_BULLETPROOFS_RangeProof(bio, proof))
|
|
goto err;
|
|
}
|
|
|
|
ret = 1;
|
|
|
|
err:
|
|
BIO_free(bio);
|
|
return ret;
|
|
}
|
|
|
|
static int bulletproofs_r1cs_proof_print(const BP_R1CS_PROOF *proof,
|
|
const char *out_file, int text)
|
|
{
|
|
int ret = 0;
|
|
BIO *bio = NULL;
|
|
|
|
if (proof == NULL || !(bio = bio_open_owner(out_file, FORMAT_PEM, 1)))
|
|
goto err;
|
|
|
|
if (text && !BP_R1CS_PROOF_print(bio, proof, 0))
|
|
goto err;
|
|
|
|
if (!noout) {
|
|
if (!PEM_write_bio_BULLETPROOFS_R1CSProof(bio, proof))
|
|
goto err;
|
|
}
|
|
|
|
ret = 1;
|
|
|
|
err:
|
|
BIO_free(bio);
|
|
return ret;
|
|
}
|
|
|
|
static int bulletproofs_long_witness_print(const BP_WITNESS *witness,
|
|
const char *out_file, int text)
|
|
{
|
|
int ret = 0;
|
|
BIO *bio = NULL;
|
|
|
|
if (witness == NULL || !(bio = bio_open_owner(out_file, FORMAT_PEM, 1)))
|
|
goto err;
|
|
|
|
if (text && !BP_WITNESS_print(bio, witness, 0, 1))
|
|
goto err;
|
|
|
|
if (!noout) {
|
|
if (!PEM_write_bio_BULLETPROOFS_LongWitness(bio, witness))
|
|
goto err;
|
|
}
|
|
|
|
ret = 1;
|
|
|
|
err:
|
|
BIO_free(bio);
|
|
return ret;
|
|
}
|
|
|
|
static int bulletproofs_short_witness_print(const BP_WITNESS *witness,
|
|
const char *out_file, int text)
|
|
{
|
|
int ret = 0;
|
|
BIO *bio = NULL;
|
|
|
|
if (witness == NULL || !(bio = bio_open_default(out_file, 'a', FORMAT_PEM)))
|
|
goto err;
|
|
|
|
if (text && !BP_WITNESS_print(bio, witness, 0, 0))
|
|
goto err;
|
|
|
|
if (!noout) {
|
|
if (!PEM_write_bio_BULLETPROOFS_ShortWitness(bio, witness))
|
|
goto err;
|
|
}
|
|
|
|
ret = 1;
|
|
|
|
err:
|
|
BIO_free(bio);
|
|
return ret;
|
|
}
|
|
|
|
static int bulletproofs_witness_action(const BP_PUB_PARAM *pp,
|
|
ZKP_TRANSCRIPT *transcript, char *argv[],
|
|
int argc, int r1cs, const char *out_file,
|
|
int text)
|
|
{
|
|
int ret = 0, i, value;
|
|
char *name = NULL, *equal_mark, *val;
|
|
BIGNUM *v = NULL;
|
|
BN_CTX *bn_ctx = NULL;
|
|
BP_WITNESS *witness = NULL;
|
|
|
|
if (argc == 0) {
|
|
BIO_printf(bio_err, "Error: witness's parameters are not specified.\n");
|
|
goto err;
|
|
}
|
|
|
|
if (!(witness = BP_WITNESS_new(pp)))
|
|
goto err;
|
|
|
|
if (!(bn_ctx = BN_CTX_new()))
|
|
goto err;
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
name = NULL;
|
|
val = argv[i];
|
|
equal_mark = strchr(argv[i], '=');
|
|
if (equal_mark != NULL) {
|
|
*equal_mark = '\0';
|
|
name = argv[i];
|
|
val = equal_mark + 1;
|
|
}
|
|
if (!opt_int(val, &value))
|
|
goto err;
|
|
|
|
if (!(v = BN_CTX_get(bn_ctx)))
|
|
goto err;
|
|
|
|
BN_set_word(v, value < 0 ? -value : value);
|
|
BN_set_negative(v, value < 1);
|
|
|
|
if (r1cs) {
|
|
if (!BP_WITNESS_r1cs_commit(witness, name, v))
|
|
goto err;
|
|
} else {
|
|
if (!BP_WITNESS_commit(witness, name, v))
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
ret = bulletproofs_long_witness_print(witness, out_file, text);
|
|
|
|
err:
|
|
BN_CTX_free(bn_ctx);
|
|
BP_WITNESS_free(witness);
|
|
return ret;
|
|
}
|
|
|
|
static int bulletproofs_range_prove(BP_PUB_PARAM *pp, ZKP_TRANSCRIPT *transcript,
|
|
BP_WITNESS *witness, const char *out_file,
|
|
int text)
|
|
{
|
|
int ret = 0;
|
|
BP_RANGE_CTX *ctx = NULL;
|
|
BP_RANGE_PROOF *proof = NULL;
|
|
|
|
if (pp == NULL || transcript == NULL || witness == NULL)
|
|
return ret;
|
|
|
|
if (!(ctx = BP_RANGE_CTX_new(pp, witness, transcript)))
|
|
goto err;
|
|
|
|
if (!(proof = BP_RANGE_PROOF_new_prove(ctx)))
|
|
goto err;
|
|
|
|
ret = bulletproofs_range_proof_print(proof, out_file, text) &&
|
|
bulletproofs_short_witness_print(witness, out_file, text);
|
|
|
|
err:
|
|
BP_RANGE_PROOF_free(proof);
|
|
BP_RANGE_CTX_free(ctx);
|
|
return ret;
|
|
}
|
|
|
|
static int bulletproofs_range_verify(BP_PUB_PARAM *pp, ZKP_TRANSCRIPT *transcript,
|
|
BP_WITNESS *witness, BP_RANGE_PROOF *proof,
|
|
const char *out_file)
|
|
{
|
|
BIO *bio = NULL;
|
|
int ret = 0, result;
|
|
BP_RANGE_CTX *ctx = NULL;
|
|
|
|
if (pp == NULL || witness == NULL || proof == NULL || transcript == NULL
|
|
|| !(bio = bio_open_owner(out_file, FORMAT_TEXT, 1)))
|
|
goto err;
|
|
|
|
if (!(ctx = BP_RANGE_CTX_new(pp, witness, transcript)))
|
|
goto err;
|
|
|
|
result = BP_RANGE_PROOF_verify(ctx, proof);
|
|
|
|
if (result)
|
|
BIO_puts(bio, "The proof is valid\n");
|
|
else
|
|
BIO_puts(bio, "The proof is invalid\n");
|
|
|
|
ret = 1;
|
|
|
|
err:
|
|
BP_RANGE_CTX_free(ctx);
|
|
BIO_free(bio);
|
|
return ret;
|
|
}
|
|
|
|
static int bulletproofs_r1cs_prove(BP_PUB_PARAM *pp, ZKP_TRANSCRIPT *transcript,
|
|
BP_WITNESS *witness, const char *constraint,
|
|
const char *out_file, int text)
|
|
{
|
|
int ret = 0;
|
|
BP_R1CS_CTX *ctx = NULL;
|
|
BP_R1CS_PROOF *proof = NULL;
|
|
|
|
if (pp == NULL || transcript == NULL || witness == NULL || constraint == NULL)
|
|
return ret;
|
|
|
|
if (!(ctx = BP_R1CS_CTX_new(pp, witness, transcript)))
|
|
goto err;
|
|
|
|
if (!BP_R1CS_constraint_expression(ctx, constraint, 1))
|
|
goto err;
|
|
|
|
if (!(proof = BP_R1CS_PROOF_prove(ctx)))
|
|
goto err;
|
|
|
|
ret = bulletproofs_r1cs_proof_print(proof, out_file, text) &&
|
|
bulletproofs_short_witness_print(witness, out_file, text);
|
|
|
|
err:
|
|
BP_R1CS_PROOF_free(proof);
|
|
BP_R1CS_CTX_free(ctx);
|
|
return ret;
|
|
}
|
|
|
|
static int bulletproofs_r1cs_verify(BP_PUB_PARAM *pp, ZKP_TRANSCRIPT *transcript,
|
|
BP_WITNESS *witness, BP_R1CS_PROOF *proof,
|
|
const char *constraint, const char *out_file)
|
|
{
|
|
BIO *bio = NULL;
|
|
int ret = 0, result;
|
|
BP_R1CS_CTX *ctx = NULL;
|
|
|
|
if (pp == NULL || witness == NULL || proof == NULL || constraint == NULL
|
|
|| !(bio = bio_open_owner(out_file, FORMAT_TEXT, 1)))
|
|
goto err;
|
|
|
|
if (!(ctx = BP_R1CS_CTX_new(pp, witness, transcript)))
|
|
goto err;
|
|
|
|
if (!BP_R1CS_constraint_expression(ctx, constraint, 0))
|
|
goto err;
|
|
|
|
result = BP_R1CS_PROOF_verify(ctx, proof);
|
|
|
|
if (result)
|
|
BIO_puts(bio, "The proof is valid\n");
|
|
else
|
|
BIO_puts(bio, "The proof is invalid\n");
|
|
|
|
ret = 1;
|
|
|
|
err:
|
|
BP_R1CS_CTX_free(ctx);
|
|
BIO_free(bio);
|
|
return ret;
|
|
}
|
|
|
|
int bulletproofs_main(int argc, char **argv)
|
|
{
|
|
BIO *in_bio = NULL, *pp_bio = NULL, *witness_bio = NULL;
|
|
ZKP_TRANSCRIPT *transcript = NULL;
|
|
BP_PUB_PARAM *bp_pp = NULL;
|
|
BP_WITNESS *bp_witness = NULL;
|
|
BP_RANGE_PROOF *bp_range_proof = NULL;
|
|
BP_R1CS_PROOF *bp_r1cs_proof = NULL;
|
|
long len;
|
|
int ret = 1, actions = 0, text = 0;
|
|
int gens_capacity = BULLETPROOFS_BITS_DEFAULT, party_capacity = 1, r1cs = 0;
|
|
int ppgen = 0, pp = 0, witness = 0, proof = 0, prove = 0, verify = 0;
|
|
char *pp_file = NULL, *witness_file = NULL, *in_file = NULL, *out_file = NULL;
|
|
char *r1cs_constraint = NULL, *name = NULL, *header = NULL;
|
|
unsigned char *data = NULL;
|
|
const unsigned char *p = NULL;
|
|
char *prog, *curve_name = BULLETPROOFS_CURVE_DEFAULT;
|
|
OPTION_CHOICE o;
|
|
|
|
prog = opt_init(argc, argv, bulletproofs_options);
|
|
if ((o = opt_next()) != OPT_EOF) {
|
|
switch (o) {
|
|
case OPT_EOF:
|
|
case OPT_ERR:
|
|
opthelp1:
|
|
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
|
|
goto err;
|
|
case OPT_HELP:
|
|
ret = 0;
|
|
opt_help(bulletproofs_options);
|
|
goto err;
|
|
case OPT_PPGEN:
|
|
ppgen = 1;
|
|
break;
|
|
case OPT_PP:
|
|
pp = 1;
|
|
break;
|
|
case OPT_WITNESS:
|
|
witness = 1;
|
|
break;
|
|
case OPT_PROOF:
|
|
proof = 1;
|
|
break;
|
|
case OPT_PROVE:
|
|
prove = 1;
|
|
break;
|
|
case OPT_VERIFY:
|
|
verify = 1;
|
|
break;
|
|
default:
|
|
goto opthelp1;
|
|
}
|
|
}
|
|
|
|
actions = ppgen + pp + witness + proof + prove + verify;
|
|
if (actions == 0) {
|
|
BIO_printf(bio_err, "No action parameter specified.\n");
|
|
goto opthelp1;
|
|
} else if (actions != 1) {
|
|
BIO_printf(bio_err, "Only one action parameter must be specified.\n");
|
|
goto opthelp1;
|
|
}
|
|
|
|
while ((o = opt_next()) != OPT_EOF) {
|
|
switch (o) {
|
|
case OPT_EOF:
|
|
case OPT_ERR:
|
|
opthelp2:
|
|
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
|
|
goto err;
|
|
case OPT_HELP:
|
|
ret = 0;
|
|
opt_help(bulletproofs_options);
|
|
goto err;
|
|
case OPT_CURVE_NAME:
|
|
curve_name = opt_arg();
|
|
break;
|
|
case OPT_GENS_CAPACITY:
|
|
gens_capacity = opt_int_arg();
|
|
break;
|
|
case OPT_PARTY_CAPACITY:
|
|
party_capacity = opt_int_arg();
|
|
break;
|
|
case OPT_IN:
|
|
in_file = opt_arg();
|
|
break;
|
|
case OPT_PP_IN:
|
|
pp_file = opt_arg();
|
|
break;
|
|
case OPT_WITNESS_IN:
|
|
witness_file = opt_arg();
|
|
break;
|
|
case OPT_OUT:
|
|
out_file = opt_arg();
|
|
break;
|
|
case OPT_R1CS:
|
|
r1cs = 1;
|
|
break;
|
|
case OPT_R1CS_CONSTRAINT:
|
|
r1cs_constraint = opt_arg();
|
|
break;
|
|
case OPT_NOOUT:
|
|
noout = 1;
|
|
break;
|
|
case OPT_TEXT:
|
|
text = 1;
|
|
break;
|
|
case OPT_VERBOSE:
|
|
verbose = 1;
|
|
break;
|
|
default:
|
|
goto opthelp2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* One optional argument, the bitsize. */
|
|
argc = opt_num_rest();
|
|
argv = opt_rest();
|
|
|
|
if (witness) {
|
|
if (argc > MAX_NUM) {
|
|
BIO_printf(bio_err, "The number of parameters has exceeded %d.\n", MAX_NUM);
|
|
goto opthelp2;
|
|
}
|
|
} else {
|
|
if (argc > 0) {
|
|
BIO_printf(bio_err, "Extra arguments given.\n");
|
|
goto opthelp2;
|
|
}
|
|
}
|
|
|
|
if (!app_RAND_load())
|
|
goto err;
|
|
|
|
if (ppgen) {
|
|
ret = bulletproofs_pub_param_gen(curve_name, gens_capacity,
|
|
party_capacity, out_file, text);
|
|
goto err;
|
|
}
|
|
|
|
if (in_file) {
|
|
in_bio = bio_open_default(in_file, 'r', FORMAT_PEM);
|
|
if (in_bio == NULL) {
|
|
BIO_printf(bio_err, "File %s failed to read.\n", in_file);
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
if (pp_file) {
|
|
pp_bio = bio_open_default(pp_file, 'r', FORMAT_PEM);
|
|
if (pp_bio == NULL) {
|
|
BIO_printf(bio_err, "File %s failed to read.\n", pp_file);
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
if (witness_file) {
|
|
witness_bio = bio_open_default(witness_file, 'r', FORMAT_PEM);
|
|
if (witness_bio == NULL) {
|
|
BIO_printf(bio_err, "File %s failed to read.\n", pp_file);
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
if (prove) {
|
|
if (witness_bio == NULL) {
|
|
BIO_printf(bio_err, "No witness_in parameter specified.\n");
|
|
goto err;
|
|
}
|
|
|
|
if (!(bp_witness = PEM_read_bio_BULLETPROOFS_LongWitness(witness_bio,
|
|
NULL, NULL, NULL)))
|
|
goto err;
|
|
}
|
|
|
|
if (proof || verify) {
|
|
if (in_bio == NULL) {
|
|
BIO_printf(bio_err, "Error: -in is not specified.\n");
|
|
goto opthelp2;
|
|
}
|
|
|
|
while (PEM_read_bio(in_bio, &name, &header, &data, &len)) {
|
|
p = data;
|
|
if (strcmp(name, PEM_STRING_BULLETPROOFS_RANGE_PROOF) == 0) {
|
|
bp_range_proof = d2i_BP_RANGE_PROOF(NULL, &p, len);
|
|
} else if (strcmp(name, PEM_STRING_BULLETPROOFS_R1CS_PROOF) == 0) {
|
|
bp_r1cs_proof = d2i_BP_R1CS_PROOF(NULL, &p, len);
|
|
} else if (strcmp(name, PEM_STRING_BULLETPROOFS_WITNESS) == 0) {
|
|
bp_witness = d2i_short_BP_WITNESS(NULL, &p, len);
|
|
} else {
|
|
BIO_printf(bio_err, "Error: -in file is invalid.\n");
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
if (bp_range_proof == NULL && bp_r1cs_proof == NULL) {
|
|
BIO_printf(bio_err, "Error: -in file is invalid.\n");
|
|
goto err;
|
|
}
|
|
|
|
if (proof) {
|
|
ret = 0;
|
|
if (bp_range_proof) {
|
|
ret = bulletproofs_range_proof_print(bp_range_proof, out_file, text);
|
|
} else if (bp_r1cs_proof) {
|
|
ret = bulletproofs_r1cs_proof_print(bp_r1cs_proof, out_file, text);
|
|
}
|
|
|
|
if (ret && bp_witness)
|
|
ret = bulletproofs_short_witness_print(bp_witness, out_file, text);
|
|
|
|
goto err;
|
|
}
|
|
} else if (argc == 0 && witness && in_bio != NULL) {
|
|
bp_witness = PEM_read_bio_BULLETPROOFS_LongWitness(in_bio, NULL, NULL,
|
|
NULL);
|
|
ret = bulletproofs_long_witness_print(bp_witness, out_file, text);
|
|
goto err;
|
|
}
|
|
|
|
if (pp_bio) {
|
|
if (!(bp_pp = PEM_read_bio_BULLETPROOFS_PublicParam(pp_bio, NULL,
|
|
NULL, NULL)))
|
|
goto err;
|
|
}
|
|
|
|
if (!bp_pp && in_bio) {
|
|
if (!(bp_pp = PEM_read_bio_BULLETPROOFS_PublicParam(in_bio, NULL,
|
|
NULL, NULL)))
|
|
goto err;
|
|
}
|
|
|
|
if (bp_pp == NULL) {
|
|
BIO_printf(bio_err, "Error: -pp_in is not specified.\n");
|
|
goto opthelp2;
|
|
}
|
|
|
|
if (!(transcript = ZKP_TRANSCRIPT_new(ZKP_TRANSCRIPT_METHOD_sha256(), "bulletproofs_app")))
|
|
goto err;
|
|
|
|
if (pp) {
|
|
ret = bulletproofs_pub_param_print(bp_pp, transcript, out_file, text);
|
|
} else if (witness) {
|
|
ret = bulletproofs_witness_action(bp_pp, transcript, argv, argc, r1cs, out_file, text);
|
|
} else if (prove) {
|
|
if (r1cs_constraint) {
|
|
ret = bulletproofs_r1cs_prove(bp_pp, transcript, bp_witness, r1cs_constraint, out_file, text);
|
|
} else {
|
|
ret = bulletproofs_range_prove(bp_pp, transcript, bp_witness, out_file, text);
|
|
}
|
|
} else if (verify) {
|
|
if (r1cs_constraint) {
|
|
ret = bulletproofs_r1cs_verify(bp_pp, transcript, bp_witness, bp_r1cs_proof, r1cs_constraint, out_file);
|
|
} else {
|
|
ret = bulletproofs_range_verify(bp_pp, transcript, bp_witness, bp_range_proof, out_file);
|
|
}
|
|
}
|
|
|
|
err:
|
|
ret = ret ? 0 : 1;
|
|
BIO_free_all(in_bio);
|
|
BIO_free_all(pp_bio);
|
|
ZKP_TRANSCRIPT_free(transcript);
|
|
BP_RANGE_PROOF_free(bp_range_proof);
|
|
BP_R1CS_PROOF_free(bp_r1cs_proof);
|
|
BP_PUB_PARAM_free(bp_pp);
|
|
if (ret != 0) {
|
|
BIO_printf(bio_err, "May be extra arguments error, please use -help for usage summary.\n");
|
|
ERR_print_errors(bio_err);
|
|
}
|
|
return ret;
|
|
}
|