Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion libsnark/gadgetlib1/gadgets/curves/scalar_multiplication.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ class variable_or_identity : public gadget<libff::Fr<ppT>>
pb_variable<FieldT> is_identity_var;
};

/// Selector gadget for variable_or_identity
/// Selector gadget for variable_or_identity. Outputs one of two
/// variable_or_identity objects, depending on a scalar parameter.
template<
typename ppT,
typename groupT,
Expand Down Expand Up @@ -401,6 +402,51 @@ class point_mul_by_scalar_gadget : public gadget<typename groupT::base_field>
protoboard<Field> &pb, const std::string &annotation_prefix);
};

/// Generic gadget to perform scalar multiplication of variable_or_identity
/// group points by scalar variables. Used by the individual group element
/// implementations.
template<
typename ppT,
typename groupT,
typename groupVarT,
typename selectorGadgetT,
typename addGadgetT,
typename dblGadgetT>
class point_variable_or_identity_mul_by_scalar_gadget
: public gadget<typename groupT::base_field>
{
public:
using Field = libff::Fr<ppT>;
using nFr = libff::Fr<other_curve<ppT>>;

using varMulByScalar = point_mul_by_scalar_gadget<
ppT,
groupT,
groupVarT,
selectorGadgetT,
addGadgetT,
dblGadgetT>;

using groupVarOrIdentity = variable_or_identity<ppT, groupT, groupVarT>;
using selectVarIdentityGadget =
variable_or_identity_selector<ppT, groupT, groupVarT, selectorGadgetT>;

varMulByScalar scalar_mul;
groupVarOrIdentity selected_result;
selectVarIdentityGadget select_result;

point_variable_or_identity_mul_by_scalar_gadget(
protoboard<Field> &pb,
const pb_linear_combination<Field> &scalar,
const groupVarOrIdentity &P,
const groupVarOrIdentity &result,
const std::string &annotation_prefix);

void generate_r1cs_constraints();
void generate_r1cs_witness();
const groupVarOrIdentity &result() const;
};

} // namespace libsnark

#include "libsnark/gadgetlib1/gadgets/curves/scalar_multiplication.tcc"
Expand Down
97 changes: 97 additions & 0 deletions libsnark/gadgetlib1/gadgets/curves/scalar_multiplication.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,103 @@ pb_variable_array<libff::Fr<ppT>> point_mul_by_scalar_gadget<
return bits;
}

template<
typename ppT,
typename groupT,
typename groupVarT,
typename selectorGadgetT,
typename addGadgetT,
typename dblGadgetT>
point_variable_or_identity_mul_by_scalar_gadget<
ppT,
groupT,
groupVarT,
selectorGadgetT,
addGadgetT,
dblGadgetT>::
point_variable_or_identity_mul_by_scalar_gadget(
protoboard<Field> &pb,
const pb_linear_combination<Field> &scalar,
const groupVarOrIdentity &P,
const groupVarOrIdentity &result,
const std::string &annotation_prefix)
: gadget<libff::Fr<ppT>>(pb, annotation_prefix)
, scalar_mul(
pb,
scalar,
P.value,
groupVarOrIdentity(pb, FMT(annotation_prefix, " scalar_mul_result")),
FMT(annotation_prefix, " scalar_mul"))
// result = P.is_identity ? P : scalar_mul_result
// = select(P.is_identity, scalar_mul_result, P)
, selected_result(result)
, select_result(
pb,
P.is_identity,
scalar_mul.result(),
P,
selected_result,
FMT(annotation_prefix, " select_result"))
{
}

template<
typename ppT,
typename groupT,
typename groupVarT,
typename selectorGadgetT,
typename addGadgetT,
typename dblGadgetT>
void point_variable_or_identity_mul_by_scalar_gadget<
ppT,
groupT,
groupVarT,
selectorGadgetT,
addGadgetT,
dblGadgetT>::generate_r1cs_constraints()
{
scalar_mul.generate_r1cs_constraints();
select_result.generate_r1cs_constraints();
}

template<
typename ppT,
typename groupT,
typename groupVarT,
typename selectorGadgetT,
typename addGadgetT,
typename dblGadgetT>
void point_variable_or_identity_mul_by_scalar_gadget<
ppT,
groupT,
groupVarT,
selectorGadgetT,
addGadgetT,
dblGadgetT>::generate_r1cs_witness()
{
scalar_mul.generate_r1cs_witness();
select_result.generate_r1cs_witness();
}

template<
typename ppT,
typename groupT,
typename groupVarT,
typename selectorGadgetT,
typename addGadgetT,
typename dblGadgetT>
const variable_or_identity<ppT, groupT, groupVarT>
&point_variable_or_identity_mul_by_scalar_gadget<
ppT,
groupT,
groupVarT,
selectorGadgetT,
addGadgetT,
dblGadgetT>::result() const
{
return selected_result;
}

} // namespace libsnark

#endif // LIBSNARK_GADGETLIB1_GADGETS_CURVE_SCALAR_MULTIPLICATION_TCC_
10 changes: 10 additions & 0 deletions libsnark/gadgetlib1/gadgets/curves/weierstrass_g1_gadget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,16 @@ using G1_mul_by_scalar_gadget = point_mul_by_scalar_gadget<
G1_add_gadget<wppT>,
G1_dbl_gadget<wppT>>;

template<typename wppT>
using G1_variable_or_identity_mul_by_scalar_gadget =
point_variable_or_identity_mul_by_scalar_gadget<
wppT,
libff::G1<other_curve<wppT>>,
G1_variable<wppT>,
G1_variable_selector_gadget<wppT>,
G1_add_gadget<wppT>,
G1_dbl_gadget<wppT>>;

} // namespace libsnark

#include <libsnark/gadgetlib1/gadgets/curves/weierstrass_g1_gadget.tcc>
Expand Down
10 changes: 10 additions & 0 deletions libsnark/gadgetlib1/gadgets/curves/weierstrass_g2_gadget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,16 @@ using G2_mul_by_scalar_gadget = point_mul_by_scalar_gadget<
G2_add_gadget<wppT>,
G2_dbl_gadget<wppT>>;

template<typename wppT>
using G2_variable_or_identity_mul_by_scalar_gadget =
point_variable_or_identity_mul_by_scalar_gadget<
wppT,
libff::G2<other_curve<wppT>>,
G2_variable<wppT>,
G2_variable_selector_gadget<wppT>,
G2_add_gadget<wppT>,
G2_dbl_gadget<wppT>>;

} // namespace libsnark

#include <libsnark/gadgetlib1/gadgets/curves/weierstrass_g2_gadget.tcc>
Expand Down
Loading