/// The limbs, each of which is a BaseField gadget.
publimbs: Vec<FpVar<BaseField>>,
/// Number of additions done over this gadget, using which the gadget decides when to reduce.
/// Number of additions done over this gadget, using which the gadget
/// decides when to reduce.
pubnum_of_additions_over_normal_form: BaseField,
/// Whether the limb representation is the normal form (using only the bits specified in the parameters, and the representation is strictly within the range of TargetField).
/// Whether the limb representation is the normal form (using only the bits
/// specified in the parameters, and the representation is strictly within
//! This module implements a field gadget for a prime field `Fp` over another prime field `Fq` where `p != q`.
//! This module implements a field gadget for a prime field `Fp` over another
//! prime field `Fq` where `p != q`.
//!
//! When writing constraint systems for many cryptographic proofs, we are restricted to a native field (e.g., the scalar field of the pairing-friendly curve).
//! This can be inconvenient; for example, the recursive composition of proofs via cycles of curves requires the verifier to compute over a non-native field.
//! When writing constraint systems for many cryptographic proofs, we are
//! restricted to a native field (e.g., the scalar field of the pairing-friendly
//! curve). This can be inconvenient; for example, the recursive composition of
//! proofs via cycles of curves requires the verifier to compute over a
//! non-native field.
//!
//! The library makes it possible to write computations over a non-native field in the same way one would write computations over the native field. This naturally introduces additional overhead, which we minimize using a variety of optimizations. (Nevertheless, the overhead is still substantial, and native fields should be used where possible.)
//! The library makes it possible to write computations over a non-native field
//! in the same way one would write computations over the native field. This
//! naturally introduces additional overhead, which we minimize using a variety
//! of optimizations. (Nevertheless, the overhead is still substantial, and
//! native fields should be used where possible.)
//!
//! ## Usage
//!
//! Because [`NonNativeFieldVar`] implements the [`FieldVar`] trait in arkworks, we can treat it like a native field variable ([`FpVar`]).
//! Because [`NonNativeFieldVar`] implements the [`FieldVar`] trait in arkworks,
//! we can treat it like a native field variable ([`FpVar`]).
//!
//! We can do the standard field operations, such as `+`, `-`, and `*`. See the following example:
//! We can do the standard field operations, such as `+`, `-`, and `*`. See the
//! After each multiplication, our library internally performs a *reduce* operation,
//! which reduces an intermediate type [`NonNativeFieldMulResultVar`] to the normalized type [`NonNativeFieldVar`].
//! This enables a user to seamlessly perform a sequence of operations without worrying about the underlying details.
//! After each multiplication, our library internally performs a *reduce*
//! operation, which reduces an intermediate type [`NonNativeFieldMulResultVar`]
//! to the normalized type [`NonNativeFieldVar`]. This enables a user to
//! seamlessly perform a sequence of operations without worrying about the
//! underlying details.
//!
//! However, this operation is expensive and is sometimes avoidable. We can reduce the number of constraints by using this intermediate type, which only supports additions. To multiply, it must be reduced back to [`NonNativeFieldVar`]. See below for a skeleton example.
//! However, this operation is expensive and is sometimes avoidable. We can
//! reduce the number of constraints by using this intermediate type, which only
//! supports additions. To multiply, it must be reduced back to
//! [`NonNativeFieldVar`]. See below for a skeleton example.
//!
//! ---
//!
//! To compute `a * b + c * d`, the straightforward (but more expensive) implementation is as follows:
//! To compute `a * b + c * d`, the straightforward (but more expensive)
//! implementation is as follows:
//!
//! ```ignore
//! let a_times_b = &a * &b;
@ -67,7 +82,8 @@
//!
//! ---
//!
//! We can save one reduction by using the [`NonNativeFieldMulResultVar`], as follows:
//! We can save one reduction by using the [`NonNativeFieldMulResultVar`], as
//! follows:
//!
//! ```ignore
//! let a_times_b = a.mul_without_reduce(&b)?;
@ -75,26 +91,31 @@
//! let res = (&a_times_b + &c_times_d)?.reduce()?;
//! ```
//!
//! It performs only one *reduce* operation and is roughly 2x faster than the first implementation.
//! It performs only one *reduce* operation and is roughly 2x faster than the
//! first implementation.
//!
//! ## Inspiration and basic design
//!
//! This implementation employs the standard idea of using multiple **limbs** to represent an element of the target field. For example, an element in the TargetField may be represented by three BaseField elements (i.e., the limbs).
//! This implementation employs the standard idea of using multiple **limbs** to
//! represent an element of the target field. For example, an element in the
//! TargetField may be represented by three BaseField elements (i.e., the
//! limbs).
//!
//! ```text
//! TargetField -> limb 1, limb 2, and limb 3 (each is a BaseField element)
//! ```
//!
//! After some computation, the limbs become saturated and need to be **reduced**, in order to engage in more computation.
//! After some computation, the limbs become saturated and need to be
//! **reduced**, in order to engage in more computation.
//!
//! We heavily use the optimization techniques in [\[KPS18\]](https://akosba.github.io/papers/xjsnark.pdf) and [\[OWWB20\]](https://eprint.iacr.org/2019/1494).
//! Both works have their own open-source libraries:
//! [xJsnark](https://github.com/akosba/xjsnark) and
//! Compared with these, this module works with the `arkworks` ecosystem.
//! It also provides the option (based on an `optimization_goal` for the constraint system) to optimize
//! for constraint density instead of number of constraints, which improves efficiency in
//! proof systems like [Marlin](https://github.com/arkworks-rs/marlin).
//! It also provides the option (based on an `optimization_goal` for the
//! constraint system) to optimize for constraint density instead of number of
//! constraints, which improves efficiency in proof systems like [Marlin](https://github.com/arkworks-rs/marlin).
//!
//! ## References
//! \[KPS18\]: A. E. Kosba, C. Papamanthou, and E. Shi. "xJsnark: a framework for efficient verifiable computation," in *Proceedings of the 39th Symposium on Security and Privacy*, ser. S&P ’18, 2018, pp. 944–961.
@ -160,7 +181,8 @@ pub(crate) use overhead;
/// Parameters for a specific `NonNativeFieldVar` instantiation
#[derive(Clone, Debug)]
pubstructNonNativeFieldConfig{
/// The number of limbs (`BaseField` elements) used to represent a `TargetField` element. Highest limb first.
/// The number of limbs (`BaseField` elements) used to represent a