├── .gitignore ├── AUTHORS ├── libff ├── algebra │ ├── curves │ │ ├── mnt │ │ │ ├── README.md │ │ │ ├── mnt46_common.cpp │ │ │ ├── mnt46_common.hpp │ │ │ ├── mnt4 │ │ │ │ ├── mnt4_fields.hpp │ │ │ │ ├── mnt4_init.hpp │ │ │ │ ├── mnt4_g2.hpp │ │ │ │ ├── mnt4_g1.hpp │ │ │ │ ├── mnt4_pp.hpp │ │ │ │ └── mnt4_pp.cpp │ │ │ ├── mnt6 │ │ │ │ ├── mnt6_fields.hpp │ │ │ │ ├── mnt6_init.hpp │ │ │ │ ├── mnt6_g2.hpp │ │ │ │ ├── mnt6_g1.hpp │ │ │ │ ├── mnt6_pp.hpp │ │ │ │ └── mnt6_pp.cpp │ │ │ └── mnt.sage │ │ ├── alt_bn128 │ │ │ ├── README.md │ │ │ ├── alt_bn128_init.hpp │ │ │ ├── alt_bn128_fields.hpp │ │ │ ├── alt_bn128_pp.cpp │ │ │ ├── alt_bn128.sage │ │ │ ├── alt_bn128_pp.hpp │ │ │ ├── alt_bn128_g1.hpp │ │ │ ├── alt_bn128_g2.hpp │ │ │ └── alt_bn128_pairing.hpp │ │ ├── bls12_381 │ │ │ ├── README.md │ │ │ ├── bls12_381_init.hpp │ │ │ ├── bls12_381_fields.hpp │ │ │ ├── bls12_381_pp.cpp │ │ │ ├── bls12_381.sage │ │ │ ├── bls12_381_pp.hpp │ │ │ ├── bls12_381_g1.hpp │ │ │ ├── bls12_381_g2.hpp │ │ │ └── bls12_381_pairing.hpp │ │ ├── bn128 │ │ │ ├── bn_utils.hpp │ │ │ ├── bn128_init.hpp │ │ │ ├── bn128_fields.hpp │ │ │ ├── bn_utils.tcc │ │ │ ├── bn128_gt.hpp │ │ │ ├── bn128_gt.cpp │ │ │ ├── bn128_pp.hpp │ │ │ ├── bn128_pairing.hpp │ │ │ ├── bn128_pp.cpp │ │ │ ├── bn128_g2.hpp │ │ │ ├── bn128_g1.hpp │ │ │ └── bn128_fields.cpp │ │ ├── curve_utils.hpp │ │ ├── curve_utils.tcc │ │ ├── edwards │ │ │ ├── edwards_fields.hpp │ │ │ ├── edwards_init.hpp │ │ │ ├── edwards_pp.cpp │ │ │ ├── edwards_pp.hpp │ │ │ ├── edwards_g1.hpp │ │ │ └── edwards_g2.hpp │ │ ├── params_generator.sage │ │ └── public_params.hpp │ ├── fields │ │ ├── binary │ │ │ ├── gf32.tcc │ │ │ ├── gf64.tcc │ │ │ ├── gf128.tcc │ │ │ ├── gf192.tcc │ │ │ ├── gf256.tcc │ │ │ ├── README.md │ │ │ ├── gf32.hpp │ │ │ ├── gf64.hpp │ │ │ ├── gf128.hpp │ │ │ ├── gf192.hpp │ │ │ └── gf256.hpp │ │ └── field.hpp │ ├── scalar_multiplication │ │ ├── wnaf.hpp │ │ └── wnaf.tcc │ └── field_utils │ │ ├── algorithms.hpp │ │ ├── bigint.hpp │ │ └── algorithms.tcc └── common │ ├── rng.hpp │ ├── template_utils.hpp │ ├── utils.tcc │ ├── profiling.hpp │ ├── default_types │ └── ec_pp.hpp │ ├── double.hpp │ ├── rng.tcc │ ├── tests │ └── test_common.cpp │ ├── serialization.hpp │ ├── utils.cpp │ ├── utils.hpp │ └── double.cpp ├── depends └── CMakeLists.txt ├── .gitmodules ├── .clang-tidy ├── clang-tidy.cmake ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── integrate.yml ├── LICENSE └── CHANGELOG.md /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /.idea/ 3 | .DS_Store 4 | .vscode 5 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | SCIPR Lab: 2 | Eli Ben-Sasson 3 | Alessandro Chiesa 4 | Eran Tromer 5 | Madars Virza 6 | Howard Wu 7 | 8 | External contributors: 9 | Alexander Chernyakhovsky (Google Inc.) 10 | Aleksejs Popovs 11 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/README.md: -------------------------------------------------------------------------------- 1 | # Implementation of the MNT4/6 cycle 2 | 3 | ## Run the sage script to generate the curve parameters 4 | 5 | 1. Make sure that you have [SageMath](https://www.sagemath.org/) installed 6 | 7 | 2. Run: 8 | ```bash 9 | sage mnt.sage 10 | ``` 11 | -------------------------------------------------------------------------------- /libff/algebra/curves/alt_bn128/README.md: -------------------------------------------------------------------------------- 1 | # Implementation of altbn128 2 | 3 | ## Run the sage script to generate the curve parameters 4 | 5 | 1. Make sure that you have [SageMath](https://www.sagemath.org/) installed 6 | 7 | 2. Run: 8 | ```bash 9 | sage alt_bn128.sage 10 | ``` 11 | -------------------------------------------------------------------------------- /libff/algebra/curves/bls12_381/README.md: -------------------------------------------------------------------------------- 1 | # Implementation of BLS12-381 2 | 3 | ## Run the sage script to generate the curve parameters 4 | 5 | 1. Make sure that you have [SageMath](https://www.sagemath.org/) installed 6 | 7 | 2. Run: 8 | ```bash 9 | sage bls12_381.sage 10 | ``` 11 | -------------------------------------------------------------------------------- /depends/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(gtest EXCLUDE_FROM_ALL) 2 | 3 | if(${CURVE} STREQUAL "BN128") 4 | include_directories(ate-pairing/include) 5 | include_directories(xbyak) 6 | add_library( 7 | zm 8 | STATIC 9 | 10 | ate-pairing/src/zm.cpp 11 | ate-pairing/src/zm2.cpp 12 | ) 13 | endif() 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "depends/ate-pairing"] 2 | path = depends/ate-pairing 3 | url = https://github.com/herumi/ate-pairing.git 4 | [submodule "depends/xbyak"] 5 | path = depends/xbyak 6 | url = https://github.com/herumi/xbyak.git 7 | [submodule "gtest"] 8 | path = depends/gtest 9 | url = https://github.com/google/googletest.git 10 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/gf32.tcc: -------------------------------------------------------------------------------- 1 | #include "libff/algebra/field_utils/algorithms.hpp" 2 | 3 | namespace libff { 4 | 5 | template 6 | gf32& gf32::operator^=(const bigint &pow) 7 | { 8 | (*this) = *this ^ pow; 9 | return (*this); 10 | } 11 | 12 | template 13 | gf32 gf32::operator^(const bigint &pow) const 14 | { 15 | return power(*this, pow); 16 | } 17 | 18 | } // namespace libff 19 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/gf64.tcc: -------------------------------------------------------------------------------- 1 | #include "libff/algebra/field_utils/algorithms.hpp" 2 | 3 | namespace libff { 4 | 5 | template 6 | gf64& gf64::operator^=(const bigint &pow) 7 | { 8 | (*this) = *this ^ pow; 9 | return (*this); 10 | } 11 | 12 | template 13 | gf64 gf64::operator^(const bigint &pow) const 14 | { 15 | return power(*this, pow); 16 | } 17 | 18 | } // namespace libff 19 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/gf128.tcc: -------------------------------------------------------------------------------- 1 | #include "libff/algebra/field_utils/algorithms.hpp" 2 | 3 | namespace libff { 4 | 5 | template 6 | gf128& gf128::operator^=(const bigint &pow) 7 | { 8 | (*this) = *this ^ pow; 9 | return (*this); 10 | } 11 | 12 | template 13 | gf128 gf128::operator^(const bigint &pow) const 14 | { 15 | return power(*this, pow); 16 | } 17 | 18 | } // namespace libff 19 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/gf192.tcc: -------------------------------------------------------------------------------- 1 | #include "libff/algebra/field_utils/algorithms.hpp" 2 | 3 | namespace libff { 4 | 5 | template 6 | gf192& gf192::operator^=(const bigint &pow) 7 | { 8 | (*this) = *this ^ pow; 9 | return (*this); 10 | } 11 | 12 | template 13 | gf192 gf192::operator^(const bigint &pow) const 14 | { 15 | return power(*this, pow); 16 | } 17 | 18 | } // namespace libff 19 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/gf256.tcc: -------------------------------------------------------------------------------- 1 | #include "libff/algebra/field_utils/algorithms.hpp" 2 | 3 | namespace libff { 4 | 5 | template 6 | gf256& gf256::operator^=(const bigint &pow) 7 | { 8 | (*this) = *this ^ pow; 9 | return (*this); 10 | } 11 | 12 | template 13 | gf256 gf256::operator^(const bigint &pow) const 14 | { 15 | return power(*this, pow); 16 | } 17 | 18 | } // namespace libff 19 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn_utils.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BN_UTILS_HPP_ 9 | #define BN_UTILS_HPP_ 10 | #include 11 | 12 | #include "depends/ate-pairing/include/bn.h" 13 | 14 | namespace libff { 15 | 16 | template 17 | void bn_batch_invert(std::vector &vec); 18 | 19 | } // namespace libff 20 | 21 | #include 22 | 23 | #endif // BN_UTILS_HPP_ 24 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: 2 | -*, 3 | bugprone-*, 4 | -bugprone-exception-escape, 5 | llvm-*, 6 | misc-*, 7 | -misc-non-private-member-variables-in-classes, 8 | modernize-*, 9 | -modernize-avoid-c-arrays, 10 | -modernize-use-auto, 11 | -modernize-use-trailing-return-type, 12 | -modernize-return-braced-init-list, 13 | -modernize-pass-by-value, 14 | -modernize-use-default-member-init, 15 | -modernize-deprecated-headers, 16 | performance-*, 17 | portability-*, 18 | readability-*, 19 | -readability-isolate-declaration, 20 | -readability-magic-numbers, 21 | -readability-function-size, 22 | -clang-diagnostic-deprecated-copy 23 | WarningsAsErrors: 24 | '' 25 | 26 | HeaderFilterRegex: 'libff/*.(hpp|tcc|cpp)' -------------------------------------------------------------------------------- /libff/common/rng.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of functions for generating randomness. 4 | ***************************************************************************** 5 | * @author This file is part of libff, developed by SCIPR Lab 6 | * and contributors (see AUTHORS). 7 | * @copyright MIT license (see LICENSE file) 8 | *****************************************************************************/ 9 | #ifndef RNG_HPP_ 10 | #define RNG_HPP_ 11 | 12 | #include 13 | 14 | namespace libff { 15 | 16 | template 17 | FieldT SHA512_rng(const uint64_t idx); 18 | 19 | } // namespace libff 20 | 21 | #include 22 | 23 | #endif // RNG_HPP_ 24 | -------------------------------------------------------------------------------- /libff/algebra/curves/curve_utils.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef CURVE_UTILS_HPP_ 9 | #define CURVE_UTILS_HPP_ 10 | #include 11 | 12 | #include 13 | 14 | namespace libff { 15 | 16 | template 17 | GroupT scalar_mul(const GroupT &base, const bigint &scalar); 18 | 19 | } // namespace libff 20 | #include 21 | 22 | #endif // CURVE_UTILS_HPP_ 23 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt46_common.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Implementation of functionality that is shared among MNT curves. 5 | 6 | See mnt46_common.hpp . 7 | 8 | ***************************************************************************** 9 | * @author This file is part of libff, developed by SCIPR Lab 10 | * and contributors (see AUTHORS). 11 | * @copyright MIT license (see LICENSE file) 12 | *****************************************************************************/ 13 | 14 | #include 15 | 16 | namespace libff { 17 | 18 | bigint mnt46_modulus_A; 19 | bigint mnt46_modulus_B; 20 | 21 | } // namespace libff 22 | -------------------------------------------------------------------------------- /libff/common/template_utils.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of functions for supporting the use of templates. 4 | ***************************************************************************** 5 | * @author This file is part of libff, developed by SCIPR Lab 6 | * and contributors (see AUTHORS). 7 | * @copyright MIT license (see LICENSE file) 8 | *****************************************************************************/ 9 | #ifndef TEMPLATE_UTILS_HPP_ 10 | #define TEMPLATE_UTILS_HPP_ 11 | 12 | namespace libff { 13 | 14 | /* A commonly used SFINAE helper type */ 15 | template 16 | struct void_type 17 | { 18 | typedef void type; 19 | }; 20 | 21 | } // namespace libff 22 | 23 | #endif // TEMPLATE_UTILS_HPP_ 24 | -------------------------------------------------------------------------------- /clang-tidy.cmake: -------------------------------------------------------------------------------- 1 | option( 2 | USE_CLANG_TIDY 3 | "Use clang-tidy if the program is found." 4 | OFF 5 | ) 6 | 7 | if(USE_CLANG_TIDY) 8 | find_program(CLANG_TIDY clang-tidy) 9 | if(CLANG_TIDY) 10 | file(DOWNLOAD 11 | https://raw.githubusercontent.com/llvm-mirror/clang-tools-extra/master/clang-tidy/tool/run-clang-tidy.py 12 | ${PROJECT_BINARY_DIR}/run-clang-tidy.py 13 | ) 14 | find_program(RUN_CLANG_TIDY run-clang-tidy.py) 15 | if(RUN_CLANG_TIDY) 16 | message("Using clang-tidy. Creating target... To run, use: make clang-tidy") 17 | add_custom_target( 18 | clang-tidy 19 | COMMAND python3 run-clang-tidy.py ../libff/algebra ../libff/common -quiet 2>&1 20 | WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 21 | ) 22 | else() 23 | message( 24 | FATAL_ERROR 25 | "run-clang-tidy.py not found. (Download and place in PATH). Aborting...") 26 | endif() 27 | else() 28 | message(FATAL_ERROR "clang-tidy not found. Aborting...") 29 | endif() 30 | endif() -------------------------------------------------------------------------------- /libff/algebra/curves/curve_utils.tcc: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef CURVE_UTILS_TCC_ 9 | #define CURVE_UTILS_TCC_ 10 | 11 | namespace libff { 12 | 13 | template 14 | GroupT scalar_mul(const GroupT &base, const bigint &scalar) 15 | { 16 | GroupT result = GroupT::zero(); 17 | 18 | bool found_one = false; 19 | for (long i = static_cast(scalar.max_bits() - 1); i >= 0; --i) 20 | { 21 | if (found_one) 22 | { 23 | result = result.dbl(); 24 | } 25 | 26 | if (scalar.test_bit(i)) 27 | { 28 | found_one = true; 29 | result = result + base; 30 | } 31 | } 32 | 33 | return result; 34 | } 35 | 36 | } // namespace libff 37 | #endif // CURVE_UTILS_TCC_ 38 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt46_common.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of functionality that is shared among MNT curves. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT46_COMMON_HPP_ 13 | #define MNT46_COMMON_HPP_ 14 | 15 | #include 16 | 17 | namespace libff { 18 | 19 | const mp_size_t mnt46_A_bitcount = 298; 20 | const mp_size_t mnt46_B_bitcount = 298; 21 | 22 | const mp_size_t mnt46_A_limbs = (mnt46_A_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 23 | const mp_size_t mnt46_B_limbs = (mnt46_B_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 24 | 25 | extern bigint mnt46_modulus_A; 26 | extern bigint mnt46_modulus_B; 27 | 28 | } // namespace libff 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn128_init.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BN128_INIT_HPP_ 9 | #define BN128_INIT_HPP_ 10 | #include "depends/ate-pairing/include/bn.h" 11 | 12 | #include 13 | #include 14 | 15 | namespace libff { 16 | 17 | extern bn::Fp bn128_coeff_b; 18 | extern std::size_t bn128_Fq_s; 19 | extern bn::Fp bn128_Fq_nqr_to_t; 20 | extern mie::Vuint bn128_Fq_t_minus_1_over_2; 21 | 22 | extern bn::Fp2 bn128_twist_coeff_b; 23 | extern std::size_t bn128_Fq2_s; 24 | extern bn::Fp2 bn128_Fq2_nqr_to_t; 25 | extern mie::Vuint bn128_Fq2_t_minus_1_over_2; 26 | 27 | void init_bn128_params(); 28 | 29 | class bn128_G1; 30 | class bn128_G2; 31 | class bn128_GT; 32 | typedef bn128_GT bn128_Fq12; 33 | 34 | } // namespace libff 35 | #endif // BN128_INIT_HPP_ 36 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn128_fields.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BN128_FIELDS_HPP_ 9 | #define BN128_FIELDS_HPP_ 10 | #include "depends/ate-pairing/include/bn.h" 11 | #include 12 | 13 | namespace libff { 14 | 15 | const mp_size_t bn128_r_bitcount = 254; 16 | const mp_size_t bn128_q_bitcount = 254; 17 | 18 | const mp_size_t bn128_r_limbs = (bn128_r_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 19 | const mp_size_t bn128_q_limbs = (bn128_q_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 20 | 21 | extern bigint bn128_modulus_r; 22 | extern bigint bn128_modulus_q; 23 | 24 | typedef Fp_model bn128_Fr; 25 | typedef Fp_model bn128_Fq; 26 | 27 | void init_bn128_fields(); 28 | 29 | } // namespace libff 30 | #endif // BN128_FIELDS_HPP_ 31 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn_utils.tcc: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BN_UTILS_TCC_ 9 | #define BN_UTILS_TCC_ 10 | 11 | namespace libff { 12 | 13 | template 14 | void bn_batch_invert(std::vector &vec) 15 | { 16 | std::vector prod; 17 | prod.reserve(vec.size()); 18 | 19 | FieldT acc = 1; 20 | 21 | for (auto el : vec) 22 | { 23 | assert(!el.isZero()); 24 | prod.emplace_back(acc); 25 | FieldT::mul(acc, acc, el); 26 | } 27 | 28 | FieldT acc_inverse = acc; 29 | acc_inverse.inverse(); 30 | 31 | for (long i = vec.size()-1; i >= 0; --i) 32 | { 33 | const FieldT old_el = vec[i]; 34 | FieldT::mul(vec[i], acc_inverse, prod[i]); 35 | FieldT::mul(acc_inverse, acc_inverse, old_el); 36 | } 37 | } 38 | 39 | } // namespace libff 40 | #endif // FIELD_UTILS_TCC_ 41 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ## Description 8 | 9 | 12 | 13 | closes: #XXXX 14 | 15 | --- 16 | 17 | Before we can merge this PR, please make sure that all the following items have been 18 | checked off. If any of the checklist items are not applicable, please leave them but 19 | write a little note why. 20 | 21 | - [ ] Targeted PR against correct branch (develop) 22 | - [ ] Linked to Github issue with discussion and accepted design OR have an explanation in the PR that describes this work. 23 | - [ ] Wrote unit tests 24 | - [ ] Updated relevant documentation in the code 25 | - [ ] Added a relevant changelog entry to the `Unreleased` section in `CHANGELOG.md` 26 | - [ ] Re-reviewed `Files changed` in the Github PR explorer 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The libff library is developed by SCIPR Lab (http://scipr-lab.org) 2 | and contributors. 3 | 4 | Copyright (c) 2012-2014 SCIPR Lab and contributors (see AUTHORS file). 5 | 6 | All files, with the exceptions below, are released under the MIT License: 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /libff/common/utils.tcc: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Implementation of templatized utility functions. 4 | ***************************************************************************** 5 | * @author This file is part of libff, developed by SCIPR Lab 6 | * and contributors (see AUTHORS). 7 | * @copyright MIT license (see LICENSE file) 8 | *****************************************************************************/ 9 | #ifndef UTILS_TCC_ 10 | #define UTILS_TCC_ 11 | 12 | namespace libff { 13 | 14 | using std::size_t; 15 | 16 | template 17 | size_t curve_size_in_bits(const std::vector &v) 18 | { 19 | return v.size() * CurveT::size_in_bits(); 20 | } 21 | 22 | template 23 | T random_element_non_zero_one() 24 | { 25 | T x = T::random_element(); 26 | while (x.is_zero() || x == T::one()) 27 | x = T::random_element(); 28 | return x; 29 | } 30 | 31 | template 32 | T random_element_non_zero() 33 | { 34 | T x = T::random_element(); 35 | while (x.is_zero()) 36 | x = T::random_element(); 37 | return x; 38 | } 39 | 40 | template 41 | T random_element_exclude(T y) 42 | { 43 | T x = T::random_element(); 44 | while (x == y) 45 | x = T::random_element(); 46 | return x; 47 | } 48 | 49 | } // namespace libff 50 | 51 | #endif // UTILS_TCC_ 52 | -------------------------------------------------------------------------------- /libff/algebra/curves/edwards/edwards_fields.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef EDWARDS_FIELDS_HPP_ 9 | #define EDWARDS_FIELDS_HPP_ 10 | #include 11 | #include 12 | #include 13 | 14 | namespace libff { 15 | 16 | const mp_size_t edwards_r_bitcount = 181; 17 | const mp_size_t edwards_q_bitcount = 183; 18 | 19 | const mp_size_t edwards_r_limbs = (edwards_r_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 20 | const mp_size_t edwards_q_limbs = (edwards_q_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 21 | 22 | extern bigint edwards_modulus_r; 23 | extern bigint edwards_modulus_q; 24 | 25 | typedef Fp_model edwards_Fr; 26 | typedef Fp_model edwards_Fq; 27 | typedef Fp3_model edwards_Fq3; 28 | typedef Fp6_2over3_model edwards_Fq6; 29 | typedef edwards_Fq6 edwards_GT; 30 | 31 | void init_edwards_fields(); 32 | 33 | } // namespace libff 34 | #endif // EDWARDS_FIELDS_HPP_ 35 | -------------------------------------------------------------------------------- /libff/algebra/curves/alt_bn128/alt_bn128_init.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef ALT_BN128_INIT_HPP_ 9 | #define ALT_BN128_INIT_HPP_ 10 | #include 11 | #include 12 | 13 | namespace libff { 14 | 15 | // parameters for Barreto--Naehrig curve E/Fq : y^2 = x^3 + b 16 | extern alt_bn128_Fq alt_bn128_coeff_b; 17 | // parameters for twisted Barreto--Naehrig curve E'/Fq2 : y^2 = x^3 + b/xi 18 | extern alt_bn128_Fq2 alt_bn128_twist; 19 | extern alt_bn128_Fq2 alt_bn128_twist_coeff_b; 20 | extern alt_bn128_Fq alt_bn128_twist_mul_by_b_c0; 21 | extern alt_bn128_Fq alt_bn128_twist_mul_by_b_c1; 22 | extern alt_bn128_Fq2 alt_bn128_twist_mul_by_q_X; 23 | extern alt_bn128_Fq2 alt_bn128_twist_mul_by_q_Y; 24 | 25 | // parameters for pairing 26 | extern bigint alt_bn128_ate_loop_count; 27 | extern bool alt_bn128_ate_is_loop_count_neg; 28 | extern bigint alt_bn128_final_exponent_z; 29 | extern bool alt_bn128_final_exponent_is_z_neg; 30 | 31 | void init_alt_bn128_params(); 32 | 33 | class alt_bn128_G1; 34 | class alt_bn128_G2; 35 | 36 | } // namespace libff 37 | #endif // ALT_BN128_INIT_HPP_ 38 | -------------------------------------------------------------------------------- /libff/algebra/curves/bls12_381/bls12_381_init.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BLS12_381_INIT_HPP_ 9 | #define BLS12_381_INIT_HPP_ 10 | #include 11 | #include 12 | 13 | namespace libff { 14 | 15 | // parameters for the curve E/Fq : y^2 = x^3 + b 16 | extern bls12_381_Fq bls12_381_coeff_b; 17 | // parameters for the twisted curve E'/Fq2 : y^2 = x^3 + b/xi 18 | extern bls12_381_Fq2 bls12_381_twist; 19 | extern bls12_381_Fq2 bls12_381_twist_coeff_b; 20 | extern bls12_381_Fq bls12_381_twist_mul_by_b_c0; 21 | extern bls12_381_Fq bls12_381_twist_mul_by_b_c1; 22 | extern bls12_381_Fq2 bls12_381_twist_mul_by_q_X; 23 | extern bls12_381_Fq2 bls12_381_twist_mul_by_q_Y; 24 | 25 | // parameters for pairing 26 | extern bigint bls12_381_ate_loop_count; 27 | extern bool bls12_381_ate_is_loop_count_neg; 28 | extern bigint<12*bls12_381_q_limbs> bls12_381_final_exponent; 29 | extern bigint bls12_381_final_exponent_z; 30 | extern bool bls12_381_final_exponent_is_z_neg; 31 | 32 | void init_bls12_381_params(); 33 | 34 | class bls12_381_G1; 35 | class bls12_381_G2; 36 | 37 | } // namespace libff 38 | #endif // BLS12_381_INIT_HPP_ 39 | -------------------------------------------------------------------------------- /libff/algebra/scalar_multiplication/wnaf.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of interfaces for wNAF ("width-w Non-Adjacent Form") exponentiation routines. 4 | ***************************************************************************** 5 | * @author This file is part of libff, developed by SCIPR Lab 6 | * and contributors (see AUTHORS). 7 | * @copyright MIT license (see LICENSE file) 8 | *****************************************************************************/ 9 | #ifndef WNAF_HPP_ 10 | #define WNAF_HPP_ 11 | 12 | #include 13 | 14 | #include 15 | 16 | namespace libff { 17 | 18 | /** 19 | * Find the wNAF representation of the given scalar relative to the given window size. 20 | */ 21 | template 22 | std::vector find_wnaf(const std::size_t window_size, const bigint &scalar); 23 | 24 | /** 25 | * In additive notation, use wNAF exponentiation (with the given window size) to compute scalar * base. 26 | */ 27 | template 28 | T fixed_window_wnaf_exp(const std::size_t window_size, const T &base, const bigint &scalar); 29 | 30 | /** 31 | * In additive notation, use wNAF exponentiation (with the window size determined by T) to compute scalar * base. 32 | */ 33 | template 34 | T opt_window_wnaf_exp(const T &base, const bigint &scalar, const std::size_t scalar_bits); 35 | 36 | } // namespace libff 37 | 38 | #include 39 | 40 | #endif // WNAF_HPP_ 41 | -------------------------------------------------------------------------------- /.github/workflows/integrate.yml: -------------------------------------------------------------------------------- 1 | name: main 2 | 3 | on: push 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - name: python_setup 11 | uses: actions/setup-python@v2 12 | with: 13 | python-version: 3.8 14 | - name: before_install 15 | run: | 16 | sudo apt-get install build-essential git libboost-all-dev cmake libgmp3-dev libssl-dev libsodium-dev libprocps-dev pkg-config gcc-10 g++-10 17 | sudo apt-get install clang-tidy 18 | git submodule init && git submodule update 19 | mkdir build 20 | cd build 21 | PATH=$PATH:${PWD} 22 | cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DUSE_CLANG_TIDY=ON .. 23 | - name: run_clang_tidy 24 | id: clang_tidy 25 | run: | 26 | cd build 27 | OUTPUT=$(python3 run-clang-tidy.py ../libff/algebra ../libff/common -quiet 2>&1) 28 | echo "::set-output name=OUTPUT::$OUTPUT" 29 | COUNT=$(echo $OUTPUT | grep "warning:" | wc -l) 30 | echo "::set-output name=COUNT::$COUNT" 31 | - name: check_errors 32 | if: steps.clang_tidy.outputs.COUNT > 0 33 | run: | 34 | echo "Clang-tidy failed. Please look at the run_clang_tidy step to see the details." 35 | exit 1 36 | - name: tests 37 | run: | 38 | cd build 39 | make 40 | make check 41 | - name: run_debug 42 | run: | 43 | rm -r build 44 | mkdir build 45 | cd build 46 | cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DUSE_CLANG_TIDY=OFF -DDEBUG=ON .. 47 | make 48 | make check -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt4/mnt4_fields.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of interfaces for initializing MNT4. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT4_FIELDS_HPP_ 13 | #define MNT4_FIELDS_HPP_ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace libff { 21 | 22 | #define mnt4_modulus_r mnt46_modulus_A 23 | #define mnt4_modulus_q mnt46_modulus_B 24 | 25 | const mp_size_t mnt4_r_bitcount = mnt46_A_bitcount; 26 | const mp_size_t mnt4_q_bitcount = mnt46_B_bitcount; 27 | 28 | const mp_size_t mnt4_r_limbs = mnt46_A_limbs; 29 | const mp_size_t mnt4_q_limbs = mnt46_B_limbs; 30 | 31 | extern bigint mnt4_modulus_r; 32 | extern bigint mnt4_modulus_q; 33 | 34 | typedef Fp_model mnt4_Fr; 35 | typedef Fp_model mnt4_Fq; 36 | typedef Fp2_model mnt4_Fq2; 37 | typedef Fp4_model mnt4_Fq4; 38 | typedef mnt4_Fq4 mnt4_GT; 39 | 40 | void init_mnt4_fields(); 41 | 42 | } // namespace libff 43 | 44 | #endif // MNT4_FIELDS_HPP_ 45 | -------------------------------------------------------------------------------- /libff/algebra/curves/bls12_381/bls12_381_fields.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BLS12_381_FIELDS_HPP_ 9 | #define BLS12_381_FIELDS_HPP_ 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace libff { 16 | 17 | const mp_size_t bls12_381_r_bitcount = 255; 18 | const mp_size_t bls12_381_q_bitcount = 381; 19 | 20 | const mp_size_t bls12_381_r_limbs = (bls12_381_r_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 21 | const mp_size_t bls12_381_q_limbs = (bls12_381_q_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 22 | 23 | extern bigint bls12_381_modulus_r; 24 | extern bigint bls12_381_modulus_q; 25 | 26 | typedef Fp_model bls12_381_Fr; 27 | typedef Fp_model bls12_381_Fq; 28 | typedef Fp2_model bls12_381_Fq2; 29 | typedef Fp6_3over2_model bls12_381_Fq6; 30 | typedef Fp12_2over3over2_model bls12_381_Fq12; 31 | typedef bls12_381_Fq12 bls12_381_GT; 32 | 33 | void init_bls12_381_fields(); 34 | 35 | } // namespace libff 36 | #endif // BLS12_381_FIELDS_HPP_ 37 | -------------------------------------------------------------------------------- /libff/algebra/curves/alt_bn128/alt_bn128_fields.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef ALT_BN128_FIELDS_HPP_ 9 | #define ALT_BN128_FIELDS_HPP_ 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace libff { 16 | 17 | const mp_size_t alt_bn128_r_bitcount = 254; 18 | const mp_size_t alt_bn128_q_bitcount = 254; 19 | 20 | const mp_size_t alt_bn128_r_limbs = (alt_bn128_r_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 21 | const mp_size_t alt_bn128_q_limbs = (alt_bn128_q_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 22 | 23 | extern bigint alt_bn128_modulus_r; 24 | extern bigint alt_bn128_modulus_q; 25 | 26 | typedef Fp_model alt_bn128_Fr; 27 | typedef Fp_model alt_bn128_Fq; 28 | typedef Fp2_model alt_bn128_Fq2; 29 | typedef Fp6_3over2_model alt_bn128_Fq6; 30 | typedef Fp12_2over3over2_model alt_bn128_Fq12; 31 | typedef alt_bn128_Fq12 alt_bn128_GT; 32 | 33 | void init_alt_bn128_fields(); 34 | 35 | } // namespace libff 36 | 37 | #endif // ALT_BN128_FIELDS_HPP_ 38 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt6/mnt6_fields.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of interfaces for initializing MNT6. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT6_FIELDS_HPP_ 13 | #define MNT6_FIELDS_HPP_ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace libff { 22 | 23 | #define mnt6_modulus_r mnt46_modulus_B 24 | #define mnt6_modulus_q mnt46_modulus_A 25 | 26 | const mp_size_t mnt6_r_bitcount = mnt46_B_bitcount; 27 | const mp_size_t mnt6_q_bitcount = mnt46_A_bitcount; 28 | 29 | const mp_size_t mnt6_r_limbs = mnt46_B_limbs; 30 | const mp_size_t mnt6_q_limbs = mnt46_A_limbs; 31 | 32 | extern bigint mnt6_modulus_r; 33 | extern bigint mnt6_modulus_q; 34 | 35 | typedef Fp_model mnt6_Fr; 36 | typedef Fp_model mnt6_Fq; 37 | typedef Fp3_model mnt6_Fq3; 38 | typedef Fp6_2over3_model mnt6_Fq6; 39 | typedef mnt6_Fq6 mnt6_GT; 40 | 41 | void init_mnt6_fields(); 42 | 43 | } // namespace libff 44 | 45 | #endif // MNT6_FIELDS_HPP_ 46 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt4/mnt4_init.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of interfaces for initializing MNT4. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT4_INIT_HPP_ 13 | #define MNT4_INIT_HPP_ 14 | 15 | #include 16 | #include 17 | 18 | namespace libff { 19 | 20 | // parameters for twisted short Weierstrass curve E'/Fq2 : y^2 = x^3 + (a * twist^2) * x + (b * twist^3) 21 | extern mnt4_Fq2 mnt4_twist; 22 | extern mnt4_Fq2 mnt4_twist_coeff_a; 23 | extern mnt4_Fq2 mnt4_twist_coeff_b; 24 | extern mnt4_Fq mnt4_twist_mul_by_a_c0; 25 | extern mnt4_Fq mnt4_twist_mul_by_a_c1; 26 | extern mnt4_Fq mnt4_twist_mul_by_b_c0; 27 | extern mnt4_Fq mnt4_twist_mul_by_b_c1; 28 | extern mnt4_Fq mnt4_twist_mul_by_q_X; 29 | extern mnt4_Fq mnt4_twist_mul_by_q_Y; 30 | 31 | // parameters for pairing 32 | extern bigint mnt4_ate_loop_count; 33 | extern bool mnt4_ate_is_loop_count_neg; 34 | extern bigint<4*mnt4_q_limbs> mnt4_final_exponent; 35 | extern bigint mnt4_final_exponent_last_chunk_abs_of_w0; 36 | extern bool mnt4_final_exponent_last_chunk_is_w0_neg; 37 | extern bigint mnt4_final_exponent_last_chunk_w1; 38 | 39 | void init_mnt4_params(); 40 | 41 | class mnt4_G1; 42 | class mnt4_G2; 43 | 44 | } // namespace libff 45 | 46 | #endif // MNT4_INIT_HPP_ 47 | -------------------------------------------------------------------------------- /libff/algebra/curves/bls12_381/bls12_381_pp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace libff { 4 | 5 | void bls12_381_pp::init_public_params() 6 | { 7 | init_bls12_381_params(); 8 | } 9 | 10 | bls12_381_GT bls12_381_pp::final_exponentiation(const bls12_381_Fq12 &elt) 11 | { 12 | return bls12_381_final_exponentiation(elt); 13 | } 14 | 15 | bls12_381_G1_precomp bls12_381_pp::precompute_G1(const bls12_381_G1 &P) 16 | { 17 | return bls12_381_precompute_G1(P); 18 | } 19 | 20 | bls12_381_G2_precomp bls12_381_pp::precompute_G2(const bls12_381_G2 &Q) 21 | { 22 | return bls12_381_precompute_G2(Q); 23 | } 24 | 25 | bls12_381_Fq12 bls12_381_pp::miller_loop(const bls12_381_G1_precomp &prec_P, 26 | const bls12_381_G2_precomp &prec_Q) 27 | { 28 | return bls12_381_miller_loop(prec_P, prec_Q); 29 | } 30 | 31 | bls12_381_Fq12 bls12_381_pp::double_miller_loop(const bls12_381_G1_precomp &prec_P1, 32 | const bls12_381_G2_precomp &prec_Q1, 33 | const bls12_381_G1_precomp &prec_P2, 34 | const bls12_381_G2_precomp &prec_Q2) 35 | { 36 | return bls12_381_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); 37 | } 38 | 39 | bls12_381_Fq12 bls12_381_pp::pairing(const bls12_381_G1 &P, 40 | const bls12_381_G2 &Q) 41 | { 42 | return bls12_381_pairing(P, Q); 43 | } 44 | 45 | bls12_381_Fq12 bls12_381_pp::reduced_pairing(const bls12_381_G1 &P, 46 | const bls12_381_G2 &Q) 47 | { 48 | return bls12_381_reduced_pairing(P, Q); 49 | } 50 | 51 | } // namespace libff 52 | -------------------------------------------------------------------------------- /libff/algebra/curves/edwards/edwards_init.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef EDWARDS_INIT_HPP_ 9 | #define EDWARDS_INIT_HPP_ 10 | #include 11 | #include 12 | 13 | namespace libff { 14 | 15 | // parameters for Edwards curve E_{1,d}(F_q) 16 | extern edwards_Fq edwards_coeff_a; 17 | extern edwards_Fq edwards_coeff_d; 18 | // parameters for twisted Edwards curve E_{a',d'}(F_q^3) 19 | extern edwards_Fq3 edwards_twist; 20 | extern edwards_Fq3 edwards_twist_coeff_a; 21 | extern edwards_Fq3 edwards_twist_coeff_d; 22 | extern edwards_Fq edwards_twist_mul_by_a_c0; 23 | extern edwards_Fq edwards_twist_mul_by_a_c1; 24 | extern edwards_Fq edwards_twist_mul_by_a_c2; 25 | extern edwards_Fq edwards_twist_mul_by_d_c0; 26 | extern edwards_Fq edwards_twist_mul_by_d_c1; 27 | extern edwards_Fq edwards_twist_mul_by_d_c2; 28 | extern edwards_Fq edwards_twist_mul_by_q_Y; 29 | extern edwards_Fq edwards_twist_mul_by_q_Z; 30 | 31 | // parameters for pairing 32 | extern bigint edwards_ate_loop_count; 33 | extern bigint edwards_final_exponent_last_chunk_abs_of_w0; 34 | extern bool edwards_final_exponent_last_chunk_is_w0_neg; 35 | extern bigint edwards_final_exponent_last_chunk_w1; 36 | 37 | void init_edwards_params(); 38 | 39 | class edwards_G1; 40 | class edwards_G2; 41 | 42 | } // namespace libff 43 | #endif // EDWARDS_INIT_HPP_ 44 | -------------------------------------------------------------------------------- /libff/common/profiling.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of functions for profiling code blocks. 4 | 5 | Reports time, operation counts, memory usage, and others. 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | #ifndef PROFILING_HPP_ 12 | #define PROFILING_HPP_ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace libff { 20 | 21 | void start_profiling(); 22 | long long get_nsec_time(); 23 | void print_time(const char* msg); 24 | void print_header(const char* msg); 25 | void print_separator(); 26 | 27 | void print_indent(); 28 | 29 | extern bool inhibit_profiling_info; 30 | extern bool inhibit_profiling_counters; 31 | extern std::map invocation_counts; 32 | extern std::map last_times; 33 | extern std::map cumulative_times; 34 | 35 | void clear_profiling_counters(); 36 | 37 | void print_cumulative_time_entry(const std::string &key, const long long factor=1); 38 | void print_cumulative_times(const long long factor=1); 39 | void print_cumulative_op_counts(const bool only_fq=false); 40 | 41 | void enter_block(const std::string &msg, const bool indent=true); 42 | void leave_block(const std::string &msg, const bool indent=true); 43 | 44 | void print_mem(const std::string &s = ""); 45 | void print_compilation_info(); 46 | 47 | } // namespace libff 48 | 49 | #endif // PROFILING_HPP_ 50 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn128_gt.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BN128_GT_HPP_ 9 | #define BN128_GT_HPP_ 10 | #include 11 | 12 | #include "depends/ate-pairing/include/bn.h" 13 | 14 | #include 15 | #include 16 | 17 | namespace libff { 18 | 19 | class bn128_GT; 20 | std::ostream& operator<<(std::ostream &, const bn128_GT&); 21 | std::istream& operator>>(std::istream &, bn128_GT&); 22 | 23 | class bn128_GT { 24 | public: 25 | static bn128_GT GT_one; 26 | bn::Fp12 elem; 27 | 28 | bn128_GT(); 29 | bool operator==(const bn128_GT &other) const; 30 | bool operator!=(const bn128_GT &other) const; 31 | 32 | bn128_GT operator*(const bn128_GT &other) const; 33 | bn128_GT unitary_inverse() const; 34 | 35 | static bn128_GT one(); 36 | 37 | void print() { std::cout << this->elem << "\n"; }; 38 | 39 | friend std::ostream& operator<<(std::ostream &out, const bn128_GT &g); 40 | friend std::istream& operator>>(std::istream &in, bn128_GT &g); 41 | }; 42 | 43 | template 44 | bn128_GT operator^(const bn128_GT &rhs, const bigint &lhs) 45 | { 46 | return power(rhs, lhs); 47 | } 48 | 49 | 50 | template& modulus_p> 51 | bn128_GT operator^(const bn128_GT &rhs, const Fp_model &lhs) 52 | { 53 | return power(rhs, lhs.as_bigint()); 54 | } 55 | 56 | } // namespace libff 57 | #endif // BN128_GT_HPP_ 58 | -------------------------------------------------------------------------------- /libff/algebra/field_utils/algorithms.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of interfaces for (square-and-multiply) exponentiation and 4 | Tonelli-Shanks square root. 5 | ***************************************************************************** 6 | * @author This file is part of libff, developed by SCIPR Lab 7 | * and contributors (see AUTHORS). 8 | * @copyright MIT license (see LICENSE file) 9 | *****************************************************************************/ 10 | 11 | #ifndef ALGORITHMS_HPP_ 12 | #define ALGORITHMS_HPP_ 13 | 14 | #include 15 | 16 | #include "libff/algebra/field_utils/bigint.hpp" 17 | 18 | namespace libff { 19 | 20 | /** Repeated squaring. */ 21 | template 22 | FieldT power(const FieldT &base, const bigint &exponent); 23 | 24 | /** Repeated squaring. */ 25 | template 26 | FieldT power(const FieldT &base, const unsigned long exponent); 27 | 28 | /** 29 | * The unsigned long long versions exist because libiop tends to use size_t instead 30 | * of unsigned long, and size_t may be the same size as ul or ull. 31 | */ 32 | template 33 | FieldT power(const FieldT &base, const unsigned long long exponent); 34 | 35 | template 36 | FieldT power(const FieldT &base, const std::vector exponent); 37 | 38 | /** 39 | * Tonelli-Shanks square root with given s, t, and quadratic non-residue. 40 | * Only terminates if there is a square root. Only works if required parameters 41 | * are set in the field class. 42 | */ 43 | template 44 | FieldT tonelli_shanks_sqrt(const FieldT &value); 45 | 46 | } // namespace libff 47 | 48 | #include 49 | 50 | #endif // ALGORITHMS_HPP_ 51 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn128_gt.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #include 9 | 10 | namespace libff { 11 | 12 | bn128_GT bn128_GT::GT_one; 13 | bn128_GT::bn128_GT() 14 | { 15 | this->elem.clear(); 16 | } 17 | 18 | bool bn128_GT::operator==(const bn128_GT &other) const 19 | { 20 | return (this->elem == other.elem); 21 | } 22 | 23 | bool bn128_GT::operator!=(const bn128_GT& other) const 24 | { 25 | return !(operator==(other)); 26 | } 27 | 28 | bn128_GT bn128_GT::operator*(const bn128_GT &other) const 29 | { 30 | bn128_GT result; 31 | bn::Fp12::mul(result.elem, this->elem, other.elem); 32 | return result; 33 | } 34 | 35 | bn128_GT bn128_GT::unitary_inverse() const 36 | { 37 | bn128_GT result(*this); 38 | bn::Fp6::neg(result.elem.b_, result.elem.b_); 39 | return result; 40 | } 41 | 42 | bn128_GT bn128_GT::one() 43 | { 44 | return GT_one; 45 | } 46 | 47 | std::ostream& operator<<(std::ostream &out, const bn128_GT &g) 48 | { 49 | #ifndef BINARY_OUTPUT 50 | out << g.elem.a_ << OUTPUT_SEPARATOR << g.elem.b_; 51 | #else 52 | out.write((char*) &g.elem.a_, sizeof(g.elem.a_)); 53 | out.write((char*) &g.elem.b_, sizeof(g.elem.b_)); 54 | #endif 55 | return out; 56 | } 57 | 58 | std::istream& operator>>(std::istream &in, bn128_GT &g) 59 | { 60 | #ifndef BINARY_OUTPUT 61 | in >> g.elem.a_; 62 | consume_OUTPUT_SEPARATOR(in); 63 | in >> g.elem.b_; 64 | #else 65 | in.read((char*) &g.elem.a_, sizeof(g.elem.a_)); 66 | in.read((char*) &g.elem.b_, sizeof(g.elem.b_)); 67 | #endif 68 | return in; 69 | } 70 | } // namespace libff 71 | -------------------------------------------------------------------------------- /libff/algebra/curves/edwards/edwards_pp.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #include 9 | 10 | namespace libff { 11 | 12 | void edwards_pp::init_public_params() 13 | { 14 | init_edwards_params(); 15 | } 16 | 17 | edwards_GT edwards_pp::final_exponentiation(const edwards_Fq6 &elt) 18 | { 19 | return edwards_final_exponentiation(elt); 20 | } 21 | 22 | edwards_G1_precomp edwards_pp::precompute_G1(const edwards_G1 &P) 23 | { 24 | return edwards_precompute_G1(P); 25 | } 26 | 27 | edwards_G2_precomp edwards_pp::precompute_G2(const edwards_G2 &Q) 28 | { 29 | return edwards_precompute_G2(Q); 30 | } 31 | 32 | edwards_Fq6 edwards_pp::miller_loop(const edwards_G1_precomp &prec_P, 33 | const edwards_G2_precomp &prec_Q) 34 | { 35 | return edwards_miller_loop(prec_P, prec_Q); 36 | } 37 | 38 | edwards_Fq6 edwards_pp::double_miller_loop(const edwards_G1_precomp &prec_P1, 39 | const edwards_G2_precomp &prec_Q1, 40 | const edwards_G1_precomp &prec_P2, 41 | const edwards_G2_precomp &prec_Q2) 42 | { 43 | return edwards_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); 44 | } 45 | 46 | edwards_Fq6 edwards_pp::pairing(const edwards_G1 &P, 47 | const edwards_G2 &Q) 48 | { 49 | return edwards_pairing(P, Q); 50 | } 51 | 52 | edwards_Fq6 edwards_pp::reduced_pairing(const edwards_G1 &P, 53 | const edwards_G2 &Q) 54 | { 55 | return edwards_reduced_pairing(P, Q); 56 | } 57 | 58 | } // namespace libff 59 | -------------------------------------------------------------------------------- /libff/algebra/curves/alt_bn128/alt_bn128_pp.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #include 9 | 10 | namespace libff { 11 | 12 | void alt_bn128_pp::init_public_params() 13 | { 14 | init_alt_bn128_params(); 15 | } 16 | 17 | alt_bn128_GT alt_bn128_pp::final_exponentiation(const alt_bn128_Fq12 &elt) 18 | { 19 | return alt_bn128_final_exponentiation(elt); 20 | } 21 | 22 | alt_bn128_G1_precomp alt_bn128_pp::precompute_G1(const alt_bn128_G1 &P) 23 | { 24 | return alt_bn128_precompute_G1(P); 25 | } 26 | 27 | alt_bn128_G2_precomp alt_bn128_pp::precompute_G2(const alt_bn128_G2 &Q) 28 | { 29 | return alt_bn128_precompute_G2(Q); 30 | } 31 | 32 | alt_bn128_Fq12 alt_bn128_pp::miller_loop(const alt_bn128_G1_precomp &prec_P, 33 | const alt_bn128_G2_precomp &prec_Q) 34 | { 35 | return alt_bn128_miller_loop(prec_P, prec_Q); 36 | } 37 | 38 | alt_bn128_Fq12 alt_bn128_pp::double_miller_loop(const alt_bn128_G1_precomp &prec_P1, 39 | const alt_bn128_G2_precomp &prec_Q1, 40 | const alt_bn128_G1_precomp &prec_P2, 41 | const alt_bn128_G2_precomp &prec_Q2) 42 | { 43 | return alt_bn128_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); 44 | } 45 | 46 | alt_bn128_Fq12 alt_bn128_pp::pairing(const alt_bn128_G1 &P, 47 | const alt_bn128_G2 &Q) 48 | { 49 | return alt_bn128_pairing(P, Q); 50 | } 51 | 52 | alt_bn128_Fq12 alt_bn128_pp::reduced_pairing(const alt_bn128_G1 &P, 53 | const alt_bn128_G2 &Q) 54 | { 55 | return alt_bn128_reduced_pairing(P, Q); 56 | } 57 | 58 | } // namespace libff 59 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt6/mnt6_init.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of interfaces for initializing MNT6. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT6_INIT_HPP_ 13 | #define MNT6_INIT_HPP_ 14 | 15 | #include 16 | #include 17 | 18 | namespace libff { 19 | 20 | typedef Fp_model mnt6_Fr; 21 | typedef Fp_model mnt6_Fq; 22 | typedef Fp3_model mnt6_Fq3; 23 | typedef Fp6_2over3_model mnt6_Fq6; 24 | typedef mnt6_Fq6 mnt6_GT; 25 | 26 | // parameters for twisted short Weierstrass curve E'/Fq3 : y^2 = x^3 + (a * twist^2) * x + (b * twist^3) 27 | extern mnt6_Fq3 mnt6_twist; 28 | extern mnt6_Fq3 mnt6_twist_coeff_a; 29 | extern mnt6_Fq3 mnt6_twist_coeff_b; 30 | extern mnt6_Fq mnt6_twist_mul_by_a_c0; 31 | extern mnt6_Fq mnt6_twist_mul_by_a_c1; 32 | extern mnt6_Fq mnt6_twist_mul_by_a_c2; 33 | extern mnt6_Fq mnt6_twist_mul_by_b_c0; 34 | extern mnt6_Fq mnt6_twist_mul_by_b_c1; 35 | extern mnt6_Fq mnt6_twist_mul_by_b_c2; 36 | extern mnt6_Fq mnt6_twist_mul_by_q_X; 37 | extern mnt6_Fq mnt6_twist_mul_by_q_Y; 38 | 39 | // parameters for pairing 40 | extern bigint mnt6_ate_loop_count; 41 | extern bool mnt6_ate_is_loop_count_neg; 42 | extern bigint<6*mnt6_q_limbs> mnt6_final_exponent; 43 | extern bigint mnt6_final_exponent_last_chunk_abs_of_w0; 44 | extern bool mnt6_final_exponent_last_chunk_is_w0_neg; 45 | extern bigint mnt6_final_exponent_last_chunk_w1; 46 | 47 | void init_mnt6_params(); 48 | 49 | class mnt6_G1; 50 | class mnt6_G2; 51 | 52 | } // namespace libff 53 | 54 | #endif // MNT6_INIT_HPP_ 55 | -------------------------------------------------------------------------------- /libff/algebra/curves/bls12_381/bls12_381.sage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sage -python 2 | 3 | from sage.all import * 4 | import sys 5 | 6 | # Prime order of the subgroup we work in 7 | def r(x): 8 | return x**4 - x**2 + 1 9 | 10 | # Prime used to generate the base finite field 11 | def q(x): 12 | return (x-1)**2 * (x**4-x**2+1)//3 + x 13 | 14 | # Compute G1 cofactor 15 | def g1_h(x): 16 | return (x-1)**2//3 17 | 18 | # Compute G2 cofactor 19 | def g2_h(x): 20 | return (x**8-4*x**7+5*x**6-4*x**4+6*x**3-4*x**2-4*x+13)//9 21 | 22 | # Computes the order of G1, the safe subgroup of E/Fq 23 | def g1_order(curve_order): 24 | decomposition = factor(curve_order) 25 | # Factor returns the prime decomposition and orders prime 26 | # factors from smaller to biggest 27 | biggest_factor = decomposition[-1] 28 | assert(biggest_factor[1] == 1) 29 | return biggest_factor[0] 30 | 31 | def main(): 32 | print("Generating parameters for bls12_381") 33 | # Curve parameter 34 | param = -0xd201000000010000 35 | 36 | prime_r = r(param) 37 | assert(prime_r == 52435875175126190479447740508185965837690552500527637822603658699938581184513) 38 | 39 | prime_q = q(param) 40 | print prime_q 41 | assert(prime_q == 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787) 42 | if (mod(prime_q, 6) != 1): 43 | raise BaseException("Unexpected: q should be = 1 (mod 6).") 44 | 45 | # Scalar field 46 | print('prime_r = {}'.format(prime_r)) 47 | #params_generator.generate_libff_Fp_model_params(prime_r) 48 | Fr = GF(prime_r) 49 | 50 | # Base field 51 | print('prime_q = {}'.format(prime_q)) 52 | #params_generator.generate_libff_Fp_model_params(prime_q) 53 | Fq = GF(prime_q) 54 | 55 | # E/Fq 56 | curve = EllipticCurve(Fq, [0, 4]) 57 | curve_order = curve.order() 58 | 59 | # Cofactors 60 | _h1 = curve_order // g1_order(curve_order) 61 | h1 = g1_h(param) 62 | assert(_h1 == h1) 63 | print('h1 = {}'.format(h1)) 64 | h2 = g2_h(param) 65 | print('h2 = {}'.format(h2)) 66 | 67 | if __name__ == '__main__': 68 | main() 69 | -------------------------------------------------------------------------------- /libff/algebra/curves/alt_bn128/alt_bn128.sage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sage -python 2 | 3 | from sage.all import * 4 | import sys 5 | sys.path.append("../") 6 | import params_generator 7 | 8 | # Prime order of the subgroup we work in 9 | def r(x): 10 | return 36*(x**4) + 36*(x**3) + 18*(x**2) + 6*x + 1 11 | 12 | # Prime used to generate the base finite field 13 | def q(x): 14 | return 36*(x**4) + 36*(x**3) + 24*(x**2) + 6*x + 1 15 | 16 | # Compute G2 cofactor 17 | # See: Proposition 1, Section 3.3: https://eprint.iacr.org/2015/247.pdf 18 | def g2_h(x): 19 | return 36*x^4+ 36*x^3+ 30*x^2+ 6*x + 1 20 | 21 | # Computes the order of G1, the safe subgroup of E/Fq 22 | def g1_order(curve_order): 23 | decomposition = factor(curve_order) 24 | # Factor returns the prime decomposition and orders prime 25 | # factors from smaller to biggest 26 | biggest_factor = decomposition[-1] 27 | assert(biggest_factor[1] == 1) 28 | return biggest_factor[0] 29 | 30 | def main(): 31 | print("Generating parameters for alt_bn128") 32 | # Curve parameter 33 | param = 0x44e992b44a6909f1 34 | 35 | prime_r = r(param) 36 | assert(prime_r == 21888242871839275222246405745257275088548364400416034343698204186575808495617) 37 | 38 | prime_q = q(param) 39 | assert(prime_q == 21888242871839275222246405745257275088696311157297823662689037894645226208583) 40 | if (mod(prime_q, 6) != 1): 41 | raise BaseException("Unexpected: q should be = 1 (mod 6). See: https://eprint.iacr.org/2007/390.pdf") 42 | 43 | # Scalar field 44 | print('prime_r = {}'.format(prime_r)) 45 | #params_generator.generate_libff_Fp_model_params(prime_r) 46 | Fr = GF(prime_r) 47 | 48 | # Base field 49 | print('prime_q = {}'.format(prime_q)) 50 | #params_generator.generate_libff_Fp_model_params(prime_q) 51 | Fq = GF(prime_q) 52 | 53 | # E/Fq 54 | curve = EllipticCurve(Fq, [0, 3]) 55 | curve_order = curve.order() 56 | 57 | # Cofactors 58 | h1 = curve_order // g1_order(curve_order) 59 | # G1 cofactor should be 1 60 | assert(h1 == 1) 61 | print('h1 = {}'.format(h1)) 62 | h2 = g2_h(param) 63 | print('h2 = {}'.format(h2)) 64 | 65 | if __name__ == '__main__': 66 | main() 67 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn128_pp.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BN128_PP_HPP_ 9 | #define BN128_PP_HPP_ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace libff { 18 | 19 | class bn128_pp { 20 | public: 21 | typedef bn128_Fr Fp_type; 22 | typedef bn128_G1 G1_type; 23 | typedef bn128_G2 G2_type; 24 | typedef bn128_ate_G1_precomp G1_precomp_type; 25 | typedef bn128_ate_G2_precomp G2_precomp_type; 26 | typedef bn128_Fq Fq_type; 27 | typedef bn128_Fq12 Fqk_type; 28 | typedef bn128_GT GT_type; 29 | 30 | static const bool has_affine_pairing = false; 31 | 32 | static void init_public_params(); 33 | static bn128_GT final_exponentiation(const bn128_Fq12 &elt); 34 | static bn128_ate_G1_precomp precompute_G1(const bn128_G1 &P); 35 | static bn128_ate_G2_precomp precompute_G2(const bn128_G2 &Q); 36 | static bn128_Fq12 miller_loop(const bn128_ate_G1_precomp &prec_P, 37 | const bn128_ate_G2_precomp &prec_Q); 38 | static bn128_Fq12 double_miller_loop(const bn128_ate_G1_precomp &prec_P1, 39 | const bn128_ate_G2_precomp &prec_Q1, 40 | const bn128_ate_G1_precomp &prec_P2, 41 | const bn128_ate_G2_precomp &prec_Q2); 42 | 43 | /* the following are used in test files */ 44 | static bn128_GT pairing(const bn128_G1 &P, 45 | const bn128_G2 &Q); 46 | static bn128_GT reduced_pairing(const bn128_G1 &P, 47 | const bn128_G2 &Q); 48 | }; 49 | 50 | } // namespace libff 51 | #endif // BN128_PP_HPP_ 52 | -------------------------------------------------------------------------------- /libff/common/default_types/ec_pp.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | This file defines default_ec_pp based on the CURVE=... make flag, which selects 4 | which elliptic curve is used to implement group arithmetic and pairings. 5 | ***************************************************************************** 6 | * @author This file is part of libff, developed by SCIPR Lab 7 | * and contributors (see AUTHORS). 8 | * @copyright MIT license (see LICENSE file) 9 | *****************************************************************************/ 10 | #ifndef EC_PP_HPP_ 11 | #define EC_PP_HPP_ 12 | 13 | /************************ Pick the elliptic curve ****************************/ 14 | 15 | #ifdef CURVE_BLS12_381 16 | #define LIBFF_DEFAULT_EC_PP_DEFINED 17 | #include 18 | namespace libff { 19 | typedef bls12_381_pp default_ec_pp; 20 | } // namespace libff 21 | #endif 22 | 23 | #ifdef CURVE_ALT_BN128 24 | #define LIBFF_DEFAULT_EC_PP_DEFINED 25 | #include 26 | namespace libff { 27 | typedef alt_bn128_pp default_ec_pp; 28 | } // namespace libff 29 | #endif 30 | 31 | #ifdef CURVE_BN128 32 | #define LIBFF_DEFAULT_EC_PP_DEFINED 33 | #include 34 | namespace libff { 35 | typedef bn128_pp default_ec_pp; 36 | } // namespace libff 37 | #endif 38 | 39 | #ifdef CURVE_EDWARDS 40 | #define LIBFF_DEFAULT_EC_PP_DEFINED 41 | #include 42 | namespace libff { 43 | typedef edwards_pp default_ec_pp; 44 | } // namespace libff 45 | #endif 46 | 47 | #ifdef CURVE_MNT4 48 | #define LIBFF_DEFAULT_EC_PP_DEFINED 49 | #include 50 | namespace libff { 51 | typedef mnt4_pp default_ec_pp; 52 | } // namespace libff 53 | #endif 54 | 55 | #ifdef CURVE_MNT6 56 | #define LIBFF_DEFAULT_EC_PP_DEFINED 57 | #include 58 | namespace libff { 59 | typedef mnt6_pp default_ec_pp; 60 | } // namespace libff 61 | #endif 62 | 63 | #ifndef LIBFF_DEFAULT_EC_PP_DEFINED 64 | #error You must define one of the CURVE_* symbols to pick a curve for pairings. 65 | #endif 66 | 67 | #endif // EC_PP_HPP_ 68 | -------------------------------------------------------------------------------- /libff/algebra/curves/edwards/edwards_pp.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef EDWARDS_PP_HPP_ 9 | #define EDWARDS_PP_HPP_ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace libff { 17 | 18 | class edwards_pp { 19 | public: 20 | typedef edwards_Fr Fp_type; 21 | typedef edwards_G1 G1_type; 22 | typedef edwards_G2 G2_type; 23 | typedef edwards_G1_precomp G1_precomp_type; 24 | typedef edwards_G2_precomp G2_precomp_type; 25 | typedef edwards_Fq Fq_type; 26 | typedef edwards_Fq3 Fqe_type; 27 | typedef edwards_Fq6 Fqk_type; 28 | typedef edwards_GT GT_type; 29 | 30 | static const bool has_affine_pairing = false; 31 | 32 | static void init_public_params(); 33 | static edwards_GT final_exponentiation(const edwards_Fq6 &elt); 34 | static edwards_G1_precomp precompute_G1(const edwards_G1 &P); 35 | static edwards_G2_precomp precompute_G2(const edwards_G2 &Q); 36 | static edwards_Fq6 miller_loop(const edwards_G1_precomp &prec_P, 37 | const edwards_G2_precomp &prec_Q); 38 | static edwards_Fq6 double_miller_loop(const edwards_G1_precomp &prec_P1, 39 | const edwards_G2_precomp &prec_Q1, 40 | const edwards_G1_precomp &prec_P2, 41 | const edwards_G2_precomp &prec_Q2); 42 | /* the following are used in test files */ 43 | static edwards_Fq6 pairing(const edwards_G1 &P, 44 | const edwards_G2 &Q); 45 | static edwards_Fq6 reduced_pairing(const edwards_G1 &P, 46 | const edwards_G2 &Q); 47 | }; 48 | 49 | } // namespace libff 50 | #endif // EDWARDS_PP_HPP_ 51 | -------------------------------------------------------------------------------- /libff/common/double.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of complex domain data type. 4 | ***************************************************************************** 5 | * @author This file is part of libff, developed by SCIPR Lab 6 | * and contributors (see AUTHORS). 7 | * @copyright MIT license (see LICENSE file) 8 | *****************************************************************************/ 9 | #ifndef DOUBLE_HPP_ 10 | #define DOUBLE_HPP_ 11 | 12 | #include 13 | 14 | #include 15 | 16 | namespace libff { 17 | 18 | const double PI = 3.141592653589793238460264338328L; 19 | 20 | class Double 21 | { 22 | public: 23 | std::complex val; 24 | 25 | Double(); 26 | 27 | Double(double real); 28 | 29 | Double(double real, double imag); 30 | 31 | Double(std::complex num); 32 | 33 | static unsigned add_cnt; 34 | static unsigned sub_cnt; 35 | static unsigned mul_cnt; 36 | static unsigned inv_cnt; 37 | 38 | Double operator+(const Double &other) const; 39 | Double operator-(const Double &other) const; 40 | Double operator*(const Double &other) const; 41 | Double operator-() const; 42 | 43 | Double& operator+=(const Double &other); 44 | Double& operator-=(const Double &other); 45 | Double& operator*=(const Double &other); 46 | 47 | bool operator==(const Double &other) const; 48 | bool operator!=(const Double &other) const; 49 | 50 | bool operator<(const Double &other) const; 51 | bool operator>(const Double &other) const; 52 | 53 | Double operator^(const libff::bigint<1> power) const; 54 | Double operator^(const std::size_t power) const; 55 | 56 | libff::bigint<1> as_bigint() const; 57 | unsigned long as_ulong() const; 58 | Double inverse() const; 59 | Double squared() const; 60 | 61 | static Double one(); 62 | static Double zero(); 63 | static Double random_element(); 64 | static Double geometric_generator(); 65 | static Double arithmetic_generator(); 66 | 67 | static Double multiplicative_generator; 68 | static Double root_of_unity; // See get_root_of_unity() in field_utils 69 | static std::size_t s; 70 | }; 71 | 72 | } // namespace libff 73 | 74 | #endif // DOUBLE_HPP_ 75 | -------------------------------------------------------------------------------- /libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef ALT_BN128_PP_HPP_ 9 | #define ALT_BN128_PP_HPP_ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace libff { 17 | 18 | class alt_bn128_pp { 19 | public: 20 | typedef alt_bn128_Fr Fp_type; 21 | typedef alt_bn128_G1 G1_type; 22 | typedef alt_bn128_G2 G2_type; 23 | typedef alt_bn128_G1_precomp G1_precomp_type; 24 | typedef alt_bn128_G2_precomp G2_precomp_type; 25 | typedef alt_bn128_Fq Fq_type; 26 | typedef alt_bn128_Fq2 Fqe_type; 27 | typedef alt_bn128_Fq12 Fqk_type; 28 | typedef alt_bn128_GT GT_type; 29 | 30 | static const bool has_affine_pairing = false; 31 | 32 | static void init_public_params(); 33 | static alt_bn128_GT final_exponentiation(const alt_bn128_Fq12 &elt); 34 | static alt_bn128_G1_precomp precompute_G1(const alt_bn128_G1 &P); 35 | static alt_bn128_G2_precomp precompute_G2(const alt_bn128_G2 &Q); 36 | static alt_bn128_Fq12 miller_loop(const alt_bn128_G1_precomp &prec_P, 37 | const alt_bn128_G2_precomp &prec_Q); 38 | static alt_bn128_Fq12 double_miller_loop(const alt_bn128_G1_precomp &prec_P1, 39 | const alt_bn128_G2_precomp &prec_Q1, 40 | const alt_bn128_G1_precomp &prec_P2, 41 | const alt_bn128_G2_precomp &prec_Q2); 42 | static alt_bn128_Fq12 pairing(const alt_bn128_G1 &P, 43 | const alt_bn128_G2 &Q); 44 | static alt_bn128_Fq12 reduced_pairing(const alt_bn128_G1 &P, 45 | const alt_bn128_G2 &Q); 46 | }; 47 | 48 | } // namespace libff 49 | 50 | #endif // ALT_BN128_PP_HPP_ 51 | -------------------------------------------------------------------------------- /libff/algebra/curves/bls12_381/bls12_381_pp.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BLS12_381_PP_HPP_ 9 | #define BLS12_381_PP_HPP_ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace libff { 17 | 18 | class bls12_381_pp { 19 | public: 20 | typedef bls12_381_Fr Fp_type; 21 | typedef bls12_381_G1 G1_type; 22 | typedef bls12_381_G2 G2_type; 23 | typedef bls12_381_G1_precomp G1_precomp_type; 24 | typedef bls12_381_G2_precomp G2_precomp_type; 25 | typedef bls12_381_Fq Fq_type; 26 | typedef bls12_381_Fq2 Fqe_type; 27 | typedef bls12_381_Fq12 Fqk_type; 28 | typedef bls12_381_GT GT_type; 29 | 30 | static const bool has_affine_pairing = false; 31 | 32 | static void init_public_params(); 33 | static bls12_381_GT final_exponentiation(const bls12_381_Fq12 &elt); 34 | static bls12_381_G1_precomp precompute_G1(const bls12_381_G1 &P); 35 | static bls12_381_G2_precomp precompute_G2(const bls12_381_G2 &Q); 36 | static bls12_381_Fq12 miller_loop(const bls12_381_G1_precomp &prec_P, 37 | const bls12_381_G2_precomp &prec_Q); 38 | static bls12_381_Fq12 double_miller_loop(const bls12_381_G1_precomp &prec_P1, 39 | const bls12_381_G2_precomp &prec_Q1, 40 | const bls12_381_G1_precomp &prec_P2, 41 | const bls12_381_G2_precomp &prec_Q2); 42 | static bls12_381_Fq12 pairing(const bls12_381_G1 &P, 43 | const bls12_381_G2 &Q); 44 | static bls12_381_Fq12 reduced_pairing(const bls12_381_G1 &P, 45 | const bls12_381_G2 &Q); 46 | }; 47 | 48 | } // namespace libff 49 | 50 | #endif // BLS12_381_PP_HPP_ 51 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn128_pairing.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ******************************************************************************** 3 | Declares functions for computing Ate pairings over the bn128 curves, split into a 4 | offline and online stages. 5 | ******************************************************************************** 6 | * @author This file is part of libff, developed by SCIPR Lab 7 | * and contributors (see AUTHORS). 8 | * @copyright MIT license (see LICENSE file) 9 | *******************************************************************************/ 10 | 11 | #ifndef BN128_PAIRING_HPP_ 12 | #define BN128_PAIRING_HPP_ 13 | #include "depends/ate-pairing/include/bn.h" 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | namespace libff { 20 | 21 | struct bn128_ate_G1_precomp { 22 | bn::Fp P[3]; 23 | 24 | bool operator==(const bn128_ate_G1_precomp &other) const; 25 | friend std::ostream& operator<<(std::ostream &out, const bn128_ate_G1_precomp &prec_P); 26 | friend std::istream& operator>>(std::istream &in, bn128_ate_G1_precomp &prec_P); 27 | }; 28 | 29 | typedef bn::Fp6 bn128_ate_ell_coeffs; 30 | 31 | struct bn128_ate_G2_precomp { 32 | bn::Fp2 Q[3]; 33 | std::vector coeffs; 34 | 35 | bool operator==(const bn128_ate_G2_precomp &other) const; 36 | friend std::ostream& operator<<(std::ostream &out, const bn128_ate_G2_precomp &prec_Q); 37 | friend std::istream& operator>>(std::istream &in, bn128_ate_G2_precomp &prec_Q); 38 | }; 39 | 40 | bn128_ate_G1_precomp bn128_ate_precompute_G1(const bn128_G1& P); 41 | bn128_ate_G2_precomp bn128_ate_precompute_G2(const bn128_G2& Q); 42 | 43 | bn128_Fq12 bn128_double_ate_miller_loop(const bn128_ate_G1_precomp &prec_P1, 44 | const bn128_ate_G2_precomp &prec_Q1, 45 | const bn128_ate_G1_precomp &prec_P2, 46 | const bn128_ate_G2_precomp &prec_Q2); 47 | bn128_Fq12 bn128_ate_miller_loop(const bn128_ate_G1_precomp &prec_P, 48 | const bn128_ate_G2_precomp &prec_Q); 49 | 50 | bn128_GT bn128_final_exponentiation(const bn128_Fq12 &elt); 51 | 52 | } // namespace libff 53 | #endif // BN128_PAIRING_HPP_ 54 | -------------------------------------------------------------------------------- /libff/algebra/curves/params_generator.sage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sage -python 2 | 3 | from sage.all import * 4 | 5 | def generate_libff_Fp_model_params(prime): 6 | num_bits = ceil(log(prime, 2)) 7 | print('num_bits = {}'.format(num_bits)) 8 | 9 | euler = (prime-1)/2 10 | print('euler = {}'.format(euler)) 11 | 12 | factorization = factor(prime-1) 13 | t = 0 14 | term_2 = factorization[0] 15 | counter = 0 16 | if term_2[0] != 2: 17 | raise BaseException("The prime decomposition doesn't have any factor 2." 18 | "The 'high 2-adicity' requirement isn't respected") 19 | while not(is_odd(t)): 20 | s = term_2[1] - counter 21 | t = (prime-1)/(2**s) 22 | counter = counter + 1 23 | print('s = {}'.format(s)) 24 | is_odd(t); print('t = {}'.format(t)) 25 | 26 | t_minus_1_over_2 = (t-1)/2 27 | print('t_minus_1_over_2 = {}'.format(t_minus_1_over_2)) 28 | 29 | multiplicative_generator = primitive_root(prime) 30 | print('multiplicative_generator = {}'.format(multiplicative_generator)) 31 | 32 | root_of_unity = pow(multiplicative_generator, t, prime) 33 | print('root_of_unity = {}'.format(root_of_unity)) 34 | 35 | nqr = least_quadratic_nonresidue(prime) 36 | print('nqr = {}'.format(nqr)) 37 | 38 | nqr_to_t = pow(nqr, t, prime) 39 | print('nqr_to_t = {}'.format(nqr_to_t)) 40 | 41 | word_len_64_bits = 64 42 | W_64_bits = 2**(word_len_64_bits) 43 | k_64_bits = ceil(num_bits/word_len_64_bits) 44 | print('k_64_bits (nb limbs) = {}'.format(k_64_bits)) 45 | R_64_bits = mod(W_64_bits**k_64_bits, prime); R_64_bits 46 | Rsquared_64_bits = R_64_bits**2 47 | print('Rsquared_64_bits = {}'.format(Rsquared_64_bits)) 48 | Rcubed_64_bits = R_64_bits**3 49 | print('Rcubed_64_bits = {}'.format(Rcubed_64_bits)) 50 | inv_64_bits = hex(int(mod((1/-prime), W_64_bits))) 51 | print('inv_64_bits = {}'.format(inv_64_bits)) 52 | 53 | word_len_32_bits = 32 54 | W_32_bits = 2**(32) 55 | k_32_bits = ceil(num_bits/word_len_32_bits) 56 | print('k_32_bits (nb limbs) = {}'.format(k_32_bits)) 57 | R_32_bits = mod(W_32_bits**k_32_bits, prime); R_32_bits 58 | Rsquared_32_bits = R_32_bits**2 59 | print('Rsquared_32_bits = {}'.format(Rsquared_32_bits)) 60 | Rcubed_32_bits = R_32_bits**3 61 | print('Rcubed_32_bits = {}'.format(Rcubed_32_bits)) 62 | inv_32_bits = hex(int(mod(1/-prime, W_32_bits))) 63 | print('inv_32_bits = {}'.format(inv_32_bits)) -------------------------------------------------------------------------------- /libff/common/rng.tcc: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Implementation of functions for generating randomness. 4 | 5 | See rng.hpp . 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | #ifndef RNG_TCC_ 12 | #define RNG_TCC_ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace libff { 22 | 23 | using std::size_t; 24 | 25 | template 26 | FieldT SHA512_rng(const uint64_t idx) 27 | { 28 | assert(GMP_NUMB_BITS == 64); // current Python code cannot handle larger values, so testing here for some assumptions. 29 | assert(is_little_endian()); 30 | 31 | assert(FieldT::ceil_size_in_bits() <= SHA512_DIGEST_LENGTH * 8); 32 | 33 | bigint rval; 34 | uint64_t iter = 0; 35 | do 36 | { 37 | mp_limb_t hash[((SHA512_DIGEST_LENGTH*8) + GMP_NUMB_BITS - 1)/GMP_NUMB_BITS]; 38 | 39 | SHA512_CTX sha512; 40 | SHA512_Init(&sha512); 41 | SHA512_Update(&sha512, &idx, sizeof(idx)); 42 | SHA512_Update(&sha512, &iter, sizeof(iter)); 43 | SHA512_Final((unsigned char*)hash, &sha512); 44 | 45 | for (mp_size_t i = 0; i < FieldT::num_limbs; ++i) 46 | { 47 | rval.data[i] = hash[i]; 48 | } 49 | 50 | /* clear all bits higher than MSB of modulus */ 51 | size_t bitno = GMP_NUMB_BITS * FieldT::num_limbs - 1; 52 | 53 | /* mod is non-zero so the loop will always terminate */ 54 | while (FieldT::mod.test_bit(bitno) == false) 55 | { 56 | const std::size_t part = bitno/GMP_NUMB_BITS; 57 | const std::size_t bit = bitno - (GMP_NUMB_BITS*part); 58 | 59 | static const mp_limb_t one = 1; 60 | rval.data[part] &= ~(one<= modulus -- repeat (rejection sampling) */ 69 | while (mpn_cmp(rval.data, FieldT::mod.data, FieldT::num_limbs) >= 0); 70 | 71 | return FieldT(rval); 72 | } 73 | 74 | } // namespace libff 75 | 76 | #endif // RNG_TCC_ 77 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/README.md: -------------------------------------------------------------------------------- 1 | # Fields 2 | 3 | This folder contains implementations of various binary fields, 4 | and some helper methods to distinguish these binary fields from the supported smooth prime fields from libff. 5 | (These are distinguished as either "additive" or "multiplicative" field types from the utils file) 6 | 7 | For the binary fields, the irreducible polynomial of order `d` chosen is the lexicographically smallest 8 | such polynomial of the given degree. 9 | The field implementations provided in this library will utilize Intel intrinsics 10 | if available, and otherwise will fall back to a pure C++ implementation.[1] 11 | The implementation of field arithmetic will work for any irreducible polynomial 12 | such that there is no term with degree greater than `d / 2` other than `x^d`. 13 | The reason for this constraint is described in the multiplication section. 14 | 15 | [1]: More precisely, it depends on if the 128 bit carryless instruction is supported. This has the corresponding CPUID flag: `PCLMULQDQ`. 16 | 17 | ## Encoding 18 | 19 | An element of a binary field can be represented as `d` bits, 20 | where the `i`th bit counting from the right is `x^i`. 21 | We encode these bits in fixed size arrays of int64s. 22 | The size of the int64 array is `d / 64`. 23 | 24 | ## Addition / Subtraction 25 | 26 | Addition over any field extension is carry-less addition. 27 | In a binary field, this is equivalent to a XOR operation. 28 | Similarly, in a binary field subtraction is equivalent to a XOR as well. 29 | 30 | ## Multiplication 31 | 32 | Multiplication over a binary field is [carry-less multiplication](https://en.wikipedia.org/wiki/Carry-less_product), 33 | with modular reduction. 34 | 35 | When taking advantage of Intrinsics, the relevant operation provided is `_mm_clmulepi64_si128`. 36 | This allows carry-less multiplication of two 64 bit numbers into a 128 bit number. 37 | Because there is no term in the irreducible polynomial with degree greater 38 | than `d / 2` other than `x^d`, the number of operations needed for 39 | modular reduction can be reduced. (See section 5.2 of [MS17]) 40 | 41 | This same multiplication implementation is used for squaring. 42 | 43 | ## Inversion 44 | 45 | Field inversion is implemented as `x^{-1} = x^{2^d -2}`, using an addition chains for this exponentiation. 46 | These addition chains were found using the Bergeron-Berstel-Brlek-Duboc method implemented in 47 | https://github.com/kwantam/addchain. 48 | 49 | ## References 50 | 51 | [MS17] [On Fast Multiplication in Binary Finite Fields and Optimal Primitive Polynomials over GF(2)](https://eprint.iacr.org/2017/889), Alexander Maximov and Helena Sjoberg, 2017. -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn128_pp.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #include 9 | #include 10 | 11 | namespace libff { 12 | 13 | void bn128_pp::init_public_params() 14 | { 15 | init_bn128_params(); 16 | } 17 | 18 | bn128_GT bn128_pp::final_exponentiation(const bn128_GT &elt) 19 | { 20 | return bn128_final_exponentiation(elt); 21 | } 22 | 23 | bn128_ate_G1_precomp bn128_pp::precompute_G1(const bn128_G1 &P) 24 | { 25 | return bn128_ate_precompute_G1(P); 26 | } 27 | 28 | bn128_ate_G2_precomp bn128_pp::precompute_G2(const bn128_G2 &Q) 29 | { 30 | return bn128_ate_precompute_G2(Q); 31 | } 32 | 33 | bn128_Fq12 bn128_pp::miller_loop(const bn128_ate_G1_precomp &prec_P, 34 | const bn128_ate_G2_precomp &prec_Q) 35 | { 36 | enter_block("Call to miller_loop"); 37 | bn128_Fq12 result = bn128_ate_miller_loop(prec_P, prec_Q); 38 | leave_block("Call to miller_loop"); 39 | return result; 40 | } 41 | 42 | bn128_Fq12 bn128_pp::double_miller_loop(const bn128_ate_G1_precomp &prec_P1, 43 | const bn128_ate_G2_precomp &prec_Q1, 44 | const bn128_ate_G1_precomp &prec_P2, 45 | const bn128_ate_G2_precomp &prec_Q2) 46 | { 47 | enter_block("Call to double_miller_loop"); 48 | bn128_Fq12 result = bn128_double_ate_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); 49 | leave_block("Call to double_miller_loop"); 50 | return result; 51 | } 52 | 53 | bn128_Fq12 bn128_pp::pairing(const bn128_G1 &P, 54 | const bn128_G2 &Q) 55 | { 56 | enter_block("Call to pairing"); 57 | bn128_ate_G1_precomp prec_P = bn128_pp::precompute_G1(P); 58 | bn128_ate_G2_precomp prec_Q = bn128_pp::precompute_G2(Q); 59 | 60 | bn128_Fq12 result = bn128_pp::miller_loop(prec_P, prec_Q); 61 | leave_block("Call to pairing"); 62 | return result; 63 | } 64 | 65 | bn128_GT bn128_pp::reduced_pairing(const bn128_G1 &P, 66 | const bn128_G2 &Q) 67 | { 68 | enter_block("Call to reduced_pairing"); 69 | const bn128_Fq12 f = bn128_pp::pairing(P, Q); 70 | const bn128_GT result = bn128_pp::final_exponentiation(f); 71 | leave_block("Call to reduced_pairing"); 72 | return result; 73 | } 74 | 75 | } // namespace libff 76 | -------------------------------------------------------------------------------- /libff/algebra/field_utils/bigint.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of bigint wrapper class around GMP's MPZ long integers. 4 | 5 | Notice that this class has no arithmetic operators. This is deliberate. All 6 | bigints should either be hardcoded or operated on the bit level to ensure 7 | high performance. 8 | ***************************************************************************** 9 | * @author This file is part of libff, developed by SCIPR Lab 10 | * and contributors (see AUTHORS). 11 | * @copyright MIT license (see LICENSE file) 12 | *****************************************************************************/ 13 | 14 | #ifndef BIGINT_HPP_ 15 | #define BIGINT_HPP_ 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | #include 22 | 23 | namespace libff { 24 | 25 | template class bigint; 26 | template std::ostream& operator<<(std::ostream &, const bigint&); 27 | template std::istream& operator>>(std::istream &, bigint&); 28 | 29 | /** 30 | * Wrapper class around GMP's MPZ long integers. It supports arithmetic operations, 31 | * serialization and randomization. Serialization is fragile, see common/serialization.hpp. 32 | */ 33 | 34 | template 35 | class bigint { 36 | public: 37 | static const mp_size_t N = n; 38 | 39 | mp_limb_t data[n] = {0}; 40 | 41 | bigint() = default; 42 | bigint(const unsigned long x); /// Initalize from a small integer 43 | bigint(const char* s); /// Initialize from a string containing an integer in decimal notation 44 | bigint(const mpz_t r); /// Initialize from MPZ element 45 | 46 | static bigint one(); 47 | 48 | void print() const; 49 | void print_hex() const; 50 | bool operator==(const bigint& other) const; 51 | bool operator!=(const bigint& other) const; 52 | bool operator<(const bigint& other) const; 53 | void clear(); 54 | bool is_zero() const; 55 | bool is_even() const; 56 | std::size_t max_bits() const { return n * GMP_NUMB_BITS; } /// Returns the number of bits representable by this bigint type 57 | std::size_t num_bits() const; /// Returns the number of bits in this specific bigint value, i.e., position of the most-significant 1 58 | 59 | unsigned long as_ulong() const; /// Return the last limb of the integer 60 | void to_mpz(mpz_t r) const; 61 | bool test_bit(const std::size_t bitno) const; 62 | 63 | bigint& randomize(); 64 | 65 | friend std::ostream& operator<< (std::ostream &out, const bigint &b); 66 | friend std::istream& operator>> (std::istream &in, bigint &b); 67 | }; 68 | 69 | } // namespace libff 70 | #include 71 | #endif 72 | -------------------------------------------------------------------------------- /libff/common/tests/test_common.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | ***************************************************************************** 3 | Some tests for the functions in this directory. 4 | ***************************************************************************** 5 | * @author This file is part of libff, developed by SCIPR Lab 6 | * and contributors (see AUTHORS). 7 | * @copyright MIT license (see LICENSE file) 8 | *****************************************************************************/ 9 | 10 | #include 11 | #include 12 | 13 | #include "libff/common/utils.hpp" 14 | #include "libff/algebra/fields/binary/gf32.hpp" 15 | #include "libff/algebra/curves/edwards/edwards_pp.hpp" 16 | #include "libff/algebra/curves/mnt/mnt6/mnt6_pp.hpp" 17 | 18 | using namespace libff; 19 | 20 | TEST(Log2Test, SimpleTest) { 21 | // There seems to be a second log2 function that operates on floats so we added libff::. 22 | EXPECT_EQ(libff::log2(0), 0ULL); 23 | EXPECT_EQ(libff::log2(1), 0ULL); 24 | EXPECT_EQ(libff::log2(2), 1ULL); 25 | EXPECT_EQ(libff::log2(3), 2ULL); 26 | EXPECT_EQ(libff::log2(4), 2ULL); 27 | EXPECT_EQ(libff::log2(5), 3ULL); 28 | EXPECT_EQ(libff::log2(6), 3ULL); 29 | EXPECT_EQ(libff::log2(7), 3ULL); 30 | EXPECT_EQ(libff::log2(8), 3ULL); 31 | EXPECT_EQ(libff::log2(9), 4ULL); 32 | } 33 | 34 | TEST(Log2Test, PowersOfTwo) { 35 | for (std::size_t i = 10; i < 20; ++i) 36 | { 37 | const std::size_t k = (1ULL< 45 | void test_random_element() 46 | { 47 | FieldT x = random_element_non_zero_one(); 48 | EXPECT_NE(x, FieldT::zero()); 49 | EXPECT_NE(x, FieldT::one()); 50 | 51 | x = random_element_non_zero(); 52 | EXPECT_NE(x, FieldT::zero()); 53 | 54 | FieldT y = random_element_exclude(x); 55 | EXPECT_NE(x, y); 56 | } 57 | 58 | TEST(UtilsTest, RandomElementTest) 59 | { 60 | init_edwards_fields(); 61 | test_random_element(); 62 | test_random_element(); 63 | } 64 | 65 | TEST(UtilsTest, CurveVectorSizeTest) 66 | { 67 | init_edwards_params(); 68 | init_mnt6_params(); 69 | 70 | std::vector vec; 71 | 72 | vec.push_back(edwards_G1::G1_one); 73 | vec.push_back(edwards_G1::G1_zero); 74 | vec.push_back(edwards_G1::G1_one); 75 | 76 | EXPECT_EQ(curve_size_in_bits(vec), 552); 77 | 78 | std::vector vec2; 79 | 80 | vec2.push_back(mnt6_G2::G2_zero); 81 | vec2.push_back(mnt6_G2::G2_one); 82 | vec2.push_back(mnt6_G2::G2_one); 83 | vec2.push_back(mnt6_G2::G2_zero); 84 | vec2.push_back(mnt6_G2::G2_zero); 85 | 86 | EXPECT_EQ(curve_size_in_bits(vec2), 4475); 87 | } 88 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v0.3.0 2 | 3 | This update introduces new field and curve API's, and enforces they are used consistently across the library. Furthermore it makes it possible to use fields, without having to initialize elliptic curves. 4 | 5 | ### Breaking Changes 6 | - #23 Remove unused exponent param of curves 7 | - #58 Add a defined API for every field type, and have minor tweaks to all fields to implement it (Thanks @alexander-zw) 8 | - #79 Separate field initialization from curves (Thanks @alexander-zw) 9 | ### Features 10 | - #71 Add BLS12-381 (Thanks @yelhousni) 11 | - #80 Add clang-tidy checks to library and CI 12 | - #82 Convert tests to use Google test (Thanks @alexander-zw) 13 | - #83 Make run-clang-tidy return an error when linting fails 14 | - #85 Add more unit tests for fields (Thanks @alexander-zw) 15 | - #86 Add binary fields from [libiop](https://github.com/scipr-lab/libiop) 16 | - #100 Move utils in from [libiop](https://github.com/scipr-lab/libiop) 17 | 18 | ### Bug fixes 19 | - #75 Get rid of warning for unused constant PI, in complex field 20 | - #78 Reduce prints when inhibit_profiling_info is set 21 | - #79 & #87 Use std::size_t for all code, fix bugs introduced by #58 22 | - #94 & #96 Fix bugs that make libff incompatible with 23 | [libfqfft](https://github.com/scipr-lab/libfqfft) and [libiop](https://github.com/scipr-lab/libiop) 24 | - #103 Fix bugs that make libff incompatible with [libsnark](https://github.com/scipr-lab/libsnark) 25 | and add more tests for the field utils 26 | 27 | ## v0.2.0 28 | 29 | _Special thanks to all downstream projects upstreaming their patches!_ 30 | 31 | ### Breaking Changes 32 | - File structure changed: All field utils are now in `libff/algebra/field_utils/`, `Fp_model` is 33 | now in `libff/algebra/fields/prime_base/`, and all other F_p^n fields in 34 | `libff/algebra/fields/prime_extension/`. 35 | - The function `base_field_char()` of all fields and curves have been renamed to `field_char()`. 36 | - The provided fields used in curves have been moved to separate files so that they can be imported 37 | separately from `[field name]_fields.hpp`. However they are still accessible from the init file. 38 | 39 | ### Features 40 | - #20 Improve operator+ speed for alt_bn, correct the corresponding docs, and reduce code duplication. 41 | - #50 Add mul_by_cofactor to elliptic curve groups 42 | - #50 Add sage scripts for altbn and mnt curves, to verify cofactors and generators 43 | - #52 Change default procps build flags to work with Mac OS 44 | 45 | ### Bug fixes 46 | - #19 Fix is_little_endian always returning true 47 | - #20 Fix operator+ not contributing to alt_bn_128 profiling opcount 48 | - #26 Remove unused warnings in release build 49 | - #39 Update Travis Config for newer Ubuntu mirror defaults 50 | - #50 Fix incorrect mnt4 g2 generator 51 | - #54 Fix is_power_of_two for n > 2^32 52 | - #55 Throw informative error for division by zero in div_ceil 53 | -------------------------------------------------------------------------------- /libff/algebra/curves/edwards/edwards_g1.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef EDWARDS_G1_HPP_ 9 | #define EDWARDS_G1_HPP_ 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace libff { 16 | 17 | class edwards_G1; 18 | std::ostream& operator<<(std::ostream &, const edwards_G1&); 19 | std::istream& operator>>(std::istream &, edwards_G1&); 20 | 21 | class edwards_G1 { 22 | public: 23 | #ifdef PROFILE_OP_COUNTS 24 | static long long add_cnt; 25 | static long long dbl_cnt; 26 | #endif 27 | static std::vector wnaf_window_table; 28 | static std::vector fixed_base_exp_window_table; 29 | static edwards_G1 G1_zero; 30 | static edwards_G1 G1_one; 31 | static bool initialized; 32 | 33 | edwards_Fq X, Y, Z; 34 | edwards_G1(); 35 | private: 36 | edwards_G1(const edwards_Fq& X, const edwards_Fq& Y, const edwards_Fq& Z) : X(X), Y(Y), Z(Z) {}; 37 | 38 | public: 39 | typedef edwards_Fq base_field; 40 | typedef edwards_Fr scalar_field; 41 | // using inverted coordinates 42 | edwards_G1(const edwards_Fq& X, const edwards_Fq& Y) : X(Y), Y(X), Z(X*Y) {}; 43 | 44 | void print() const; 45 | void print_coordinates() const; 46 | 47 | void to_affine_coordinates(); 48 | void to_special(); 49 | bool is_special() const; 50 | 51 | bool is_zero() const; 52 | 53 | bool operator==(const edwards_G1 &other) const; 54 | bool operator!=(const edwards_G1 &other) const; 55 | 56 | edwards_G1 operator+(const edwards_G1 &other) const; 57 | edwards_G1 operator-() const; 58 | edwards_G1 operator-(const edwards_G1 &other) const; 59 | 60 | edwards_G1 add(const edwards_G1 &other) const; 61 | edwards_G1 mixed_add(const edwards_G1 &other) const; 62 | edwards_G1 dbl() const; 63 | 64 | bool is_well_formed() const; 65 | 66 | static edwards_G1 zero(); 67 | static edwards_G1 one(); 68 | static edwards_G1 random_element(); 69 | 70 | static std::size_t size_in_bits() { return edwards_Fq::ceil_size_in_bits() + 1; } 71 | static bigint field_char() { return base_field::field_char(); } 72 | static bigint order() { return scalar_field::field_char(); } 73 | 74 | friend std::ostream& operator<<(std::ostream &out, const edwards_G1 &g); 75 | friend std::istream& operator>>(std::istream &in, edwards_G1 &g); 76 | 77 | static void batch_to_special_all_non_zeros(std::vector &vec); 78 | }; 79 | 80 | template 81 | edwards_G1 operator*(const bigint &lhs, const edwards_G1 &rhs) 82 | { 83 | return scalar_mul(rhs, lhs); 84 | } 85 | 86 | template& modulus_p> 87 | edwards_G1 operator*(const Fp_model &lhs, const edwards_G1 &rhs) 88 | { 89 | return scalar_mul(rhs, lhs.as_bigint()); 90 | } 91 | 92 | std::ostream& operator<<(std::ostream& out, const std::vector &v); 93 | std::istream& operator>>(std::istream& in, std::vector &v); 94 | 95 | } // namespace libff 96 | #endif // EDWARDS_G1_HPP_ 97 | -------------------------------------------------------------------------------- /libff/algebra/scalar_multiplication/wnaf.tcc: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Implementation of interfaces for wNAF ("weighted Non-Adjacent Form") exponentiation routines. 4 | 5 | See wnaf.hpp . 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | #ifndef WNAF_TCC_ 12 | #define WNAF_TCC_ 13 | 14 | #include 15 | 16 | namespace libff { 17 | 18 | using std::size_t; 19 | 20 | template 21 | std::vector find_wnaf(const size_t window_size, const bigint &scalar) 22 | { 23 | const size_t length = scalar.max_bits(); // upper bound 24 | std::vector res(length+1); 25 | bigint c = scalar; 26 | long j = 0; 27 | while (!c.is_zero()) 28 | { 29 | long u; 30 | if ((c.data[0] & 1) == 1) 31 | { 32 | u = c.data[0] % (1u << (window_size+1)); 33 | if (u > (1 << window_size)) 34 | { 35 | u = u - (1 << (window_size+1)); 36 | } 37 | 38 | if (u > 0) 39 | { 40 | mpn_sub_1(c.data, c.data, n, u); 41 | } 42 | else 43 | { 44 | mpn_add_1(c.data, c.data, n, -u); 45 | } 46 | } 47 | else 48 | { 49 | u = 0; 50 | } 51 | res[j] = u; 52 | ++j; 53 | 54 | mpn_rshift(c.data, c.data, n, 1); // c = c/2 55 | } 56 | 57 | return res; 58 | } 59 | 60 | template 61 | T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint &scalar) 62 | { 63 | std::vector naf = find_wnaf(window_size, scalar); 64 | std::vector table(1ul<<(window_size-1)); 65 | T tmp = base; 66 | T dbl = base.dbl(); 67 | for (size_t i = 0; i < 1ul<<(window_size-1); ++i) 68 | { 69 | table[i] = tmp; 70 | tmp = tmp + dbl; 71 | } 72 | 73 | T res = T::zero(); 74 | bool found_nonzero = false; 75 | for (long i = naf.size()-1; i >= 0; --i) 76 | { 77 | if (found_nonzero) 78 | { 79 | res = res.dbl(); 80 | } 81 | 82 | if (naf[i] != 0) 83 | { 84 | found_nonzero = true; 85 | if (naf[i] > 0) 86 | { 87 | res = res + table[naf[i]/2]; 88 | } 89 | else 90 | { 91 | res = res - table[(-naf[i])/2]; 92 | } 93 | } 94 | } 95 | 96 | return res; 97 | } 98 | 99 | template 100 | T opt_window_wnaf_exp(const T &base, const bigint &scalar, const size_t scalar_bits) 101 | { 102 | size_t best = 0; 103 | for (long i = T::wnaf_window_table.size() - 1; i >= 0; --i) 104 | { 105 | if (scalar_bits >= T::wnaf_window_table[i]) 106 | { 107 | best = i+1; 108 | break; 109 | } 110 | } 111 | 112 | if (best > 0) 113 | { 114 | return fixed_window_wnaf_exp(best, base, scalar); 115 | } 116 | else 117 | { 118 | return scalar * base; 119 | } 120 | } 121 | 122 | } // namespace libff 123 | 124 | #endif // WNAF_TCC_ 125 | -------------------------------------------------------------------------------- /libff/algebra/curves/edwards/edwards_g2.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef EDWARDS_G2_HPP_ 9 | #define EDWARDS_G2_HPP_ 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace libff { 17 | 18 | class edwards_G2; 19 | std::ostream& operator<<(std::ostream &, const edwards_G2&); 20 | std::istream& operator>>(std::istream &, edwards_G2&); 21 | 22 | class edwards_G2 { 23 | public: 24 | #ifdef PROFILE_OP_COUNTS 25 | static long long add_cnt; 26 | static long long dbl_cnt; 27 | #endif 28 | static std::vector wnaf_window_table; 29 | static std::vector fixed_base_exp_window_table; 30 | 31 | static edwards_G2 G2_zero; 32 | static edwards_G2 G2_one; 33 | static bool initialized; 34 | 35 | edwards_Fq3 X, Y, Z; 36 | edwards_G2(); 37 | private: 38 | edwards_G2(const edwards_Fq3& X, const edwards_Fq3& Y, const edwards_Fq3& Z) : X(X), Y(Y), Z(Z) {}; 39 | public: 40 | static edwards_Fq3 mul_by_a(const edwards_Fq3 &elt); 41 | static edwards_Fq3 mul_by_d(const edwards_Fq3 &elt); 42 | typedef edwards_Fq base_field; 43 | typedef edwards_Fq3 twist_field; 44 | typedef edwards_Fr scalar_field; 45 | 46 | // using inverted coordinates 47 | edwards_G2(const edwards_Fq3& X, const edwards_Fq3& Y) : X(Y), Y(X), Z(X*Y) {}; 48 | 49 | void print() const; 50 | void print_coordinates() const; 51 | 52 | void to_affine_coordinates(); 53 | void to_special(); 54 | bool is_special() const; 55 | 56 | bool is_zero() const; 57 | 58 | bool operator==(const edwards_G2 &other) const; 59 | bool operator!=(const edwards_G2 &other) const; 60 | 61 | edwards_G2 operator+(const edwards_G2 &other) const; 62 | edwards_G2 operator-() const; 63 | edwards_G2 operator-(const edwards_G2 &other) const; 64 | 65 | edwards_G2 add(const edwards_G2 &other) const; 66 | edwards_G2 mixed_add(const edwards_G2 &other) const; 67 | edwards_G2 dbl() const; 68 | edwards_G2 mul_by_q() const; 69 | 70 | bool is_well_formed() const; 71 | 72 | static edwards_G2 zero(); 73 | static edwards_G2 one(); 74 | static edwards_G2 random_element(); 75 | 76 | static std::size_t size_in_bits() { return twist_field::ceil_size_in_bits() + 1; } 77 | static bigint field_char() { return base_field::field_char(); } 78 | static bigint order() { return scalar_field::field_char(); } 79 | 80 | friend std::ostream& operator<<(std::ostream &out, const edwards_G2 &g); 81 | friend std::istream& operator>>(std::istream &in, edwards_G2 &g); 82 | 83 | static void batch_to_special_all_non_zeros(std::vector &vec); 84 | }; 85 | 86 | template 87 | edwards_G2 operator*(const bigint &lhs, const edwards_G2 &rhs) 88 | { 89 | return scalar_mul(rhs, lhs); 90 | } 91 | 92 | template& modulus_p> 93 | edwards_G2 operator*(const Fp_model &lhs, const edwards_G2 &rhs) 94 | { 95 | return scalar_mul(rhs, lhs.as_bigint()); 96 | } 97 | 98 | } // namespace libff 99 | #endif // EDWARDS_G2_HPP_ 100 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn128_g2.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BN128_G2_HPP_ 9 | #define BN128_G2_HPP_ 10 | #include 11 | #include 12 | 13 | #include "depends/ate-pairing/include/bn.h" 14 | 15 | #include 16 | #include 17 | 18 | namespace libff { 19 | 20 | class bn128_G2; 21 | std::ostream& operator<<(std::ostream &, const bn128_G2&); 22 | std::istream& operator>>(std::istream &, bn128_G2&); 23 | 24 | class bn128_G2 { 25 | private: 26 | static bn::Fp2 sqrt(const bn::Fp2 &el); 27 | public: 28 | #ifdef PROFILE_OP_COUNTS 29 | static long long add_cnt; 30 | static long long dbl_cnt; 31 | #endif 32 | static std::vector wnaf_window_table; 33 | static std::vector fixed_base_exp_window_table; 34 | static bn128_G2 G2_zero; 35 | static bn128_G2 G2_one; 36 | static bool initialized; 37 | 38 | typedef bn128_Fq base_field; 39 | typedef bn128_Fr scalar_field; 40 | 41 | // Cofactor 42 | static const mp_size_t h_bitcount = 256; 43 | static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 44 | static bigint h; 45 | 46 | bn::Fp2 X, Y, Z; 47 | void fill_coord(bn::Fp2 coord[3]) const { coord[0] = this->X; coord[1] = this->Y; coord[2] = this->Z; }; 48 | 49 | bn128_G2(); 50 | bn128_G2(bn::Fp2 coord[3]) : X(coord[0]), Y(coord[1]), Z(coord[2]) {}; 51 | 52 | void print() const; 53 | void print_coordinates() const; 54 | 55 | void to_affine_coordinates(); 56 | void to_special(); 57 | bool is_special() const; 58 | 59 | bool is_zero() const; 60 | 61 | bool operator==(const bn128_G2 &other) const; 62 | bool operator!=(const bn128_G2 &other) const; 63 | 64 | bn128_G2 operator+(const bn128_G2 &other) const; 65 | bn128_G2 operator-() const; 66 | bn128_G2 operator-(const bn128_G2 &other) const; 67 | 68 | bn128_G2 add(const bn128_G2 &other) const; 69 | bn128_G2 mixed_add(const bn128_G2 &other) const; 70 | bn128_G2 dbl() const; 71 | bn128_G2 mul_by_cofactor() const; 72 | 73 | bool is_well_formed() const; 74 | 75 | static bn128_G2 zero(); 76 | static bn128_G2 one(); 77 | static bn128_G2 random_element(); 78 | 79 | static std::size_t size_in_bits() { return 2*base_field::ceil_size_in_bits() + 1; } 80 | static bigint field_char() { return base_field::field_char(); } 81 | static bigint order() { return scalar_field::field_char(); } 82 | 83 | friend std::ostream& operator<<(std::ostream &out, const bn128_G2 &g); 84 | friend std::istream& operator>>(std::istream &in, bn128_G2 &g); 85 | 86 | static void batch_to_special_all_non_zeros(std::vector &vec); 87 | }; 88 | 89 | template 90 | bn128_G2 operator*(const bigint &lhs, const bn128_G2 &rhs) 91 | { 92 | return scalar_mul(rhs, lhs); 93 | } 94 | 95 | template& modulus_p> 96 | bn128_G2 operator*(const Fp_model &lhs, const bn128_G2 &rhs) 97 | { 98 | return scalar_mul(rhs, lhs.as_bigint()); 99 | } 100 | 101 | } // namespace libff 102 | #endif // BN128_G2_HPP_ 103 | -------------------------------------------------------------------------------- /libff/algebra/curves/bls12_381/bls12_381_g1.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BLS12_381_G1_HPP_ 9 | #define BLS12_381_G1_HPP_ 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace libff { 16 | 17 | class bls12_381_G1; 18 | std::ostream& operator<<(std::ostream &, const bls12_381_G1&); 19 | std::istream& operator>>(std::istream &, bls12_381_G1&); 20 | 21 | class bls12_381_G1 { 22 | public: 23 | #ifdef PROFILE_OP_COUNTS 24 | static long long add_cnt; 25 | static long long dbl_cnt; 26 | #endif 27 | static std::vector wnaf_window_table; 28 | static std::vector fixed_base_exp_window_table; 29 | static bls12_381_G1 G1_zero; 30 | static bls12_381_G1 G1_one; 31 | // Cofactor 32 | static const mp_size_t h_bitcount = 126; 33 | static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 34 | static bigint h; 35 | 36 | typedef bls12_381_Fq base_field; 37 | typedef bls12_381_Fr scalar_field; 38 | 39 | bls12_381_Fq X, Y, Z; 40 | 41 | // using Jacobian coordinates 42 | bls12_381_G1(); 43 | bls12_381_G1(const bls12_381_Fq& X, const bls12_381_Fq& Y, const bls12_381_Fq& Z) : X(X), Y(Y), Z(Z) {}; 44 | 45 | void print() const; 46 | void print_coordinates() const; 47 | 48 | void to_affine_coordinates(); 49 | void to_special(); 50 | bool is_special() const; 51 | 52 | bool is_zero() const; 53 | 54 | bool operator==(const bls12_381_G1 &other) const; 55 | bool operator!=(const bls12_381_G1 &other) const; 56 | 57 | bls12_381_G1 operator+(const bls12_381_G1 &other) const; 58 | bls12_381_G1 operator-() const; 59 | bls12_381_G1 operator-(const bls12_381_G1 &other) const; 60 | 61 | bls12_381_G1 add(const bls12_381_G1 &other) const; 62 | bls12_381_G1 mixed_add(const bls12_381_G1 &other) const; 63 | bls12_381_G1 dbl() const; 64 | bls12_381_G1 mul_by_cofactor() const; 65 | 66 | bool is_well_formed() const; 67 | 68 | static bls12_381_G1 zero(); 69 | static bls12_381_G1 one(); 70 | static bls12_381_G1 random_element(); 71 | 72 | static std::size_t size_in_bits() { return base_field::ceil_size_in_bits() + 1; } 73 | static bigint field_char() { return base_field::field_char(); } 74 | static bigint order() { return scalar_field::field_char(); } 75 | 76 | friend std::ostream& operator<<(std::ostream &out, const bls12_381_G1 &g); 77 | friend std::istream& operator>>(std::istream &in, bls12_381_G1 &g); 78 | 79 | static void batch_to_special_all_non_zeros(std::vector &vec); 80 | }; 81 | 82 | template 83 | bls12_381_G1 operator*(const bigint &lhs, const bls12_381_G1 &rhs) 84 | { 85 | return scalar_mul(rhs, lhs); 86 | } 87 | 88 | template& modulus_p> 89 | bls12_381_G1 operator*(const Fp_model &lhs, const bls12_381_G1 &rhs) 90 | { 91 | return scalar_mul(rhs, lhs.as_bigint()); 92 | } 93 | 94 | std::ostream& operator<<(std::ostream& out, const std::vector &v); 95 | std::istream& operator>>(std::istream& in, std::vector &v); 96 | 97 | } // namespace libff 98 | #endif // BLS12_381_G1_HPP_ 99 | -------------------------------------------------------------------------------- /libff/algebra/curves/bls12_381/bls12_381_g2.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BLS12_381_G2_HPP_ 9 | #define BLS12_381_G2_HPP_ 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace libff { 16 | 17 | class bls12_381_G2; 18 | std::ostream& operator<<(std::ostream &, const bls12_381_G2&); 19 | std::istream& operator>>(std::istream &, bls12_381_G2&); 20 | 21 | class bls12_381_G2 { 22 | public: 23 | #ifdef PROFILE_OP_COUNTS 24 | static long long add_cnt; 25 | static long long dbl_cnt; 26 | #endif 27 | static std::vector wnaf_window_table; 28 | static std::vector fixed_base_exp_window_table; 29 | static bls12_381_G2 G2_zero; 30 | static bls12_381_G2 G2_one; 31 | // Cofactor 32 | static const mp_size_t h_bitcount = 507; 33 | static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 34 | static bigint h; 35 | 36 | typedef bls12_381_Fq base_field; 37 | typedef bls12_381_Fq2 twist_field; 38 | typedef bls12_381_Fr scalar_field; 39 | 40 | bls12_381_Fq2 X, Y, Z; 41 | 42 | // using Jacobian coordinates 43 | bls12_381_G2(); 44 | bls12_381_G2(const bls12_381_Fq2& X, const bls12_381_Fq2& Y, const bls12_381_Fq2& Z) : X(X), Y(Y), Z(Z) {}; 45 | 46 | static bls12_381_Fq2 mul_by_b(const bls12_381_Fq2 &elt); 47 | 48 | void print() const; 49 | void print_coordinates() const; 50 | 51 | void to_affine_coordinates(); 52 | void to_special(); 53 | bool is_special() const; 54 | 55 | bool is_zero() const; 56 | 57 | bool operator==(const bls12_381_G2 &other) const; 58 | bool operator!=(const bls12_381_G2 &other) const; 59 | 60 | bls12_381_G2 operator+(const bls12_381_G2 &other) const; 61 | bls12_381_G2 operator-() const; 62 | bls12_381_G2 operator-(const bls12_381_G2 &other) const; 63 | 64 | bls12_381_G2 add(const bls12_381_G2 &other) const; 65 | bls12_381_G2 mixed_add(const bls12_381_G2 &other) const; 66 | bls12_381_G2 dbl() const; 67 | bls12_381_G2 mul_by_q() const; 68 | bls12_381_G2 mul_by_cofactor() const; 69 | 70 | bool is_well_formed() const; 71 | 72 | static bls12_381_G2 zero(); 73 | static bls12_381_G2 one(); 74 | static bls12_381_G2 random_element(); 75 | 76 | static std::size_t size_in_bits() { return twist_field::ceil_size_in_bits() + 1; } 77 | static bigint field_char() { return base_field::field_char(); } 78 | static bigint order() { return scalar_field::field_char(); } 79 | 80 | friend std::ostream& operator<<(std::ostream &out, const bls12_381_G2 &g); 81 | friend std::istream& operator>>(std::istream &in, bls12_381_G2 &g); 82 | 83 | static void batch_to_special_all_non_zeros(std::vector &vec); 84 | }; 85 | 86 | template 87 | bls12_381_G2 operator*(const bigint &lhs, const bls12_381_G2 &rhs) 88 | { 89 | return scalar_mul(rhs, lhs); 90 | } 91 | 92 | template& modulus_p> 93 | bls12_381_G2 operator*(const Fp_model &lhs, const bls12_381_G2 &rhs) 94 | { 95 | return scalar_mul(rhs, lhs.as_bigint()); 96 | } 97 | 98 | } // namespace libff 99 | #endif // BLS12_381_G2_HPP_ 100 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn128_g1.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BN128_G1_HPP_ 9 | #define BN128_G1_HPP_ 10 | #include 11 | 12 | #include "depends/ate-pairing/include/bn.h" 13 | 14 | #include 15 | #include 16 | 17 | namespace libff { 18 | 19 | class bn128_G1; 20 | std::ostream& operator<<(std::ostream &, const bn128_G1&); 21 | std::istream& operator>>(std::istream &, bn128_G1&); 22 | 23 | class bn128_G1 { 24 | private: 25 | static bn::Fp sqrt(const bn::Fp &el); 26 | public: 27 | #ifdef PROFILE_OP_COUNTS 28 | static long long add_cnt; 29 | static long long dbl_cnt; 30 | #endif 31 | static std::vector wnaf_window_table; 32 | static std::vector fixed_base_exp_window_table; 33 | static bn128_G1 G1_zero; 34 | static bn128_G1 G1_one; 35 | static bool initialized; 36 | 37 | typedef bn128_Fq base_field; 38 | typedef bn128_Fr scalar_field; 39 | 40 | // Cofactor 41 | static const mp_size_t h_bitcount = 1; 42 | static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 43 | static bigint h; 44 | 45 | bn::Fp X, Y, Z; 46 | void fill_coord(bn::Fp coord[3]) const { coord[0] = this->X; coord[1] = this->Y; coord[2] = this->Z; return; }; 47 | 48 | bn128_G1(); 49 | bn128_G1(bn::Fp coord[3]) : X(coord[0]), Y(coord[1]), Z(coord[2]) {}; 50 | 51 | void print() const; 52 | void print_coordinates() const; 53 | 54 | void to_affine_coordinates(); 55 | void to_special(); 56 | bool is_special() const; 57 | 58 | bool is_zero() const; 59 | 60 | bool operator==(const bn128_G1 &other) const; 61 | bool operator!=(const bn128_G1 &other) const; 62 | 63 | bn128_G1 operator+(const bn128_G1 &other) const; 64 | bn128_G1 operator-() const; 65 | bn128_G1 operator-(const bn128_G1 &other) const; 66 | 67 | bn128_G1 add(const bn128_G1 &other) const; 68 | bn128_G1 mixed_add(const bn128_G1 &other) const; 69 | bn128_G1 dbl() const; 70 | bn128_G1 mul_by_cofactor() const; 71 | 72 | bool is_well_formed() const; 73 | 74 | static bn128_G1 zero(); 75 | static bn128_G1 one(); 76 | static bn128_G1 random_element(); 77 | 78 | static std::size_t size_in_bits() { return bn128_Fq::ceil_size_in_bits() + 1; } 79 | static bigint field_char() { return base_field::field_char(); } 80 | static bigint order() { return scalar_field::field_char(); } 81 | 82 | friend std::ostream& operator<<(std::ostream &out, const bn128_G1 &g); 83 | friend std::istream& operator>>(std::istream &in, bn128_G1 &g); 84 | 85 | static void batch_to_special_all_non_zeros(std::vector &vec); 86 | }; 87 | 88 | template 89 | bn128_G1 operator*(const bigint &lhs, const bn128_G1 &rhs) 90 | { 91 | return scalar_mul(rhs, lhs); 92 | } 93 | 94 | template& modulus_p> 95 | bn128_G1 operator*(const Fp_model &lhs, const bn128_G1 &rhs) 96 | { 97 | return scalar_mul(rhs, lhs.as_bigint()); 98 | } 99 | 100 | std::ostream& operator<<(std::ostream& out, const std::vector &v); 101 | std::istream& operator>>(std::istream& in, std::vector &v); 102 | 103 | 104 | } // namespace libff 105 | #endif // BN128_G1_HPP_ 106 | -------------------------------------------------------------------------------- /libff/algebra/curves/alt_bn128/alt_bn128_g1.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef ALT_BN128_G1_HPP_ 9 | #define ALT_BN128_G1_HPP_ 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace libff { 16 | 17 | class alt_bn128_G1; 18 | std::ostream& operator<<(std::ostream &, const alt_bn128_G1&); 19 | std::istream& operator>>(std::istream &, alt_bn128_G1&); 20 | 21 | class alt_bn128_G1 { 22 | public: 23 | #ifdef PROFILE_OP_COUNTS 24 | static long long add_cnt; 25 | static long long dbl_cnt; 26 | #endif 27 | static std::vector wnaf_window_table; 28 | static std::vector fixed_base_exp_window_table; 29 | static alt_bn128_G1 G1_zero; 30 | static alt_bn128_G1 G1_one; 31 | static bool initialized; 32 | 33 | typedef alt_bn128_Fq base_field; 34 | typedef alt_bn128_Fr scalar_field; 35 | 36 | // Cofactor 37 | static const mp_size_t h_bitcount = 1; 38 | static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 39 | static bigint h; 40 | 41 | alt_bn128_Fq X, Y, Z; 42 | 43 | // using Jacobian coordinates 44 | alt_bn128_G1(); 45 | alt_bn128_G1(const alt_bn128_Fq& X, const alt_bn128_Fq& Y, const alt_bn128_Fq& Z) : X(X), Y(Y), Z(Z) {}; 46 | 47 | void print() const; 48 | void print_coordinates() const; 49 | 50 | void to_affine_coordinates(); 51 | void to_special(); 52 | bool is_special() const; 53 | 54 | bool is_zero() const; 55 | 56 | bool operator==(const alt_bn128_G1 &other) const; 57 | bool operator!=(const alt_bn128_G1 &other) const; 58 | 59 | alt_bn128_G1 operator+(const alt_bn128_G1 &other) const; 60 | alt_bn128_G1 operator-() const; 61 | alt_bn128_G1 operator-(const alt_bn128_G1 &other) const; 62 | 63 | alt_bn128_G1 add(const alt_bn128_G1 &other) const; 64 | alt_bn128_G1 mixed_add(const alt_bn128_G1 &other) const; 65 | alt_bn128_G1 dbl() const; 66 | alt_bn128_G1 mul_by_cofactor() const; 67 | 68 | bool is_well_formed() const; 69 | 70 | static alt_bn128_G1 zero(); 71 | static alt_bn128_G1 one(); 72 | static alt_bn128_G1 random_element(); 73 | 74 | static std::size_t size_in_bits() { return base_field::ceil_size_in_bits() + 1; } 75 | static bigint field_char() { return base_field::field_char(); } 76 | static bigint order() { return scalar_field::field_char(); } 77 | 78 | friend std::ostream& operator<<(std::ostream &out, const alt_bn128_G1 &g); 79 | friend std::istream& operator>>(std::istream &in, alt_bn128_G1 &g); 80 | 81 | static void batch_to_special_all_non_zeros(std::vector &vec); 82 | }; 83 | 84 | template 85 | alt_bn128_G1 operator*(const bigint &lhs, const alt_bn128_G1 &rhs) 86 | { 87 | return scalar_mul(rhs, lhs); 88 | } 89 | 90 | template& modulus_p> 91 | alt_bn128_G1 operator*(const Fp_model &lhs, const alt_bn128_G1 &rhs) 92 | { 93 | return scalar_mul(rhs, lhs.as_bigint()); 94 | } 95 | 96 | std::ostream& operator<<(std::ostream& out, const std::vector &v); 97 | std::istream& operator>>(std::istream& in, std::vector &v); 98 | 99 | } // namespace libff 100 | #endif // ALT_BN128_G1_HPP_ 101 | -------------------------------------------------------------------------------- /libff/algebra/curves/alt_bn128/alt_bn128_g2.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef ALT_BN128_G2_HPP_ 9 | #define ALT_BN128_G2_HPP_ 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace libff { 16 | 17 | class alt_bn128_G2; 18 | std::ostream& operator<<(std::ostream &, const alt_bn128_G2&); 19 | std::istream& operator>>(std::istream &, alt_bn128_G2&); 20 | 21 | class alt_bn128_G2 { 22 | public: 23 | #ifdef PROFILE_OP_COUNTS 24 | static long long add_cnt; 25 | static long long dbl_cnt; 26 | #endif 27 | static std::vector wnaf_window_table; 28 | static std::vector fixed_base_exp_window_table; 29 | static alt_bn128_G2 G2_zero; 30 | static alt_bn128_G2 G2_one; 31 | static bool initialized; 32 | 33 | typedef alt_bn128_Fq base_field; 34 | typedef alt_bn128_Fq2 twist_field; 35 | typedef alt_bn128_Fr scalar_field; 36 | 37 | // Cofactor 38 | static const mp_size_t h_bitcount = 256; 39 | static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 40 | static bigint h; 41 | 42 | alt_bn128_Fq2 X, Y, Z; 43 | 44 | // using Jacobian coordinates 45 | alt_bn128_G2(); 46 | alt_bn128_G2(const alt_bn128_Fq2& X, const alt_bn128_Fq2& Y, const alt_bn128_Fq2& Z) : X(X), Y(Y), Z(Z) {}; 47 | 48 | static alt_bn128_Fq2 mul_by_b(const alt_bn128_Fq2 &elt); 49 | 50 | void print() const; 51 | void print_coordinates() const; 52 | 53 | void to_affine_coordinates(); 54 | void to_special(); 55 | bool is_special() const; 56 | 57 | bool is_zero() const; 58 | 59 | bool operator==(const alt_bn128_G2 &other) const; 60 | bool operator!=(const alt_bn128_G2 &other) const; 61 | 62 | alt_bn128_G2 operator+(const alt_bn128_G2 &other) const; 63 | alt_bn128_G2 operator-() const; 64 | alt_bn128_G2 operator-(const alt_bn128_G2 &other) const; 65 | 66 | alt_bn128_G2 add(const alt_bn128_G2 &other) const; 67 | alt_bn128_G2 mixed_add(const alt_bn128_G2 &other) const; 68 | alt_bn128_G2 dbl() const; 69 | alt_bn128_G2 mul_by_q() const; 70 | alt_bn128_G2 mul_by_cofactor() const; 71 | 72 | bool is_well_formed() const; 73 | 74 | static alt_bn128_G2 zero(); 75 | static alt_bn128_G2 one(); 76 | static alt_bn128_G2 random_element(); 77 | 78 | static std::size_t size_in_bits() { return twist_field::ceil_size_in_bits() + 1; } 79 | static bigint field_char() { return base_field::field_char(); } 80 | static bigint order() { return scalar_field::field_char(); } 81 | 82 | friend std::ostream& operator<<(std::ostream &out, const alt_bn128_G2 &g); 83 | friend std::istream& operator>>(std::istream &in, alt_bn128_G2 &g); 84 | 85 | static void batch_to_special_all_non_zeros(std::vector &vec); 86 | }; 87 | 88 | template 89 | alt_bn128_G2 operator*(const bigint &lhs, const alt_bn128_G2 &rhs) 90 | { 91 | return scalar_mul(rhs, lhs); 92 | } 93 | 94 | template& modulus_p> 95 | alt_bn128_G2 operator*(const Fp_model &lhs, const alt_bn128_G2 &rhs) 96 | { 97 | return scalar_mul(rhs, lhs.as_bigint()); 98 | } 99 | 100 | 101 | } // namespace libff 102 | #endif // ALT_BN128_G2_HPP_ 103 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt4/mnt4_g2.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of interfaces for the MNT4 G2 group. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT4_G2_HPP_ 13 | #define MNT4_G2_HPP_ 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | namespace libff { 21 | 22 | class mnt4_G2; 23 | std::ostream& operator<<(std::ostream &, const mnt4_G2&); 24 | std::istream& operator>>(std::istream &, mnt4_G2&); 25 | 26 | class mnt4_G2 { 27 | public: 28 | #ifdef PROFILE_OP_COUNTS 29 | static long long add_cnt; 30 | static long long dbl_cnt; 31 | #endif 32 | static std::vector wnaf_window_table; 33 | static std::vector fixed_base_exp_window_table; 34 | static mnt4_G2 G2_zero; 35 | static mnt4_G2 G2_one; 36 | static bool initialized; 37 | static mnt4_Fq2 twist; 38 | static mnt4_Fq2 coeff_a; 39 | static mnt4_Fq2 coeff_b; 40 | 41 | typedef mnt4_Fq base_field; 42 | typedef mnt4_Fq2 twist_field; 43 | typedef mnt4_Fr scalar_field; 44 | 45 | // Cofactor 46 | static const mp_size_t h_bitcount = 298; 47 | static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 48 | static bigint h; 49 | 50 | mnt4_Fq2 X, Y, Z; 51 | 52 | // using projective coordinates 53 | mnt4_G2(); 54 | mnt4_G2(const mnt4_Fq2& X, const mnt4_Fq2& Y, const mnt4_Fq2& Z) : X(X), Y(Y), Z(Z) {}; 55 | 56 | static mnt4_Fq2 mul_by_a(const mnt4_Fq2 &elt); 57 | static mnt4_Fq2 mul_by_b(const mnt4_Fq2 &elt); 58 | 59 | void print() const; 60 | void print_coordinates() const; 61 | 62 | void to_affine_coordinates(); 63 | void to_special(); 64 | bool is_special() const; 65 | 66 | bool is_zero() const; 67 | 68 | bool operator==(const mnt4_G2 &other) const; 69 | bool operator!=(const mnt4_G2 &other) const; 70 | 71 | mnt4_G2 operator+(const mnt4_G2 &other) const; 72 | mnt4_G2 operator-() const; 73 | mnt4_G2 operator-(const mnt4_G2 &other) const; 74 | 75 | mnt4_G2 add(const mnt4_G2 &other) const; 76 | mnt4_G2 mixed_add(const mnt4_G2 &other) const; 77 | mnt4_G2 dbl() const; 78 | mnt4_G2 mul_by_q() const; 79 | mnt4_G2 mul_by_cofactor() const; 80 | 81 | bool is_well_formed() const; 82 | 83 | static mnt4_G2 zero(); 84 | static mnt4_G2 one(); 85 | static mnt4_G2 random_element(); 86 | 87 | static std::size_t size_in_bits() { return mnt4_Fq2::ceil_size_in_bits() + 1; } 88 | static bigint field_char() { return mnt4_Fq::field_char(); } 89 | static bigint order() { return mnt4_Fr::field_char(); } 90 | 91 | friend std::ostream& operator<<(std::ostream &out, const mnt4_G2 &g); 92 | friend std::istream& operator>>(std::istream &in, mnt4_G2 &g); 93 | 94 | static void batch_to_special_all_non_zeros(std::vector &vec); 95 | }; 96 | 97 | template 98 | mnt4_G2 operator*(const bigint &lhs, const mnt4_G2 &rhs) 99 | { 100 | return scalar_mul(rhs, lhs); 101 | } 102 | 103 | template& modulus_p> 104 | mnt4_G2 operator*(const Fp_model &lhs, const mnt4_G2 &rhs) 105 | { 106 | return scalar_mul(rhs, lhs.as_bigint()); 107 | } 108 | 109 | } // namespace libff 110 | 111 | #endif // MNT4_G2_HPP_ 112 | -------------------------------------------------------------------------------- /libff/common/serialization.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of serialization routines and constants. 4 | ***************************************************************************** 5 | * @author This file is part of libff, developed by SCIPR Lab 6 | * and contributors (see AUTHORS). 7 | * @copyright MIT license (see LICENSE file) 8 | *****************************************************************************/ 9 | #ifndef SERIALIZATION_HPP_ 10 | #define SERIALIZATION_HPP_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace libff { 19 | 20 | /* 21 | * @todo 22 | * The serialization is fragile. Shoud be rewritten using a standard, portable-format 23 | * library like boost::serialize. 24 | * 25 | * However, for now the following conventions are used within the code. 26 | * 27 | * All algebraic objects support either binary or decimal output using 28 | * the standard C++ stream operators (operator<<, operator>>). 29 | * 30 | * The binary mode is activated by defining a BINARY_OUTPUT 31 | * preprocessor macro (e.g. g++ -DBINARY_OUTPUT ...). 32 | * 33 | * Binary output assumes that the stream is to be binary read at its 34 | * current position so any white space should be consumed beforehand. 35 | * 36 | * Consecutive algebraic objects are separated by OUTPUT_NEWLINE and 37 | * within themselves (e.g. X and Y coordinates for field elements) with 38 | * OUTPUT_SEPARATOR (as defined below). 39 | * 40 | * Therefore to dump two integers, two Fp elements and another integer 41 | * one would: 42 | * 43 | * out << 3 << "\n"; 44 | * out << 4 << "\n"; 45 | * out << FieldT(56) << OUTPUT_NEWLINE; 46 | * out << FieldT(78) << OUTPUT_NEWLINE; 47 | * out << 9 << "\n"; 48 | * 49 | * Then reading back it its reader's responsibility (!) to consume "\n" 50 | * after 4, but Fp::operator<< will correctly consume OUTPUT_NEWLINE. 51 | * 52 | * The reader should also consume "\n" after 9, so that another field 53 | * element can be properly chained. This is especially important for 54 | * binary output. 55 | * 56 | * The binary serialization of algebraic objects is currently *not* 57 | * portable between machines of different word sizes. 58 | */ 59 | 60 | #ifdef BINARY_OUTPUT 61 | #define OUTPUT_NEWLINE "" 62 | #define OUTPUT_SEPARATOR "" 63 | #else 64 | #define OUTPUT_NEWLINE "\n" 65 | #define OUTPUT_SEPARATOR " " 66 | #endif 67 | 68 | inline void consume_newline(std::istream &in); 69 | inline void consume_OUTPUT_NEWLINE(std::istream &in); 70 | inline void consume_OUTPUT_SEPARATOR(std::istream &in); 71 | 72 | inline void output_bool(std::ostream &out, const bool b); 73 | inline void input_bool(std::istream &in, bool &b); 74 | 75 | inline void output_bool_vector(std::ostream &out, const std::vector &v); 76 | inline void input_bool_vector(std::istream &in, std::vector &v); 77 | 78 | template 79 | T reserialize(const T &obj); 80 | 81 | template 82 | std::ostream& operator<<(std::ostream& out, const std::vector &v); 83 | 84 | template 85 | std::istream& operator>>(std::ostream& out, std::vector &v); 86 | 87 | template 88 | std::ostream& operator<<(std::ostream& out, const std::map &m); 89 | 90 | template 91 | std::istream& operator>>(std::istream& in, std::map &m); 92 | 93 | template 94 | std::ostream& operator<<(std::ostream& out, const std::set &s); 95 | 96 | template 97 | std::istream& operator>>(std::istream& in, std::set &s); 98 | 99 | } // namespace libff 100 | 101 | #include 102 | 103 | #endif // SERIALIZATION_HPP_ 104 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt4/mnt4_g1.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of interfaces for the MNT4 G1 group. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT4_G1_HPP_ 13 | #define MNT4_G1_HPP_ 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | namespace libff { 21 | 22 | class mnt4_G1; 23 | std::ostream& operator<<(std::ostream &, const mnt4_G1&); 24 | std::istream& operator>>(std::istream &, mnt4_G1&); 25 | 26 | class mnt4_G1 { 27 | public: 28 | #ifdef PROFILE_OP_COUNTS 29 | static long long add_cnt; 30 | static long long dbl_cnt; 31 | #endif 32 | static std::vector wnaf_window_table; 33 | static std::vector fixed_base_exp_window_table; 34 | static mnt4_G1 G1_zero; 35 | static mnt4_G1 G1_one; 36 | static bool initialized; 37 | static mnt4_Fq coeff_a; 38 | static mnt4_Fq coeff_b; 39 | 40 | typedef mnt4_Fq base_field; 41 | typedef mnt4_Fr scalar_field; 42 | 43 | // Cofactor 44 | static const mp_size_t h_bitcount = 1; 45 | static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 46 | static bigint h; 47 | 48 | mnt4_Fq X, Y, Z; 49 | 50 | // using projective coordinates 51 | mnt4_G1(); 52 | mnt4_G1(const mnt4_Fq& X, const mnt4_Fq& Y) : X(X), Y(Y), Z(base_field::one()) {} 53 | mnt4_G1(const mnt4_Fq& X, const mnt4_Fq& Y, const mnt4_Fq& Z) : X(X), Y(Y), Z(Z) {} 54 | 55 | void print() const; 56 | void print_coordinates() const; 57 | 58 | void to_affine_coordinates(); 59 | void to_special(); 60 | bool is_special() const; 61 | 62 | bool is_zero() const; 63 | 64 | bool operator==(const mnt4_G1 &other) const; 65 | bool operator!=(const mnt4_G1 &other) const; 66 | 67 | mnt4_G1 operator+(const mnt4_G1 &other) const; 68 | mnt4_G1 operator-() const; 69 | mnt4_G1 operator-(const mnt4_G1 &other) const; 70 | 71 | mnt4_G1 add(const mnt4_G1 &other) const; 72 | mnt4_G1 mixed_add(const mnt4_G1 &other) const; 73 | mnt4_G1 dbl() const; 74 | mnt4_G1 mul_by_cofactor() const; 75 | 76 | bool is_well_formed() const; 77 | 78 | static mnt4_G1 zero(); 79 | static mnt4_G1 one(); 80 | static mnt4_G1 random_element(); 81 | 82 | static std::size_t size_in_bits() { return mnt4_Fq::ceil_size_in_bits() + 1; } 83 | static bigint field_char() { return mnt4_Fq::field_char(); } 84 | static bigint order() { return mnt4_Fr::field_char(); } 85 | 86 | friend std::ostream& operator<<(std::ostream &out, const mnt4_G1 &g); 87 | friend std::istream& operator>>(std::istream &in, mnt4_G1 &g); 88 | 89 | static void batch_to_special_all_non_zeros(std::vector &vec); 90 | }; 91 | 92 | template 93 | mnt4_G1 operator*(const bigint &lhs, const mnt4_G1 &rhs) 94 | { 95 | return scalar_mul(rhs, lhs); 96 | } 97 | 98 | template& modulus_p> 99 | mnt4_G1 operator*(const Fp_model &lhs, const mnt4_G1 &rhs) 100 | { 101 | return scalar_mul(rhs, lhs.as_bigint()); 102 | } 103 | 104 | std::ostream& operator<<(std::ostream& out, const std::vector &v); 105 | std::istream& operator>>(std::istream& in, std::vector &v); 106 | 107 | } // namespace libff 108 | 109 | #endif // MNT4_G1_HPP_ 110 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt6/mnt6_g2.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of interfaces for the MNT6 G2 group. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT6_G2_HPP_ 13 | #define MNT6_G2_HPP_ 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | namespace libff { 21 | 22 | class mnt6_G2; 23 | std::ostream& operator<<(std::ostream &, const mnt6_G2&); 24 | std::istream& operator>>(std::istream &, mnt6_G2&); 25 | 26 | class mnt6_G2 { 27 | public: 28 | #ifdef PROFILE_OP_COUNTS 29 | static long long add_cnt; 30 | static long long dbl_cnt; 31 | #endif 32 | static std::vector wnaf_window_table; 33 | static std::vector fixed_base_exp_window_table; 34 | static mnt6_G2 G2_zero; 35 | static mnt6_G2 G2_one; 36 | static bool initialized; 37 | static mnt6_Fq3 twist; 38 | static mnt6_Fq3 coeff_a; 39 | static mnt6_Fq3 coeff_b; 40 | 41 | typedef mnt6_Fq base_field; 42 | typedef mnt6_Fq3 twist_field; 43 | typedef mnt6_Fr scalar_field; 44 | 45 | // Cofactor 46 | static const mp_size_t h_bitcount = 596; 47 | static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 48 | static bigint h; 49 | 50 | mnt6_Fq3 X, Y, Z; 51 | 52 | // using projective coordinates 53 | mnt6_G2(); 54 | mnt6_G2(const mnt6_Fq3& X, const mnt6_Fq3& Y, const mnt6_Fq3& Z) : X(X), Y(Y), Z(Z) {} 55 | 56 | static mnt6_Fq3 mul_by_a(const mnt6_Fq3 &elt); 57 | static mnt6_Fq3 mul_by_b(const mnt6_Fq3 &elt); 58 | 59 | void print() const; 60 | void print_coordinates() const; 61 | 62 | void to_affine_coordinates(); 63 | void to_special(); 64 | bool is_special() const; 65 | 66 | bool is_zero() const; 67 | 68 | bool operator==(const mnt6_G2 &other) const; 69 | bool operator!=(const mnt6_G2 &other) const; 70 | 71 | mnt6_G2 operator+(const mnt6_G2 &other) const; 72 | mnt6_G2 operator-() const; 73 | mnt6_G2 operator-(const mnt6_G2 &other) const; 74 | 75 | mnt6_G2 add(const mnt6_G2 &other) const; 76 | mnt6_G2 mixed_add(const mnt6_G2 &other) const; 77 | mnt6_G2 dbl() const; 78 | mnt6_G2 mul_by_q() const; 79 | mnt6_G2 mul_by_cofactor() const; 80 | 81 | bool is_well_formed() const; 82 | 83 | static mnt6_G2 zero(); 84 | static mnt6_G2 one(); 85 | static mnt6_G2 random_element(); 86 | 87 | static std::size_t size_in_bits() { return twist_field::ceil_size_in_bits() + 1; } 88 | static bigint field_char() { return base_field::field_char(); } 89 | static bigint order() { return scalar_field::field_char(); } 90 | 91 | friend std::ostream& operator<<(std::ostream &out, const mnt6_G2 &g); 92 | friend std::istream& operator>>(std::istream &in, mnt6_G2 &g); 93 | 94 | static void batch_to_special_all_non_zeros(std::vector &vec); 95 | }; 96 | 97 | template 98 | mnt6_G2 operator*(const bigint &lhs, const mnt6_G2 &rhs) 99 | { 100 | return scalar_mul(rhs, lhs); 101 | } 102 | 103 | template& modulus_p> 104 | mnt6_G2 operator*(const Fp_model &lhs, const mnt6_G2 &rhs) 105 | { 106 | return scalar_mul(rhs, lhs.as_bigint()); 107 | } 108 | 109 | } // namespace libff 110 | 111 | #endif // MNT6_G2_HPP_ 112 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt6/mnt6_g1.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of interfaces for the MNT6 G1 group. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT6_G1_HPP_ 13 | #define MNT6_G1_HPP_ 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | namespace libff { 21 | 22 | class mnt6_G1; 23 | std::ostream& operator<<(std::ostream &, const mnt6_G1&); 24 | std::istream& operator>>(std::istream &, mnt6_G1&); 25 | 26 | class mnt6_G1 { 27 | public: 28 | #ifdef PROFILE_OP_COUNTS 29 | static long long add_cnt; 30 | static long long dbl_cnt; 31 | #endif 32 | static std::vector wnaf_window_table; 33 | static std::vector fixed_base_exp_window_table; 34 | static mnt6_G1 G1_zero; 35 | static mnt6_G1 G1_one; 36 | static bool initialized; 37 | static mnt6_Fq coeff_a; 38 | static mnt6_Fq coeff_b; 39 | 40 | typedef mnt6_Fq base_field; 41 | typedef mnt6_Fr scalar_field; 42 | 43 | // Cofactor 44 | static const mp_size_t h_bitcount = 1; 45 | static const mp_size_t h_limbs = (h_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; 46 | static bigint h; 47 | 48 | mnt6_Fq X, Y, Z; 49 | 50 | // using projective coordinates 51 | mnt6_G1(); 52 | mnt6_G1(const mnt6_Fq& X, const mnt6_Fq& Y) : X(X), Y(Y), Z(base_field::one()) {} 53 | mnt6_G1(const mnt6_Fq& X, const mnt6_Fq& Y, const mnt6_Fq& Z) : X(X), Y(Y), Z(Z) {} 54 | 55 | void print() const; 56 | void print_coordinates() const; 57 | 58 | void to_affine_coordinates(); 59 | void to_special(); 60 | bool is_special() const; 61 | 62 | bool is_zero() const; 63 | 64 | bool operator==(const mnt6_G1 &other) const; 65 | bool operator!=(const mnt6_G1 &other) const; 66 | 67 | mnt6_G1 operator+(const mnt6_G1 &other) const; 68 | mnt6_G1 operator-() const; 69 | mnt6_G1 operator-(const mnt6_G1 &other) const; 70 | 71 | mnt6_G1 add(const mnt6_G1 &other) const; 72 | mnt6_G1 mixed_add(const mnt6_G1 &other) const; 73 | mnt6_G1 dbl() const; 74 | mnt6_G1 mul_by_cofactor() const; 75 | 76 | bool is_well_formed() const; 77 | 78 | static mnt6_G1 zero(); 79 | static mnt6_G1 one(); 80 | static mnt6_G1 random_element(); 81 | 82 | static std::size_t size_in_bits() { return base_field::ceil_size_in_bits() + 1; } 83 | static bigint field_char() { return base_field::field_char(); } 84 | static bigint order() { return scalar_field::field_char(); } 85 | 86 | friend std::ostream& operator<<(std::ostream &out, const mnt6_G1 &g); 87 | friend std::istream& operator>>(std::istream &in, mnt6_G1 &g); 88 | 89 | static void batch_to_special_all_non_zeros(std::vector &vec); 90 | }; 91 | 92 | template 93 | mnt6_G1 operator*(const bigint &lhs, const mnt6_G1 &rhs) 94 | { 95 | return scalar_mul(rhs, lhs); 96 | } 97 | 98 | template& modulus_p> 99 | mnt6_G1 operator*(const Fp_model &lhs, const mnt6_G1 &rhs) 100 | { 101 | return scalar_mul(rhs, lhs.as_bigint()); 102 | } 103 | 104 | std::ostream& operator<<(std::ostream& out, const std::vector &v); 105 | std::istream& operator>>(std::istream& in, std::vector &v); 106 | 107 | } // namespace libff 108 | 109 | #endif // MNT6_G1_HPP_ 110 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt.sage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sage -python 2 | 3 | from sage.all import * 4 | import sys 5 | sys.path.append("../") 6 | import params_generator 7 | 8 | # Computes the order of G1, the safe subgroup of E/Fq 9 | def g1_order(curve_order): 10 | decomposition = factor(curve_order) 11 | # Factor returns the prime decomposition and orders prime 12 | # factors from smaller to biggest 13 | biggest_factor = decomposition[-1] 14 | assert(biggest_factor[1] == 1) 15 | return biggest_factor[0] 16 | 17 | def mnt4_298_params(): 18 | print("Generating parameters for MNT4-298") 19 | # Scalar field 20 | prime_r = 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 21 | params_generator.generate_libff_Fp_model_params(prime_r) 22 | Fr = GF(prime_r) 23 | 24 | # Base field characteristic 25 | prime_q = 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081 26 | params_generator.generate_libff_Fp_model_params(prime_q) 27 | Fq = GF(prime_q) 28 | 29 | # E/Fq 30 | coeff_a = 2 31 | coeff_b = 423894536526684178289416011533888240029318103673896002803341544124054745019340795360841685 32 | curve = EllipticCurve(Fq, [coeff_a, coeff_b]) 33 | 34 | # E'/Fq2 35 | non_residue = Fq(17) 36 | Fqx. = PolynomialRing(Fq, 'j') 37 | assert(Fqx(j^2 + non_residue).is_irreducible()) 38 | Fq2. = GF(prime_q^2, modulus=j^2 - non_residue) 39 | 40 | twist_coeff_a = Fq2(coeff_a * non_residue) 41 | twist_coeff_b = Fq2(coeff_b * non_residue * u) 42 | twist = EllipticCurve(Fq2, [twist_coeff_a, twist_coeff_b]) 43 | 44 | # Cofactors 45 | curve_order = curve.order() 46 | print('curve_order = {}'.format(curve_order)) 47 | twist_order = twist.order() 48 | print('twist_order = {}'.format(twist_order)) 49 | 50 | g1_h = curve_order // g1_order(curve_order) 51 | assert(g1_h == 1) 52 | assert(curve_order == prime_r) 53 | print('g1_h = {}'.format(g1_h)) 54 | g2_h = twist_order // g1_order(curve_order) 55 | print('g2_h = {}'.format(g2_h)) 56 | 57 | def mnt6_298_params(): 58 | print("Generating parameters for MNT6-298") 59 | # Scalar field 60 | prime_r = 475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081 61 | params_generator.generate_libff_Fp_model_params(prime_r) 62 | Fr = GF(prime_r) 63 | 64 | # Base field characteristic 65 | prime_q = 475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137 66 | params_generator.generate_libff_Fp_model_params(prime_q) 67 | Fq = GF(prime_q) 68 | 69 | # E/Fq 70 | coeff_a = 11 71 | coeff_b = 106700080510851735677967319632585352256454251201367587890185989362936000262606668469523074 72 | curve = EllipticCurve(Fq, [coeff_a, coeff_b]) 73 | 74 | # E'/Fq3 75 | non_residue = Fq(5) 76 | print('non_residue = {}'.format(non_residue)) 77 | Fqx. = PolynomialRing(Fq, 'j') 78 | assert(Fqx(j^3 + non_residue).is_irreducible()) 79 | Fq3. = GF(prime_q^3, modulus=j^3 - non_residue) 80 | 81 | twist_coeff_a = Fq3(coeff_a * u^2) 82 | twist_coeff_b = Fq3(coeff_b * non_residue) 83 | 84 | twist = EllipticCurve(Fq3, [twist_coeff_a, twist_coeff_b]) 85 | 86 | # Cofactors 87 | curve_order = curve.order() 88 | print('curve_order = {}'.format(curve_order)) 89 | twist_order = twist.order() 90 | print('twist_order = {}'.format(twist_order)) 91 | 92 | g1_h = curve_order // g1_order(curve_order) 93 | assert(g1_h == 1) 94 | assert(curve_order == prime_r) 95 | print('g1_h = {}'.format(g1_h)) 96 | g2_h = twist_order // g1_order(curve_order) 97 | print('g2_h = {}'.format(g2_h)) 98 | 99 | def main(): 100 | mnt4_298_params() 101 | mnt6_298_params() 102 | 103 | if __name__ == '__main__': 104 | main() 105 | -------------------------------------------------------------------------------- /libff/common/utils.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Implementation of misc math and serialization utility functions. 4 | ***************************************************************************** 5 | * @author This file is part of libff, developed by SCIPR Lab 6 | * and contributors (see AUTHORS). 7 | * @copyright MIT license (see LICENSE file) 8 | *****************************************************************************/ 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace libff { 17 | 18 | using std::size_t; 19 | 20 | /** 21 | * Round n to the next power of two. 22 | * If n is a power of two, return n 23 | */ 24 | size_t get_power_of_two(size_t n) 25 | { 26 | n--; 27 | n |= n >> 1; 28 | n |= n >> 2; 29 | n |= n >> 4; 30 | n |= n >> 8; 31 | n |= n >> 16; 32 | n |= n >> 32; 33 | n++; 34 | 35 | return n; 36 | } 37 | 38 | /* If n is a power of 2, returns n */ 39 | size_t round_to_next_power_of_2(const size_t n) 40 | { 41 | return (1ULL << log2(n)); 42 | } 43 | 44 | bool is_power_of_2(const size_t n) 45 | { 46 | return ((n != 0) && ((n & (n-1)) == 0)); 47 | } 48 | 49 | size_t log2(size_t n) 50 | /* returns ceil(log2(n)), so 1ul< 1) 56 | { 57 | n >>= 1; 58 | r++; 59 | } 60 | 61 | return r; 62 | } 63 | 64 | size_t to_twos_complement(int i, size_t w) 65 | { 66 | assert(i >= -(1l<<(w-1))); 67 | assert(i < (1l<<(w-1))); 68 | return (i >= 0) ? i : i + (1L<>= 1; 84 | } 85 | return r; 86 | } 87 | 88 | bit_vector int_list_to_bits(const std::initializer_list &l, const size_t wordsize) 89 | { 90 | bit_vector res(wordsize*l.size()); 91 | for (size_t i = 0; i < l.size(); ++i) 92 | { 93 | for (size_t j = 0; j < wordsize; ++j) 94 | { 95 | res[i*wordsize + j] = (*(l.begin()+i) & (1UL<<(wordsize-1-j))) != 0U; 96 | } 97 | } 98 | return res; 99 | } 100 | 101 | long long div_ceil(long long x, long long y) 102 | { 103 | if (y == 0) 104 | { 105 | throw std::invalid_argument("libff::div_ceil: division by zero, second argument must be non-zero"); 106 | } 107 | return (x + (y-1)) / y; 108 | } 109 | 110 | bool is_little_endian() 111 | { 112 | uint64_t a = 0x12345678; 113 | unsigned char *c = (unsigned char*)(&a); 114 | return (*c == 0x78); 115 | } 116 | 117 | std::string FORMAT(const std::string &prefix, const char* format, ...) 118 | { 119 | const static size_t MAX_FMT = 256; 120 | char buf[MAX_FMT]; 121 | va_list args; 122 | va_start(args, format); 123 | vsnprintf(buf, MAX_FMT, format, args); 124 | va_end(args); 125 | 126 | return prefix + std::string(buf); 127 | } 128 | 129 | void serialize_bit_vector(std::ostream &out, const bit_vector &v) 130 | { 131 | out << v.size() << "\n"; 132 | for (auto b : v) 133 | { 134 | out << b << "\n"; 135 | } 136 | } 137 | 138 | void deserialize_bit_vector(std::istream &in, bit_vector &v) 139 | { 140 | size_t size; 141 | in >> size; 142 | v.resize(size); 143 | for (size_t i = 0; i < size; ++i) 144 | { 145 | bool b; 146 | in >> b; 147 | v[i] = b; 148 | } 149 | } 150 | 151 | } // namespace libff 152 | -------------------------------------------------------------------------------- /libff/algebra/curves/alt_bn128/alt_bn128_pairing.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef ALT_BN128_PAIRING_HPP_ 9 | #define ALT_BN128_PAIRING_HPP_ 10 | #include 11 | 12 | #include 13 | 14 | namespace libff { 15 | 16 | /* final exponentiation */ 17 | 18 | alt_bn128_GT alt_bn128_final_exponentiation(const alt_bn128_Fq12 &elt); 19 | 20 | /* ate pairing */ 21 | 22 | struct alt_bn128_ate_G1_precomp { 23 | alt_bn128_Fq PX; 24 | alt_bn128_Fq PY; 25 | 26 | bool operator==(const alt_bn128_ate_G1_precomp &other) const; 27 | friend std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_G1_precomp &prec_P); 28 | friend std::istream& operator>>(std::istream &in, alt_bn128_ate_G1_precomp &prec_P); 29 | }; 30 | 31 | struct alt_bn128_ate_ell_coeffs { 32 | alt_bn128_Fq2 ell_0; 33 | alt_bn128_Fq2 ell_VW; 34 | alt_bn128_Fq2 ell_VV; 35 | 36 | bool operator==(const alt_bn128_ate_ell_coeffs &other) const; 37 | friend std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_ell_coeffs &c); 38 | friend std::istream& operator>>(std::istream &in, alt_bn128_ate_ell_coeffs &c); 39 | }; 40 | 41 | struct alt_bn128_ate_G2_precomp { 42 | alt_bn128_Fq2 QX; 43 | alt_bn128_Fq2 QY; 44 | std::vector coeffs; 45 | 46 | bool operator==(const alt_bn128_ate_G2_precomp &other) const; 47 | friend std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_G2_precomp &prec_Q); 48 | friend std::istream& operator>>(std::istream &in, alt_bn128_ate_G2_precomp &prec_Q); 49 | }; 50 | 51 | alt_bn128_ate_G1_precomp alt_bn128_ate_precompute_G1(const alt_bn128_G1& P); 52 | alt_bn128_ate_G2_precomp alt_bn128_ate_precompute_G2(const alt_bn128_G2& Q); 53 | 54 | alt_bn128_Fq12 alt_bn128_ate_miller_loop(const alt_bn128_ate_G1_precomp &prec_P, 55 | const alt_bn128_ate_G2_precomp &prec_Q); 56 | alt_bn128_Fq12 alt_bn128_ate_double_miller_loop(const alt_bn128_ate_G1_precomp &prec_P1, 57 | const alt_bn128_ate_G2_precomp &prec_Q1, 58 | const alt_bn128_ate_G1_precomp &prec_P2, 59 | const alt_bn128_ate_G2_precomp &prec_Q2); 60 | 61 | alt_bn128_Fq12 alt_bn128_ate_pairing(const alt_bn128_G1& P, 62 | const alt_bn128_G2 &Q); 63 | alt_bn128_GT alt_bn128_ate_reduced_pairing(const alt_bn128_G1 &P, 64 | const alt_bn128_G2 &Q); 65 | 66 | /* choice of pairing */ 67 | 68 | typedef alt_bn128_ate_G1_precomp alt_bn128_G1_precomp; 69 | typedef alt_bn128_ate_G2_precomp alt_bn128_G2_precomp; 70 | 71 | alt_bn128_G1_precomp alt_bn128_precompute_G1(const alt_bn128_G1& P); 72 | 73 | alt_bn128_G2_precomp alt_bn128_precompute_G2(const alt_bn128_G2& Q); 74 | 75 | alt_bn128_Fq12 alt_bn128_miller_loop(const alt_bn128_G1_precomp &prec_P, 76 | const alt_bn128_G2_precomp &prec_Q); 77 | 78 | alt_bn128_Fq12 alt_bn128_double_miller_loop(const alt_bn128_G1_precomp &prec_P1, 79 | const alt_bn128_G2_precomp &prec_Q1, 80 | const alt_bn128_G1_precomp &prec_P2, 81 | const alt_bn128_G2_precomp &prec_Q2); 82 | 83 | alt_bn128_Fq12 alt_bn128_pairing(const alt_bn128_G1& P, 84 | const alt_bn128_G2 &Q); 85 | 86 | alt_bn128_GT alt_bn128_reduced_pairing(const alt_bn128_G1 &P, 87 | const alt_bn128_G2 &Q); 88 | 89 | alt_bn128_GT alt_bn128_affine_reduced_pairing(const alt_bn128_G1 &P, 90 | const alt_bn128_G2 &Q); 91 | 92 | } // namespace libff 93 | #endif // ALT_BN128_PAIRING_HPP_ 94 | -------------------------------------------------------------------------------- /libff/algebra/curves/bls12_381/bls12_381_pairing.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef BLS12_381_PAIRING_HPP_ 9 | #define BLS12_381_PAIRING_HPP_ 10 | #include 11 | 12 | #include 13 | 14 | namespace libff { 15 | 16 | /* final exponentiation */ 17 | 18 | bls12_381_GT bls12_381_final_exponentiation(const bls12_381_Fq12 &elt); 19 | 20 | /* ate pairing */ 21 | 22 | struct bls12_381_ate_G1_precomp { 23 | bls12_381_Fq PX; 24 | bls12_381_Fq PY; 25 | 26 | bool operator==(const bls12_381_ate_G1_precomp &other) const; 27 | friend std::ostream& operator<<(std::ostream &out, const bls12_381_ate_G1_precomp &prec_P); 28 | friend std::istream& operator>>(std::istream &in, bls12_381_ate_G1_precomp &prec_P); 29 | }; 30 | 31 | struct bls12_381_ate_ell_coeffs { 32 | bls12_381_Fq2 ell_0; 33 | bls12_381_Fq2 ell_VW; 34 | bls12_381_Fq2 ell_VV; 35 | 36 | bool operator==(const bls12_381_ate_ell_coeffs &other) const; 37 | friend std::ostream& operator<<(std::ostream &out, const bls12_381_ate_ell_coeffs &c); 38 | friend std::istream& operator>>(std::istream &in, bls12_381_ate_ell_coeffs &c); 39 | }; 40 | 41 | struct bls12_381_ate_G2_precomp { 42 | bls12_381_Fq2 QX; 43 | bls12_381_Fq2 QY; 44 | std::vector coeffs; 45 | 46 | bool operator==(const bls12_381_ate_G2_precomp &other) const; 47 | friend std::ostream& operator<<(std::ostream &out, const bls12_381_ate_G2_precomp &prec_Q); 48 | friend std::istream& operator>>(std::istream &in, bls12_381_ate_G2_precomp &prec_Q); 49 | }; 50 | 51 | bls12_381_ate_G1_precomp bls12_381_ate_precompute_G1(const bls12_381_G1& P); 52 | bls12_381_ate_G2_precomp bls12_381_ate_precompute_G2(const bls12_381_G2& Q); 53 | 54 | bls12_381_Fq12 bls12_381_ate_miller_loop(const bls12_381_ate_G1_precomp &prec_P, 55 | const bls12_381_ate_G2_precomp &prec_Q); 56 | bls12_381_Fq12 bls12_381_ate_double_miller_loop(const bls12_381_ate_G1_precomp &prec_P1, 57 | const bls12_381_ate_G2_precomp &prec_Q1, 58 | const bls12_381_ate_G1_precomp &prec_P2, 59 | const bls12_381_ate_G2_precomp &prec_Q2); 60 | 61 | bls12_381_Fq12 bls12_381_ate_pairing(const bls12_381_G1& P, 62 | const bls12_381_G2 &Q); 63 | bls12_381_GT bls12_381_ate_reduced_pairing(const bls12_381_G1 &P, 64 | const bls12_381_G2 &Q); 65 | 66 | /* choice of pairing */ 67 | 68 | typedef bls12_381_ate_G1_precomp bls12_381_G1_precomp; 69 | typedef bls12_381_ate_G2_precomp bls12_381_G2_precomp; 70 | 71 | bls12_381_G1_precomp bls12_381_precompute_G1(const bls12_381_G1& P); 72 | 73 | bls12_381_G2_precomp bls12_381_precompute_G2(const bls12_381_G2& Q); 74 | 75 | bls12_381_Fq12 bls12_381_miller_loop(const bls12_381_G1_precomp &prec_P, 76 | const bls12_381_G2_precomp &prec_Q); 77 | 78 | bls12_381_Fq12 bls12_381_double_miller_loop(const bls12_381_G1_precomp &prec_P1, 79 | const bls12_381_G2_precomp &prec_Q1, 80 | const bls12_381_G1_precomp &prec_P2, 81 | const bls12_381_G2_precomp &prec_Q2); 82 | 83 | bls12_381_Fq12 bls12_381_pairing(const bls12_381_G1& P, 84 | const bls12_381_G2 &Q); 85 | 86 | bls12_381_GT bls12_381_reduced_pairing(const bls12_381_G1 &P, 87 | const bls12_381_G2 &Q); 88 | 89 | bls12_381_GT bls12_381_affine_reduced_pairing(const bls12_381_G1 &P, 90 | const bls12_381_G2 &Q); 91 | 92 | } // namespace libff 93 | #endif // BLS12_381_PAIRING_HPP_ 94 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/gf32.hpp: -------------------------------------------------------------------------------- 1 | /**@file 2 | ***************************************************************************** 3 | Declaration of GF(2^32) finite field. 4 | ***************************************************************************** 5 | * @author This file is part of libff (see AUTHORS), migrated from libiop 6 | * @copyright MIT license (see LICENSE file) 7 | *****************************************************************************/ 8 | 9 | #ifndef LIBFF_ALGEBRA_GF32_HPP_ 10 | #define LIBFF_ALGEBRA_GF32_HPP_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace libff { 18 | 19 | /* gf32 implements the field GF(2)/[x^32 + x^22 + x^2 + x^1 + 1]. 20 | Elements are represented internally with a single uint32 */ 21 | class gf32 { 22 | public: 23 | #ifdef PROFILE_OP_COUNTS // NOTE: op counts are affected when you exponentiate with ^ 24 | static long long add_cnt; 25 | static long long sub_cnt; 26 | static long long mul_cnt; 27 | static long long sqr_cnt; 28 | static long long inv_cnt; 29 | #endif 30 | // x^32 + x^22 + x^2 + x^1 + 1 31 | static const constexpr uint64_t modulus_ = 0b10000000000000000000111; 32 | static const constexpr uint64_t num_bits = 32; 33 | 34 | explicit gf32(); 35 | explicit gf32(const uint32_t value); 36 | 37 | gf32& operator+=(const gf32 &other); 38 | gf32& operator-=(const gf32 &other); 39 | gf32& operator*=(const gf32 &other); 40 | gf32& operator^=(const unsigned long pow); 41 | template 42 | gf32& operator^=(const bigint &pow); 43 | 44 | gf32& square(); 45 | gf32& invert(); 46 | 47 | gf32 operator+(const gf32 &other) const; 48 | gf32 operator-(const gf32 &other) const; 49 | gf32 operator-() const; 50 | gf32 operator*(const gf32 &other) const; 51 | gf32 operator^(const unsigned long pow) const; 52 | template 53 | gf32 operator^(const bigint &pow) const; 54 | 55 | gf32 squared() const; 56 | gf32 inverse() const; 57 | gf32 sqrt() const; 58 | 59 | void randomize(); 60 | void clear(); 61 | 62 | bool operator==(const gf32 &other) const; 63 | bool operator!=(const gf32 &other) const; 64 | 65 | bool is_zero() const; 66 | 67 | void print() const; 68 | /** 69 | * Returns the constituent bits in 64 bit words, in little-endian order. 70 | * Only the right-most ceil_size_in_bits() bits are used; other bits are 0. 71 | */ 72 | std::vector to_words() const; 73 | /** 74 | * Sets the field element from the given bits in 64 bit words, in little-endian order. 75 | * Only the right-most ceil_size_in_bits() bits are used; other bits are ignored. 76 | * Should always return true since the right-most bits are always valid. 77 | */ 78 | bool from_words(std::vector words); 79 | 80 | static gf32 random_element(); 81 | 82 | static gf32 zero(); 83 | static gf32 one(); 84 | static gf32 multiplicative_generator; // generator of gf32^* 85 | 86 | static std::size_t ceil_size_in_bits() { return num_bits; } 87 | static std::size_t floor_size_in_bits() { return num_bits; } 88 | static constexpr std::size_t extension_degree() { return 32; } 89 | template 90 | static constexpr bigint field_char() { return bigint(2); } 91 | 92 | friend std::ostream& operator<<(std::ostream &out, const gf32 &el); 93 | friend std::istream& operator>>(std::istream &in, gf32 &el); 94 | private: 95 | uint32_t value_; 96 | }; 97 | 98 | #ifdef PROFILE_OP_COUNTS 99 | long long gf32::add_cnt = 0; 100 | long long gf32::sub_cnt = 0; 101 | long long gf32::mul_cnt = 0; 102 | long long gf32::sqr_cnt = 0; 103 | long long gf32::inv_cnt = 0; 104 | #endif 105 | 106 | } // namespace libff 107 | #include 108 | 109 | #endif // #ifndef LIBFF_ALGEBRA_GF32_HPP_ 110 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt6/mnt6_pp.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of interfaces for public parameters of MNT6. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT6_PP_HPP_ 13 | #define MNT6_PP_HPP_ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace libff { 22 | 23 | class mnt6_pp { 24 | public: 25 | typedef mnt6_Fr Fp_type; 26 | typedef mnt6_G1 G1_type; 27 | typedef mnt6_G2 G2_type; 28 | typedef mnt6_affine_ate_G1_precomputation affine_ate_G1_precomp_type; 29 | typedef mnt6_affine_ate_G2_precomputation affine_ate_G2_precomp_type; 30 | typedef mnt6_G1_precomp G1_precomp_type; 31 | typedef mnt6_G2_precomp G2_precomp_type; 32 | typedef mnt6_Fq Fq_type; 33 | typedef mnt6_Fq3 Fqe_type; 34 | typedef mnt6_Fq6 Fqk_type; 35 | typedef mnt6_GT GT_type; 36 | 37 | static const bool has_affine_pairing = true; 38 | 39 | static void init_public_params(); 40 | static mnt6_GT final_exponentiation(const mnt6_Fq6 &elt); 41 | static mnt6_G1_precomp precompute_G1(const mnt6_G1 &P); 42 | static mnt6_G2_precomp precompute_G2(const mnt6_G2 &Q); 43 | static mnt6_Fq6 miller_loop(const mnt6_G1_precomp &prec_P, 44 | const mnt6_G2_precomp &prec_Q); 45 | static mnt6_affine_ate_G1_precomputation affine_ate_precompute_G1(const mnt6_G1 &P); 46 | static mnt6_affine_ate_G2_precomputation affine_ate_precompute_G2(const mnt6_G2 &Q); 47 | static mnt6_Fq6 affine_ate_miller_loop(const mnt6_affine_ate_G1_precomputation &prec_P, 48 | const mnt6_affine_ate_G2_precomputation &prec_Q); 49 | static mnt6_Fq6 affine_ate_e_over_e_miller_loop(const mnt6_affine_ate_G1_precomputation &prec_P1, 50 | const mnt6_affine_ate_G2_precomputation &prec_Q1, 51 | const mnt6_affine_ate_G1_precomputation &prec_P2, 52 | const mnt6_affine_ate_G2_precomputation &prec_Q2); 53 | static mnt6_Fq6 affine_ate_e_times_e_over_e_miller_loop(const mnt6_affine_ate_G1_precomputation &prec_P1, 54 | const mnt6_affine_ate_G2_precomputation &prec_Q1, 55 | const mnt6_affine_ate_G1_precomputation &prec_P2, 56 | const mnt6_affine_ate_G2_precomputation &prec_Q2, 57 | const mnt6_affine_ate_G1_precomputation &prec_P3, 58 | const mnt6_affine_ate_G2_precomputation &prec_Q3); 59 | static mnt6_Fq6 double_miller_loop(const mnt6_G1_precomp &prec_P1, 60 | const mnt6_G2_precomp &prec_Q1, 61 | const mnt6_G1_precomp &prec_P2, 62 | const mnt6_G2_precomp &prec_Q2); 63 | 64 | /* the following are used in test files */ 65 | static mnt6_Fq6 pairing(const mnt6_G1 &P, 66 | const mnt6_G2 &Q); 67 | static mnt6_Fq6 reduced_pairing(const mnt6_G1 &P, 68 | const mnt6_G2 &Q); 69 | static mnt6_Fq6 affine_reduced_pairing(const mnt6_G1 &P, 70 | const mnt6_G2 &Q); 71 | }; 72 | 73 | } // namespace libff 74 | 75 | #endif // MNT6_PP_HPP_ 76 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt4/mnt4_pp.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Declaration of interfaces for public parameters of MNT4. 5 | 6 | ***************************************************************************** 7 | * @author This file is part of libff, developed by SCIPR Lab 8 | * and contributors (see AUTHORS). 9 | * @copyright MIT license (see LICENSE file) 10 | *****************************************************************************/ 11 | 12 | #ifndef MNT4_PP_HPP_ 13 | #define MNT4_PP_HPP_ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace libff { 22 | 23 | class mnt4_pp { 24 | public: 25 | typedef mnt4_Fr Fp_type; 26 | typedef mnt4_G1 G1_type; 27 | typedef mnt4_G2 G2_type; 28 | typedef mnt4_G1_precomp G1_precomp_type; 29 | typedef mnt4_G2_precomp G2_precomp_type; 30 | typedef mnt4_affine_ate_G1_precomputation affine_ate_G1_precomp_type; 31 | typedef mnt4_affine_ate_G2_precomputation affine_ate_G2_precomp_type; 32 | typedef mnt4_Fq Fq_type; 33 | typedef mnt4_Fq2 Fqe_type; 34 | typedef mnt4_Fq4 Fqk_type; 35 | typedef mnt4_GT GT_type; 36 | 37 | static const bool has_affine_pairing = true; 38 | 39 | static void init_public_params(); 40 | static mnt4_GT final_exponentiation(const mnt4_Fq4 &elt); 41 | 42 | static mnt4_G1_precomp precompute_G1(const mnt4_G1 &P); 43 | static mnt4_G2_precomp precompute_G2(const mnt4_G2 &Q); 44 | 45 | static mnt4_Fq4 miller_loop(const mnt4_G1_precomp &prec_P, 46 | const mnt4_G2_precomp &prec_Q); 47 | 48 | static mnt4_affine_ate_G1_precomputation affine_ate_precompute_G1(const mnt4_G1 &P); 49 | static mnt4_affine_ate_G2_precomputation affine_ate_precompute_G2(const mnt4_G2 &Q); 50 | static mnt4_Fq4 affine_ate_miller_loop(const mnt4_affine_ate_G1_precomputation &prec_P, 51 | const mnt4_affine_ate_G2_precomputation &prec_Q); 52 | 53 | static mnt4_Fq4 affine_ate_e_over_e_miller_loop(const mnt4_affine_ate_G1_precomputation &prec_P1, 54 | const mnt4_affine_ate_G2_precomputation &prec_Q1, 55 | const mnt4_affine_ate_G1_precomputation &prec_P2, 56 | const mnt4_affine_ate_G2_precomputation &prec_Q2); 57 | static mnt4_Fq4 affine_ate_e_times_e_over_e_miller_loop(const mnt4_affine_ate_G1_precomputation &prec_P1, 58 | const mnt4_affine_ate_G2_precomputation &prec_Q1, 59 | const mnt4_affine_ate_G1_precomputation &prec_P2, 60 | const mnt4_affine_ate_G2_precomputation &prec_Q2, 61 | const mnt4_affine_ate_G1_precomputation &prec_P3, 62 | const mnt4_affine_ate_G2_precomputation &prec_Q3); 63 | 64 | static mnt4_Fq4 double_miller_loop(const mnt4_G1_precomp &prec_P1, 65 | const mnt4_G2_precomp &prec_Q1, 66 | const mnt4_G1_precomp &prec_P2, 67 | const mnt4_G2_precomp &prec_Q2); 68 | 69 | /* the following are used in test files */ 70 | static mnt4_Fq4 pairing(const mnt4_G1 &P, 71 | const mnt4_G2 &Q); 72 | static mnt4_Fq4 reduced_pairing(const mnt4_G1 &P, 73 | const mnt4_G2 &Q); 74 | static mnt4_Fq4 affine_reduced_pairing(const mnt4_G1 &P, 75 | const mnt4_G2 &Q); 76 | }; 77 | 78 | } // namespace libff 79 | 80 | #endif // MNT4_PP_HPP_ 81 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/gf64.hpp: -------------------------------------------------------------------------------- 1 | /**@file 2 | ***************************************************************************** 3 | Declaration of GF(2^64) finite field. 4 | ***************************************************************************** 5 | * @author This file is part of libff (see AUTHORS), migrated from libiop 6 | * @copyright MIT license (see LICENSE file) 7 | *****************************************************************************/ 8 | 9 | #ifndef LIBFF_ALGEBRA_GF64_HPP_ 10 | #define LIBFF_ALGEBRA_GF64_HPP_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace libff { 18 | 19 | /* gf64 implements the field GF(2)/[x^64 + x^4 + x^3 + x + 1]. 20 | Elements are represented internally with a single uint64 */ 21 | class gf64 { 22 | public: 23 | #ifdef PROFILE_OP_COUNTS // NOTE: op counts are affected when you exponentiate with ^ 24 | static long long add_cnt; 25 | static long long sub_cnt; 26 | static long long mul_cnt; 27 | static long long sqr_cnt; 28 | static long long inv_cnt; 29 | #endif 30 | // x^64 + x^4 + x^3 + x + 1. The assembly code assumes that no term other 31 | // than x^64 is greater than x^31, to enable faster multiplication. 32 | static const constexpr uint64_t modulus_ = 0b11011; 33 | static const constexpr uint64_t num_bits = 64; 34 | 35 | explicit gf64(); 36 | explicit gf64(const uint64_t value); 37 | 38 | gf64& operator+=(const gf64 &other); 39 | gf64& operator-=(const gf64 &other); 40 | gf64& operator*=(const gf64 &other); 41 | gf64& operator^=(const unsigned long pow); 42 | template 43 | gf64& operator^=(const bigint &pow); 44 | 45 | gf64& square(); 46 | gf64& invert(); 47 | 48 | gf64 operator+(const gf64 &other) const; 49 | gf64 operator-(const gf64 &other) const; 50 | gf64 operator-() const; 51 | gf64 operator*(const gf64 &other) const; 52 | gf64 operator^(const unsigned long pow) const; 53 | template 54 | gf64 operator^(const bigint &pow) const; 55 | 56 | gf64 squared() const; 57 | gf64 inverse() const; 58 | gf64 sqrt() const; 59 | 60 | void randomize(); 61 | void clear(); 62 | 63 | bool operator==(const gf64 &other) const; 64 | bool operator!=(const gf64 &other) const; 65 | 66 | bool is_zero() const; 67 | 68 | void print() const; 69 | /** 70 | * Returns the constituent bits in 64 bit words, in little-endian order. 71 | * Only the right-most ceil_size_in_bits() bits are used; other bits are 0. 72 | */ 73 | std::vector to_words() const; 74 | /** 75 | * Sets the field element from the given bits in 64 bit words, in little-endian order. 76 | * Only the right-most ceil_size_in_bits() bits are used; other bits are ignored. 77 | * Should always return true since the right-most bits are always valid. 78 | */ 79 | bool from_words(std::vector words); 80 | 81 | static gf64 random_element(); 82 | 83 | static gf64 zero(); 84 | static gf64 one(); 85 | static gf64 multiplicative_generator; // generator of gf64^* 86 | 87 | static std::size_t ceil_size_in_bits() { return num_bits; } 88 | static std::size_t floor_size_in_bits() { return num_bits; } 89 | static constexpr std::size_t extension_degree() { return 64; } 90 | template 91 | static constexpr bigint field_char() { return bigint(2); } 92 | 93 | friend std::ostream& operator<<(std::ostream &out, const gf64 &el); 94 | friend std::istream& operator>>(std::istream &in, gf64 &el); 95 | private: 96 | uint64_t value_; 97 | }; 98 | 99 | #ifdef PROFILE_OP_COUNTS 100 | long long gf64::add_cnt = 0; 101 | long long gf64::sub_cnt = 0; 102 | long long gf64::mul_cnt = 0; 103 | long long gf64::sqr_cnt = 0; 104 | long long gf64::inv_cnt = 0; 105 | #endif 106 | 107 | } // namespace libff 108 | #include 109 | 110 | #endif // namespace libff_ALGEBRA_GF64_HPP_ 111 | -------------------------------------------------------------------------------- /libff/algebra/curves/bn128/bn128_fields.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #include 9 | 10 | namespace libff { 11 | 12 | bigint bn128_modulus_r; 13 | bigint bn128_modulus_q; 14 | 15 | void init_bn128_fields() 16 | { 17 | bn::Param::init(); // init ate-pairing library 18 | 19 | using bigint_r = bigint; 20 | using bigint_q = bigint; 21 | 22 | assert(sizeof(mp_limb_t) == 8 || sizeof(mp_limb_t) == 4); // Montgomery assumes this 23 | 24 | /* parameters for scalar field Fr */ 25 | bn128_modulus_r = bigint_r("21888242871839275222246405745257275088548364400416034343698204186575808495617"); 26 | assert(bn128_Fr::modulus_is_valid()); 27 | if (sizeof(mp_limb_t) == 8) 28 | { 29 | bn128_Fr::Rsquared = bigint_r("944936681149208446651664254269745548490766851729442924617792859073125903783"); 30 | bn128_Fr::Rcubed = bigint_r("5866548545943845227489894872040244720403868105578784105281690076696998248512"); 31 | bn128_Fr::inv = 0xc2e1f593efffffff; 32 | } 33 | if (sizeof(mp_limb_t) == 4) 34 | { 35 | bn128_Fr::Rsquared = bigint_r("944936681149208446651664254269745548490766851729442924617792859073125903783"); 36 | bn128_Fr::Rcubed = bigint_r("5866548545943845227489894872040244720403868105578784105281690076696998248512"); 37 | bn128_Fr::inv = 0xefffffff; 38 | } 39 | bn128_Fr::num_bits = 254; 40 | bn128_Fr::euler = bigint_r("10944121435919637611123202872628637544274182200208017171849102093287904247808"); 41 | bn128_Fr::s = 28; 42 | bn128_Fr::t = bigint_r("81540058820840996586704275553141814055101440848469862132140264610111"); 43 | bn128_Fr::t_minus_1_over_2 = bigint_r("40770029410420498293352137776570907027550720424234931066070132305055"); 44 | bn128_Fr::multiplicative_generator = bn128_Fr("5"); 45 | bn128_Fr::root_of_unity = bn128_Fr("19103219067921713944291392827692070036145651957329286315305642004821462161904"); 46 | bn128_Fr::nqr = bn128_Fr("5"); 47 | bn128_Fr::nqr_to_t = bn128_Fr("19103219067921713944291392827692070036145651957329286315305642004821462161904"); 48 | 49 | /* parameters for base field Fq */ 50 | bn128_modulus_q = bigint_q("21888242871839275222246405745257275088696311157297823662689037894645226208583"); 51 | assert(bn128_Fq::modulus_is_valid()); 52 | if (sizeof(mp_limb_t) == 8) 53 | { 54 | bn128_Fq::Rsquared = bigint_q("3096616502983703923843567936837374451735540968419076528771170197431451843209"); 55 | bn128_Fq::Rcubed = bigint_q("14921786541159648185948152738563080959093619838510245177710943249661917737183"); 56 | bn128_Fq::inv = 0x87d20782e4866389; 57 | } 58 | if (sizeof(mp_limb_t) == 4) 59 | { 60 | bn128_Fq::Rsquared = bigint_q("3096616502983703923843567936837374451735540968419076528771170197431451843209"); 61 | bn128_Fq::Rcubed = bigint_q("14921786541159648185948152738563080959093619838510245177710943249661917737183"); 62 | bn128_Fq::inv = 0xe4866389; 63 | } 64 | bn128_Fq::num_bits = 254; 65 | bn128_Fq::euler = bigint_q("10944121435919637611123202872628637544348155578648911831344518947322613104291"); 66 | bn128_Fq::s = 1; 67 | bn128_Fq::t = bigint_q("10944121435919637611123202872628637544348155578648911831344518947322613104291"); 68 | bn128_Fq::t_minus_1_over_2 = bigint_q("5472060717959818805561601436314318772174077789324455915672259473661306552145"); 69 | bn128_Fq::multiplicative_generator = bn128_Fq("3"); 70 | bn128_Fq::root_of_unity = bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); 71 | bn128_Fq::nqr = bn128_Fq("3"); 72 | bn128_Fq::nqr_to_t = bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); 73 | } 74 | 75 | } // namespace libff 76 | -------------------------------------------------------------------------------- /libff/algebra/fields/field.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of common API for all finite fields. 4 | 5 | Currently NOT used by the fields in this library. This class is not actually 6 | the parent class of any field. All APIs are enforced through tests instead. 7 | 8 | The reason for this is to ensure high performance of all fields. This class 9 | exists as documentation for common API between fields. 10 | 11 | Includes two types of fields, F[p^n] for selected n and F[2^n] for a separate 12 | range of n. All of these finite fields must implement all functions declared 13 | in this class. 14 | ***************************************************************************** 15 | * @author This file is part of libff, developed by SCIPR Lab 16 | * and contributors (see AUTHORS). 17 | * @copyright MIT license (see LICENSE file) 18 | *****************************************************************************/ 19 | #include 20 | #include 21 | 22 | namespace libff { 23 | 24 | template 25 | class Field; 26 | 27 | /* The type parameter T is intended to be set to the child class 28 | when this class is extended. For example, 29 | class Fp_model : public Field ... */ 30 | template 31 | class Field { 32 | public: 33 | #ifdef PROFILE_OP_COUNTS // NOTE: op counts are affected when you exponentiate with ^ 34 | static long long add_cnt; 35 | static long long sub_cnt; 36 | static long long mul_cnt; 37 | static long long sqr_cnt; 38 | static long long inv_cnt; 39 | #endif 40 | 41 | virtual T& operator+=(const T& other) = 0; 42 | virtual T& operator-=(const T& other) = 0; 43 | virtual T& operator*=(const T& other) = 0; 44 | virtual T& operator^=(const unsigned long pow) = 0; 45 | template 46 | virtual T& operator^=(const bigint &pow) = 0; 47 | 48 | virtual T& square() = 0; 49 | virtual T& invert() = 0; 50 | 51 | virtual T operator+(const T& other) const; 52 | virtual T operator-(const T& other) const; 53 | virtual T operator*(const T& other) const; 54 | virtual T operator-() const = 0; 55 | 56 | virtual T squared() const; 57 | virtual T inverse() const; 58 | /** HAS TO BE A SQUARE (else does not terminate). */ 59 | virtual T sqrt() const = 0; 60 | 61 | virtual T operator^(const unsigned long pow) const; 62 | template 63 | virtual T operator^(const bigint &pow) const; 64 | 65 | bool operator==(const T& other) const = 0; 66 | bool operator!=(const T& other) const = 0; 67 | bool is_zero() const = 0; 68 | 69 | void print() const = 0; 70 | /** 71 | * Returns the constituent bits in 64 bit words, in little-endian order. 72 | * Only the right-most ceil_size_in_bits() bits are used; other bits are 0. 73 | */ 74 | std::vector to_words() const = 0; 75 | /** 76 | * Sets the field element from the given bits in 64 bit words, in little-endian order. 77 | * Only the right-most ceil_size_in_bits() bits are used; other bits are ignored. 78 | * Returns true when the right-most bits represent a value less than the modulus. 79 | */ 80 | bool from_words(std::vector words) = 0; 81 | 82 | void randomize() = 0; 83 | void clear() = 0; 84 | 85 | /* The static functions should be defined in field classes, but are static so they 86 | can't be inherited. */ 87 | static T zero(); 88 | static T one(); 89 | static T random_element(); 90 | /** Equals 1 for prime field Fp. */ 91 | static constexpr std::size_t extension_degree(); 92 | static std::size_t ceil_size_in_bits(); 93 | static std::size_t floor_size_in_bits(); 94 | 95 | // the following should be defined as well but can't be inherited; 96 | // make sure binary and prime never serialize to same thing 97 | friend std::ostream& operator<<(std::ostream &out, const T &p); 98 | friend std::istream& operator>>(std::istream &in, T &p); 99 | 100 | }; 101 | 102 | } // namespace libff 103 | -------------------------------------------------------------------------------- /libff/common/utils.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of miscellaneous math, serialization, and other common utility 4 | functions. 5 | ***************************************************************************** 6 | * @author This file is part of libff, developed by SCIPR Lab 7 | * and contributors (see AUTHORS). 8 | * @copyright MIT license (see LICENSE file) 9 | *****************************************************************************/ 10 | #ifndef UTILS_HPP_ 11 | #define UTILS_HPP_ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace libff { 20 | 21 | typedef std::vector bit_vector; 22 | 23 | template 24 | struct enable_if { typedef void* type; }; 25 | 26 | template 27 | struct enable_if { typedef T type; }; 28 | 29 | std::size_t get_power_of_two(std::size_t n); 30 | 31 | std::size_t round_to_next_power_of_2(const std::size_t n); 32 | bool is_power_of_2(const std::size_t n); 33 | 34 | /// returns ceil(log2(n)), so 1ul< &l, const std::size_t wordsize); 44 | /* throws error if y = 0 */ 45 | long long div_ceil(long long x, long long y); 46 | 47 | bool is_little_endian(); 48 | 49 | std::string FORMAT(const std::string &prefix, const char* format, ...); 50 | 51 | /* A variadic template to suppress unused argument warnings */ 52 | template 53 | void UNUSED(Types&&...) {} 54 | 55 | #ifdef DEBUG 56 | #define FMT libff::FORMAT 57 | #else 58 | #define FMT(...) (libff::UNUSED(__VA_ARGS__), "") 59 | #endif 60 | 61 | void serialize_bit_vector(std::ostream &out, const bit_vector &v); 62 | void deserialize_bit_vector(std::istream &in, bit_vector &v); 63 | 64 | /** Should not be used for fields, because the field function is named ceil_size_in_bits instead. */ 65 | template 66 | std::size_t curve_size_in_bits(const std::vector &v); 67 | 68 | /* Print a vector in the form { elem0 elem1 elem2 ... }, with a newline at the end 69 | template 70 | void print_vector(std::vector &vec); 71 | template 72 | void print_vector(std::vector vec);*/ 73 | 74 | template 75 | void print_vector(std::vector &vec) 76 | { 77 | printf("{ "); 78 | for (auto const& elem : vec) 79 | { 80 | std::cout << elem << " "; 81 | } 82 | printf("}\n"); 83 | } 84 | 85 | template 86 | void print_vector(std::vector vec) 87 | { 88 | printf("{ "); 89 | for (auto const& elem : vec) 90 | { 91 | std::cout << elem << " "; 92 | } 93 | printf("}\n"); 94 | } 95 | 96 | /** 97 | * Returns a random element of T that is not zero or one. 98 | * T can be a field or elliptic curve group. 99 | * Used for testing to generate a test example that doesn't error. 100 | */ 101 | template 102 | T random_element_non_zero_one(); 103 | /** 104 | * Returns a random element of T that is not zero. 105 | * T can be a field or elliptic curve group. 106 | * Used for testing to generate a test example that doesn't error. 107 | */ 108 | template 109 | T random_element_non_zero(); 110 | /** 111 | * Returns a random element of T that is not equal to y. 112 | * T can be a field or elliptic curve group. 113 | * Used for testing to generate a test example that doesn't error. 114 | */ 115 | template 116 | T random_element_exclude(T y); 117 | 118 | #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) 119 | 120 | } // namespace libff 121 | 122 | #include /* note that utils has a templatized part (utils.tcc) and non-templatized part (utils.cpp) */ 123 | #endif // UTILS_HPP_ 124 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/gf128.hpp: -------------------------------------------------------------------------------- 1 | /**@file 2 | ***************************************************************************** 3 | Declaration of GF(2^128) finite field. 4 | ***************************************************************************** 5 | * @author This file is part of libff (see AUTHORS), migrated from libiop 6 | * @copyright MIT license (see LICENSE file) 7 | *****************************************************************************/ 8 | 9 | #ifndef LIBFF_ALGEBRA_GF128_HPP_ 10 | #define LIBFF_ALGEBRA_GF128_HPP_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace libff { 18 | 19 | /* gf128 implements the field GF(2)/(x^128 + x^7 + x^2 + x + 1). 20 | Elements are represented internally with two uint64s */ 21 | class gf128 { 22 | public: 23 | #ifdef PROFILE_OP_COUNTS // NOTE: op counts are affected when you exponentiate with ^ 24 | static long long add_cnt; 25 | static long long sub_cnt; 26 | static long long mul_cnt; 27 | static long long sqr_cnt; 28 | static long long inv_cnt; 29 | #endif 30 | // x^128 + x^7 + x^2 + x + 1 31 | static const constexpr uint64_t modulus_ = 0b10000111; 32 | static const constexpr uint64_t num_bits = 128; 33 | 34 | explicit gf128(); 35 | /* we need a constructor that only initializes the low half of value_ to 36 | be able to do gf128(0) and gf128(1). */ 37 | explicit gf128(const uint64_t value_low); 38 | explicit gf128(const uint64_t value_high, const uint64_t value_low); 39 | 40 | gf128& operator+=(const gf128 &other); 41 | gf128& operator-=(const gf128 &other); 42 | gf128& operator*=(const gf128 &other); 43 | gf128& operator^=(const unsigned long pow); 44 | template 45 | gf128& operator^=(const bigint &pow); 46 | 47 | gf128& square(); 48 | gf128& invert(); 49 | 50 | gf128 operator+(const gf128 &other) const; 51 | gf128 operator-(const gf128 &other) const; 52 | gf128 operator-() const; 53 | gf128 operator*(const gf128 &other) const; 54 | gf128 operator^(const unsigned long pow) const; 55 | template 56 | gf128 operator^(const bigint &pow) const; 57 | 58 | gf128 squared() const; 59 | gf128 inverse() const; 60 | gf128 sqrt() const; 61 | 62 | void randomize(); 63 | void clear(); 64 | 65 | bool operator==(const gf128 &other) const; 66 | bool operator!=(const gf128 &other) const; 67 | 68 | bool is_zero() const; 69 | 70 | void print() const; 71 | /** 72 | * Returns the constituent bits in 64 bit words, in little-endian order. 73 | * Only the right-most ceil_size_in_bits() bits are used; other bits are 0. 74 | */ 75 | std::vector to_words() const; 76 | /** 77 | * Sets the field element from the given bits in 64 bit words, in little-endian order. 78 | * Only the right-most ceil_size_in_bits() bits are used; other bits are ignored. 79 | * Should always return true since the right-most bits are always valid. 80 | */ 81 | bool from_words(std::vector words); 82 | 83 | static gf128 random_element(); 84 | 85 | static gf128 zero(); 86 | static gf128 one(); 87 | static gf128 multiplicative_generator; // generator of gf128^* 88 | 89 | static std::size_t ceil_size_in_bits() { return num_bits; } 90 | static std::size_t floor_size_in_bits() { return num_bits; } 91 | static constexpr std::size_t extension_degree() { return 128; } 92 | template 93 | static constexpr bigint field_char() { return bigint(2); } 94 | 95 | friend std::ostream& operator<<(std::ostream &out, const gf128 &el); 96 | friend std::istream& operator>>(std::istream &in, gf128 &el); 97 | private: 98 | /* little-endian */ 99 | uint64_t value_[2]; 100 | }; 101 | 102 | #ifdef PROFILE_OP_COUNTS 103 | long long gf128::add_cnt = 0; 104 | long long gf128::sub_cnt = 0; 105 | long long gf128::mul_cnt = 0; 106 | long long gf128::sqr_cnt = 0; 107 | long long gf128::inv_cnt = 0; 108 | #endif 109 | 110 | } // namespace libff 111 | #include 112 | 113 | #endif // namespace libff_ALGEBRA_GF128_HPP_ 114 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt4/mnt4_pp.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Implementation of interfaces for public parameters of MNT4. 5 | 6 | See mnt4_pp.hpp . 7 | 8 | ***************************************************************************** 9 | * @author This file is part of libff, developed by SCIPR Lab 10 | * and contributors (see AUTHORS). 11 | * @copyright MIT license (see LICENSE file) 12 | *****************************************************************************/ 13 | 14 | #include 15 | 16 | namespace libff { 17 | 18 | void mnt4_pp::init_public_params() 19 | { 20 | init_mnt4_params(); 21 | } 22 | 23 | mnt4_GT mnt4_pp::final_exponentiation(const mnt4_Fq4 &elt) 24 | { 25 | return mnt4_final_exponentiation(elt); 26 | } 27 | 28 | mnt4_G1_precomp mnt4_pp::precompute_G1(const mnt4_G1 &P) 29 | { 30 | return mnt4_precompute_G1(P); 31 | } 32 | 33 | mnt4_G2_precomp mnt4_pp::precompute_G2(const mnt4_G2 &Q) 34 | { 35 | return mnt4_precompute_G2(Q); 36 | } 37 | 38 | mnt4_Fq4 mnt4_pp::miller_loop(const mnt4_G1_precomp &prec_P, 39 | const mnt4_G2_precomp &prec_Q) 40 | { 41 | return mnt4_miller_loop(prec_P, prec_Q); 42 | } 43 | 44 | mnt4_affine_ate_G1_precomputation mnt4_pp::affine_ate_precompute_G1(const mnt4_G1 &P) 45 | { 46 | return mnt4_affine_ate_precompute_G1(P); 47 | } 48 | 49 | mnt4_affine_ate_G2_precomputation mnt4_pp::affine_ate_precompute_G2(const mnt4_G2 &Q) 50 | { 51 | return mnt4_affine_ate_precompute_G2(Q); 52 | } 53 | 54 | mnt4_Fq4 mnt4_pp::affine_ate_miller_loop(const mnt4_affine_ate_G1_precomputation &prec_P, 55 | const mnt4_affine_ate_G2_precomputation &prec_Q) 56 | { 57 | return mnt4_affine_ate_miller_loop(prec_P, prec_Q); 58 | } 59 | 60 | mnt4_Fq4 mnt4_pp::affine_ate_e_over_e_miller_loop(const mnt4_affine_ate_G1_precomputation &prec_P1, 61 | const mnt4_affine_ate_G2_precomputation &prec_Q1, 62 | const mnt4_affine_ate_G1_precomputation &prec_P2, 63 | const mnt4_affine_ate_G2_precomputation &prec_Q2) 64 | { 65 | return mnt4_affine_ate_miller_loop(prec_P1, prec_Q1) * mnt4_affine_ate_miller_loop(prec_P2, prec_Q2).unitary_inverse(); 66 | } 67 | 68 | mnt4_Fq4 mnt4_pp::affine_ate_e_times_e_over_e_miller_loop(const mnt4_affine_ate_G1_precomputation &prec_P1, 69 | const mnt4_affine_ate_G2_precomputation &prec_Q1, 70 | const mnt4_affine_ate_G1_precomputation &prec_P2, 71 | const mnt4_affine_ate_G2_precomputation &prec_Q2, 72 | const mnt4_affine_ate_G1_precomputation &prec_P3, 73 | const mnt4_affine_ate_G2_precomputation &prec_Q3) 74 | { 75 | return ((mnt4_affine_ate_miller_loop(prec_P1, prec_Q1) * mnt4_affine_ate_miller_loop(prec_P2, prec_Q2)) * 76 | mnt4_affine_ate_miller_loop(prec_P3, prec_Q3).unitary_inverse()); 77 | } 78 | 79 | mnt4_Fq4 mnt4_pp::double_miller_loop(const mnt4_G1_precomp &prec_P1, 80 | const mnt4_G2_precomp &prec_Q1, 81 | const mnt4_G1_precomp &prec_P2, 82 | const mnt4_G2_precomp &prec_Q2) 83 | { 84 | return mnt4_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); 85 | } 86 | 87 | mnt4_Fq4 mnt4_pp::pairing(const mnt4_G1 &P, 88 | const mnt4_G2 &Q) 89 | { 90 | return mnt4_pairing(P, Q); 91 | } 92 | 93 | mnt4_Fq4 mnt4_pp::reduced_pairing(const mnt4_G1 &P, 94 | const mnt4_G2 &Q) 95 | { 96 | return mnt4_reduced_pairing(P, Q); 97 | } 98 | 99 | mnt4_Fq4 mnt4_pp::affine_reduced_pairing(const mnt4_G1 &P, 100 | const mnt4_G2 &Q) 101 | { 102 | return mnt4_affine_reduced_pairing(P, Q); 103 | } 104 | 105 | } // namespace libff 106 | -------------------------------------------------------------------------------- /libff/algebra/curves/mnt/mnt6/mnt6_pp.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | 4 | Implementation of interfaces for public parameters of MNT6. 5 | 6 | See mnt6_pp.hpp . 7 | 8 | ***************************************************************************** 9 | * @author This file is part of libff, developed by SCIPR Lab 10 | * and contributors (see AUTHORS). 11 | * @copyright MIT license (see LICENSE file) 12 | *****************************************************************************/ 13 | 14 | #include 15 | 16 | namespace libff { 17 | 18 | void mnt6_pp::init_public_params() 19 | { 20 | init_mnt6_params(); 21 | } 22 | 23 | mnt6_GT mnt6_pp::final_exponentiation(const mnt6_Fq6 &elt) 24 | { 25 | return mnt6_final_exponentiation(elt); 26 | } 27 | 28 | mnt6_G1_precomp mnt6_pp::precompute_G1(const mnt6_G1 &P) 29 | { 30 | return mnt6_precompute_G1(P); 31 | } 32 | 33 | mnt6_G2_precomp mnt6_pp::precompute_G2(const mnt6_G2 &Q) 34 | { 35 | return mnt6_precompute_G2(Q); 36 | } 37 | 38 | 39 | mnt6_Fq6 mnt6_pp::miller_loop(const mnt6_G1_precomp &prec_P, 40 | const mnt6_G2_precomp &prec_Q) 41 | { 42 | return mnt6_miller_loop(prec_P, prec_Q); 43 | } 44 | 45 | mnt6_affine_ate_G1_precomputation mnt6_pp::affine_ate_precompute_G1(const mnt6_G1 &P) 46 | { 47 | return mnt6_affine_ate_precompute_G1(P); 48 | } 49 | 50 | mnt6_affine_ate_G2_precomputation mnt6_pp::affine_ate_precompute_G2(const mnt6_G2 &Q) 51 | { 52 | return mnt6_affine_ate_precompute_G2(Q); 53 | } 54 | 55 | mnt6_Fq6 mnt6_pp::affine_ate_miller_loop(const mnt6_affine_ate_G1_precomputation &prec_P, 56 | const mnt6_affine_ate_G2_precomputation &prec_Q) 57 | { 58 | return mnt6_affine_ate_miller_loop(prec_P, prec_Q); 59 | } 60 | 61 | mnt6_Fq6 mnt6_pp::double_miller_loop(const mnt6_G1_precomp &prec_P1, 62 | const mnt6_G2_precomp &prec_Q1, 63 | const mnt6_G1_precomp &prec_P2, 64 | const mnt6_G2_precomp &prec_Q2) 65 | { 66 | return mnt6_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); 67 | } 68 | 69 | mnt6_Fq6 mnt6_pp::affine_ate_e_over_e_miller_loop(const mnt6_affine_ate_G1_precomputation &prec_P1, 70 | const mnt6_affine_ate_G2_precomputation &prec_Q1, 71 | const mnt6_affine_ate_G1_precomputation &prec_P2, 72 | const mnt6_affine_ate_G2_precomputation &prec_Q2) 73 | { 74 | return mnt6_affine_ate_miller_loop(prec_P1, prec_Q1) * mnt6_affine_ate_miller_loop(prec_P2, prec_Q2).unitary_inverse(); 75 | } 76 | 77 | mnt6_Fq6 mnt6_pp::affine_ate_e_times_e_over_e_miller_loop(const mnt6_affine_ate_G1_precomputation &prec_P1, 78 | const mnt6_affine_ate_G2_precomputation &prec_Q1, 79 | const mnt6_affine_ate_G1_precomputation &prec_P2, 80 | const mnt6_affine_ate_G2_precomputation &prec_Q2, 81 | const mnt6_affine_ate_G1_precomputation &prec_P3, 82 | const mnt6_affine_ate_G2_precomputation &prec_Q3) 83 | { 84 | return ((mnt6_affine_ate_miller_loop(prec_P1, prec_Q1) * mnt6_affine_ate_miller_loop(prec_P2, prec_Q2)) * 85 | mnt6_affine_ate_miller_loop(prec_P3, prec_Q3).unitary_inverse()); 86 | } 87 | 88 | mnt6_Fq6 mnt6_pp::pairing(const mnt6_G1 &P, 89 | const mnt6_G2 &Q) 90 | { 91 | return mnt6_pairing(P, Q); 92 | } 93 | 94 | mnt6_Fq6 mnt6_pp::reduced_pairing(const mnt6_G1 &P, 95 | const mnt6_G2 &Q) 96 | { 97 | return mnt6_reduced_pairing(P, Q); 98 | } 99 | 100 | mnt6_Fq6 mnt6_pp::affine_reduced_pairing(const mnt6_G1 &P, 101 | const mnt6_G2 &Q) 102 | { 103 | return mnt6_affine_reduced_pairing(P, Q); 104 | } 105 | 106 | } // namespace libff 107 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/gf192.hpp: -------------------------------------------------------------------------------- 1 | /**@file 2 | ***************************************************************************** 3 | Declaration of GF(2^192) finite field. 4 | ***************************************************************************** 5 | * @author This file is part of libff (see AUTHORS), migrated from libiop 6 | * @copyright MIT license (see LICENSE file) 7 | *****************************************************************************/ 8 | 9 | #ifndef LIBFF_ALGEBRA_GF192_HPP_ 10 | #define LIBFF_ALGEBRA_GF192_HPP_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace libff { 18 | 19 | /* gf192 implements the field GF(2)/(x^192 + x^7 + x^2 + x + 1). 20 | Elements are represented internally with three uint64s */ 21 | class gf192 { 22 | public: 23 | #ifdef PROFILE_OP_COUNTS // NOTE: op counts are affected when you exponentiate with ^ 24 | static long long add_cnt; 25 | static long long sub_cnt; 26 | static long long mul_cnt; 27 | static long long sqr_cnt; 28 | static long long inv_cnt; 29 | #endif 30 | // x^192 + x^7 + x^2 + x + 1 31 | static const constexpr uint64_t modulus_ = 0b10000111; 32 | static const constexpr uint64_t num_bits = 192; 33 | 34 | explicit gf192(); 35 | /* we need a constructor that only initializes the low half of value_ to 36 | be able to do gf192(0) and gf192(1). */ 37 | explicit gf192(const uint64_t value_low); 38 | explicit gf192(const uint64_t value_high, const uint64_t value_mid, const uint64_t value_low); 39 | 40 | gf192& operator+=(const gf192 &other); 41 | gf192& operator-=(const gf192 &other); 42 | gf192& operator*=(const gf192 &other); 43 | gf192& operator^=(const unsigned long pow); 44 | template 45 | gf192& operator^=(const bigint &pow); 46 | 47 | gf192& square(); 48 | gf192& invert(); 49 | 50 | gf192 operator+(const gf192 &other) const; 51 | gf192 operator-(const gf192 &other) const; 52 | gf192 operator-() const; 53 | gf192 operator*(const gf192 &other) const; 54 | gf192 operator^(const unsigned long pow) const; 55 | template 56 | gf192 operator^(const bigint &pow) const; 57 | 58 | gf192 squared() const; 59 | gf192 inverse() const; 60 | gf192 sqrt() const; 61 | /** 62 | * Returns the constituent bits in 64 bit words, in little-endian order. 63 | * Only the right-most ceil_size_in_bits() bits are used; other bits are 0. 64 | */ 65 | std::vector to_words() const; 66 | /** 67 | * Sets the field element from the given bits in 64 bit words, in little-endian order. 68 | * Only the right-most ceil_size_in_bits() bits are used; other bits are ignored. 69 | * Should always return true since the right-most bits are always valid. 70 | */ 71 | bool from_words(std::vector words); 72 | 73 | void randomize(); 74 | void clear(); 75 | 76 | bool operator==(const gf192 &other) const; 77 | bool operator!=(const gf192 &other) const; 78 | 79 | bool is_zero() const; 80 | 81 | void print() const; 82 | 83 | static gf192 random_element(); 84 | 85 | static gf192 zero(); 86 | static gf192 one(); 87 | static gf192 multiplicative_generator; // generator of gf192^* 88 | 89 | static std::size_t ceil_size_in_bits() { return num_bits; } 90 | static std::size_t floor_size_in_bits() { return num_bits; } 91 | static constexpr std::size_t extension_degree() { return 192; } 92 | template 93 | static constexpr bigint field_char() { return bigint(2); } 94 | 95 | friend std::ostream& operator<<(std::ostream &out, const gf192 &el); 96 | friend std::istream& operator>>(std::istream &in, gf192 &el); 97 | private: 98 | /* little-endian */ 99 | uint64_t value_[3]; 100 | }; 101 | 102 | #ifdef PROFILE_OP_COUNTS 103 | long long gf192::add_cnt = 0; 104 | long long gf192::sub_cnt = 0; 105 | long long gf192::mul_cnt = 0; 106 | long long gf192::sqr_cnt = 0; 107 | long long gf192::inv_cnt = 0; 108 | #endif 109 | 110 | } // namespace libff 111 | #include 112 | 113 | #endif // namespace libff_ALGEBRA_GF192_HPP_ 114 | -------------------------------------------------------------------------------- /libff/algebra/fields/binary/gf256.hpp: -------------------------------------------------------------------------------- 1 | /**@file 2 | ***************************************************************************** 3 | Declaration of GF(2^256) finite field. 4 | ***************************************************************************** 5 | * @author This file is part of libff (see AUTHORS), migrated from libiop 6 | * @copyright MIT license (see LICENSE file) 7 | *****************************************************************************/ 8 | 9 | #ifndef LIBFF_ALGEBRA_GF256_HPP_ 10 | #define LIBFF_ALGEBRA_GF256_HPP_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace libff { 18 | 19 | /* x^256 + x^10 + x^5 + x^2 + 1 */ 20 | /* gf256 implements the field GF(2)/(x^256 + x^10 + x^5 + x^2 + 1). 21 | Elements are represented internally with four uint64s */ 22 | class gf256 { 23 | public: 24 | #ifdef PROFILE_OP_COUNTS // NOTE: op counts are affected when you exponentiate with ^ 25 | static long long add_cnt; 26 | static long long sub_cnt; 27 | static long long mul_cnt; 28 | static long long sqr_cnt; 29 | static long long inv_cnt; 30 | #endif 31 | // x^256 + x^10 + x^5 + x^2 + 1 32 | static const constexpr uint64_t modulus_ = 0b10000100101; 33 | static const constexpr uint64_t num_bits = 256; 34 | 35 | explicit gf256(); 36 | /* we need a constructor that only initializes the low 64 bits of value_ to 37 | be able to do gf256(0) and gf256(1). */ 38 | explicit gf256(const uint64_t value_low); 39 | explicit gf256(const uint64_t value_high, const uint64_t value_midh, 40 | const uint64_t value_midl, const uint64_t value_low); 41 | 42 | gf256& operator+=(const gf256 &other); 43 | gf256& operator-=(const gf256 &other); 44 | gf256& operator*=(const gf256 &other); 45 | gf256& operator^=(const unsigned long pow); 46 | template 47 | gf256& operator^=(const bigint &pow); 48 | 49 | gf256& square(); 50 | gf256& invert(); 51 | 52 | gf256 operator+(const gf256 &other) const; 53 | gf256 operator-(const gf256 &other) const; 54 | gf256 operator-() const; 55 | gf256 operator*(const gf256 &other) const; 56 | gf256 operator^(const unsigned long pow) const; 57 | template 58 | gf256 operator^(const bigint &pow) const; 59 | 60 | gf256 squared() const; 61 | gf256 inverse() const; 62 | gf256 sqrt() const; 63 | 64 | void randomize(); 65 | void clear(); 66 | 67 | bool operator==(const gf256 &other) const; 68 | bool operator!=(const gf256 &other) const; 69 | 70 | bool is_zero() const; 71 | 72 | void print() const; 73 | /** 74 | * Returns the constituent bits in 64 bit words, in little-endian order. 75 | * Only the right-most ceil_size_in_bits() bits are used; other bits are 0. 76 | */ 77 | std::vector to_words() const; 78 | /** 79 | * Sets the field element from the given bits in 64 bit words, in little-endian order. 80 | * Only the right-most ceil_size_in_bits() bits are used; other bits are ignored. 81 | * Should always return true since the right-most bits are always valid. 82 | */ 83 | bool from_words(std::vector words); 84 | 85 | static gf256 random_element(); 86 | 87 | static gf256 zero(); 88 | static gf256 one(); 89 | static gf256 multiplicative_generator; // generator of gf256^* 90 | 91 | static std::size_t ceil_size_in_bits() { return num_bits; } 92 | static std::size_t floor_size_in_bits() { return num_bits; } 93 | static constexpr std::size_t extension_degree() { return 256; } 94 | template 95 | static constexpr bigint field_char() { return bigint(2); } 96 | 97 | friend std::ostream& operator<<(std::ostream &out, const gf256 &el); 98 | friend std::istream& operator>>(std::istream &in, gf256 &el); 99 | private: 100 | /* little-endian */ 101 | uint64_t value_[4]; 102 | }; 103 | 104 | #ifdef PROFILE_OP_COUNTS 105 | long long gf256::add_cnt = 0; 106 | long long gf256::sub_cnt = 0; 107 | long long gf256::mul_cnt = 0; 108 | long long gf256::sqr_cnt = 0; 109 | long long gf256::inv_cnt = 0; 110 | #endif 111 | 112 | } // namespace libff 113 | #include 114 | 115 | #endif // namespace libff_ALGEBRA_GF256_HPP_ 116 | -------------------------------------------------------------------------------- /libff/algebra/curves/public_params.hpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | * @author This file is part of libff, developed by SCIPR Lab 4 | * and contributors (see AUTHORS). 5 | * @copyright MIT license (see LICENSE file) 6 | *****************************************************************************/ 7 | 8 | #ifndef PUBLIC_PARAMS_HPP_ 9 | #define PUBLIC_PARAMS_HPP_ 10 | #include 11 | 12 | namespace libff { 13 | 14 | /* 15 | for every curve the user should define corresponding 16 | public_params with the following typedefs: 17 | 18 | Fp_type 19 | G1_type 20 | G2_type 21 | G1_precomp_type 22 | G2_precomp_type 23 | affine_ate_G1_precomp_type 24 | affine_ate_G2_precomp_type 25 | Fq_type 26 | Fqe_type 27 | Fqk_type 28 | GT_type 29 | 30 | one should also define the following static methods: 31 | 32 | void init_public_params(); 33 | 34 | GT final_exponentiation(const Fqk &elt); 35 | 36 | G1_precomp precompute_G1(const G1 &P); 37 | G2_precomp precompute_G2(const G2 &Q); 38 | 39 | Fqk miller_loop(const G1_precomp &prec_P, 40 | const G2_precomp &prec_Q); 41 | 42 | affine_ate_G1_precomp affine_ate_precompute_G1(const G1 &P); 43 | affine_ate_G2_precomp affine_ate_precompute_G2(const G2 &Q); 44 | 45 | 46 | Fqk affine_ate_miller_loop(const affine_ate_G1_precomp &prec_P, 47 | const affine_ate_G2_precomp &prec_Q); 48 | Fqk affine_ate_e_over_e_miller_loop(const affine_ate_G1_precomp &prec_P1, 49 | const affine_ate_G2_precomp &prec_Q1, 50 | const affine_ate_G1_precomp &prec_P2, 51 | const affine_ate_G2_precomp &prec_Q2); 52 | Fqk affine_ate_e_times_e_over_e_miller_loop(const affine_ate_G1_precomp &prec_P1, 53 | const affine_ate_G2_precomp &prec_Q1, 54 | const affine_ate_G1_precomp &prec_P2, 55 | const affine_ate_G2_precomp &prec_Q2, 56 | const affine_ate_G1_precomp &prec_P3, 57 | const affine_ate_G2_precomp &prec_Q3); 58 | Fqk double_miller_loop(const G1_precomp &prec_P1, 59 | const G2_precomp &prec_Q1, 60 | const G1_precomp &prec_P2, 61 | const G2_precomp &prec_Q2); 62 | 63 | Fqk pairing(const G1 &P, 64 | const G2 &Q); 65 | GT reduced_pairing(const G1 &P, 66 | const G2 &Q); 67 | GT affine_reduced_pairing(const G1 &P, 68 | const G2 &Q); 69 | */ 70 | 71 | template 72 | using Fr = typename EC_ppT::Fp_type; 73 | template 74 | using G1 = typename EC_ppT::G1_type; 75 | template 76 | using G2 = typename EC_ppT::G2_type; 77 | template 78 | using G1_precomp = typename EC_ppT::G1_precomp_type; 79 | template 80 | using G2_precomp = typename EC_ppT::G2_precomp_type; 81 | template 82 | using affine_ate_G1_precomp = typename EC_ppT::affine_ate_G1_precomp_type; 83 | template 84 | using affine_ate_G2_precomp = typename EC_ppT::affine_ate_G2_precomp_type; 85 | template 86 | using Fq = typename EC_ppT::Fq_type; 87 | template 88 | using Fqe = typename EC_ppT::Fqe_type; 89 | template 90 | using Fqk = typename EC_ppT::Fqk_type; 91 | template 92 | using GT = typename EC_ppT::GT_type; 93 | 94 | template 95 | using Fr_vector = std::vector >; 96 | template 97 | using G1_vector = std::vector >; 98 | template 99 | using G2_vector = std::vector >; 100 | 101 | } // namespace libff 102 | 103 | #endif // PUBLIC_PARAMS_HPP_ 104 | -------------------------------------------------------------------------------- /libff/common/double.cpp: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Implementation of complex domain data type. 4 | ***************************************************************************** 5 | * @author This file is part of libff, developed by SCIPR Lab 6 | * and contributors (see AUTHORS). 7 | * @copyright MIT license (see LICENSE file) 8 | *****************************************************************************/ 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace libff { 18 | 19 | using std::size_t; 20 | 21 | Double::Double() 22 | { 23 | val = std::complex(0, 0); 24 | } 25 | 26 | Double::Double(double real) 27 | { 28 | val = std::complex(real, 0); 29 | } 30 | 31 | Double::Double(double real, double imag) 32 | { 33 | val = std::complex(real, imag); 34 | } 35 | 36 | Double::Double(std::complex num) 37 | { 38 | val = num; 39 | } 40 | 41 | unsigned Double::add_cnt = 0; 42 | unsigned Double::sub_cnt = 0; 43 | unsigned Double::mul_cnt = 0; 44 | unsigned Double::inv_cnt = 0; 45 | 46 | Double Double::operator+(const Double &other) const 47 | { 48 | #ifdef PROFILE_OP_COUNTS 49 | ++add_cnt; 50 | #endif 51 | 52 | return Double(val + other.val); 53 | } 54 | 55 | Double Double::operator-(const Double &other) const 56 | { 57 | #ifdef PROFILE_OP_COUNTS 58 | ++sub_cnt; 59 | #endif 60 | 61 | return Double(val - other.val); 62 | } 63 | 64 | Double Double::operator*(const Double &other) const 65 | { 66 | #ifdef PROFILE_OP_COUNTS 67 | ++mul_cnt; 68 | #endif 69 | 70 | return Double(val * other.val); 71 | } 72 | 73 | Double Double::operator-() const 74 | { 75 | if (val.imag() == 0) { 76 | return Double(-val.real()); 77 | } 78 | 79 | return Double(-val.real(), -val.imag()); 80 | } 81 | 82 | Double& Double::operator+=(const Double &other) 83 | { 84 | #ifdef PROFILE_OP_COUNTS 85 | ++add_cnt; 86 | #endif 87 | 88 | this->val = std::complex(val + other.val); 89 | return *this; 90 | } 91 | 92 | Double& Double::operator-=(const Double &other) 93 | { 94 | #ifdef PROFILE_OP_COUNTS 95 | ++sub_cnt; 96 | #endif 97 | 98 | this->val = std::complex(val - other.val); 99 | return *this; 100 | } 101 | 102 | Double& Double::operator*=(const Double &other) 103 | { 104 | #ifdef PROFILE_OP_COUNTS 105 | ++mul_cnt; 106 | #endif 107 | 108 | this->val *= std::complex(other.val); 109 | return *this; 110 | } 111 | 112 | bool Double::operator==(const Double &other) const 113 | { 114 | return (std::abs(val.real() - other.val.real()) < 0.000001) 115 | && (std::abs(val.imag() - other.val.imag()) < 0.000001); 116 | } 117 | 118 | bool Double::operator!=(const Double &other) const 119 | { 120 | return !(*this == other); 121 | } 122 | 123 | bool Double::operator<(const Double &other) const 124 | { 125 | return (val.real() < other.val.real()); 126 | } 127 | 128 | bool Double::operator>(const Double &other) const 129 | { 130 | return (val.real() > other.val.real()); 131 | } 132 | 133 | Double Double::operator^(const libff::bigint<1> power) const 134 | { 135 | return Double(pow(val, power.as_ulong())); 136 | } 137 | 138 | Double Double::operator^(const size_t power) const 139 | { 140 | return Double(pow(val, power)); 141 | } 142 | 143 | Double Double::inverse() const 144 | { 145 | #ifdef PROFILE_OP_COUNTS 146 | ++inv_cnt; 147 | #endif 148 | 149 | return Double(std::complex(1) / val); 150 | } 151 | 152 | libff::bigint<1> Double::as_bigint() const 153 | { 154 | return libff::bigint<1>((size_t) val.real()); 155 | } 156 | 157 | unsigned long Double::as_ulong() const 158 | { 159 | return round((size_t) val.real()); 160 | } 161 | 162 | Double Double::squared() const 163 | { 164 | return Double(val * val); 165 | } 166 | 167 | Double Double::one() 168 | { 169 | return Double(1); 170 | } 171 | 172 | Double Double::zero() 173 | { 174 | return Double(0); 175 | } 176 | 177 | Double Double::random_element() 178 | { 179 | return Double(std::rand() % 1001); 180 | } 181 | 182 | Double Double::geometric_generator() 183 | { 184 | return Double(2); 185 | } 186 | 187 | Double Double::arithmetic_generator() 188 | { 189 | return Double(1); 190 | } 191 | 192 | Double Double::multiplicative_generator = Double(2); 193 | 194 | } // namespace libff 195 | -------------------------------------------------------------------------------- /libff/algebra/field_utils/algorithms.tcc: -------------------------------------------------------------------------------- 1 | /** @file 2 | ***************************************************************************** 3 | Declaration of interfaces for (square-and-multiply) exponentiation and 4 | Tonelli-Shanks square root. 5 | ***************************************************************************** 6 | * @author This file is part of libff, developed by SCIPR Lab 7 | * and contributors (see AUTHORS). 8 | * @copyright MIT license (see LICENSE file) 9 | *****************************************************************************/ 10 | 11 | #ifndef ALGORITHMS_TCC_ 12 | #define ALGORITHMS_TCC_ 13 | 14 | #include "libff/common/utils.hpp" 15 | #include "libff/common/profiling.hpp" 16 | 17 | namespace libff { 18 | 19 | using std::size_t; 20 | 21 | template 22 | FieldT power(const FieldT &base, const bigint &exponent) 23 | { 24 | FieldT result = FieldT::one(); 25 | bool found_one = false; 26 | 27 | for (long i = exponent.max_bits() - 1; i >= 0; --i) 28 | { 29 | if (found_one) 30 | { 31 | result = result * result; 32 | } 33 | 34 | if (exponent.test_bit(i)) 35 | { 36 | found_one = true; 37 | result = result * base; 38 | } 39 | } 40 | 41 | return result; 42 | } 43 | 44 | template 45 | FieldT power(const FieldT &base, const unsigned long exponent) 46 | { 47 | return power(base, bigint<1>(exponent)); 48 | } 49 | 50 | template 51 | FieldT power(const FieldT &base, const unsigned long long exponent) 52 | { 53 | FieldT result = FieldT::one(); 54 | 55 | bool found_one = false; 56 | 57 | for (long i = 8 * sizeof(exponent) - 1; i >= 0; --i) 58 | { 59 | if (found_one) 60 | { 61 | result = result.squared(); 62 | } 63 | 64 | if (exponent & (1ull << i)) 65 | { 66 | found_one = true; 67 | result *= base; 68 | } 69 | } 70 | 71 | return result; 72 | } 73 | 74 | template 75 | FieldT power(const FieldT &base, const std::vector exponent) 76 | { 77 | FieldT result = FieldT::one(); 78 | 79 | bool found_one = false; 80 | 81 | for (unsigned long long j = 0; j < exponent.size(); j++) 82 | { 83 | unsigned long long cur_exp = exponent[j]; 84 | for (long i = 8 * sizeof(cur_exp) - 1; i >= 0; --i) 85 | { 86 | if (found_one) 87 | { 88 | result = result.squared(); 89 | } 90 | 91 | if (cur_exp & (1ull << i)) 92 | { 93 | found_one = true; 94 | result *= base; 95 | } 96 | } 97 | } 98 | 99 | return result; 100 | } 101 | 102 | template 103 | FieldT tonelli_shanks_sqrt(const FieldT &value) 104 | { 105 | // A few assertions to make sure s, t, and nqr are initialized. 106 | assert(FieldT::s != 0); 107 | assert(!FieldT::t.is_even()); // Check that t is odd. 108 | assert(!FieldT::nqr.is_zero()); 109 | 110 | if (value.is_zero()) 111 | { 112 | return FieldT::zero(); 113 | } 114 | 115 | FieldT one = FieldT::one(); 116 | 117 | size_t v = FieldT::s; 118 | FieldT z = FieldT::nqr_to_t; 119 | FieldT w = value^FieldT::t_minus_1_over_2; 120 | FieldT x = value * w; 121 | FieldT b = x * w; // b = value^t 122 | 123 | #if DEBUG 124 | // check if square with euler's criterion 125 | FieldT check = b; 126 | for (size_t i = 0; i < v-1; ++i) 127 | { 128 | check = check.squared(); 129 | } 130 | assert(check == one); 131 | #endif 132 | 133 | // compute square root with Tonelli--Shanks 134 | // (does not terminate if not a square!) 135 | 136 | while (b != one) 137 | { 138 | size_t m = 0; 139 | FieldT b2m = b; 140 | while (b2m != one) 141 | { 142 | /* invariant: b2m = b^(2^m) after entering this loop */ 143 | b2m = b2m.squared(); 144 | m += 1; 145 | } 146 | 147 | int j = v-m-1; 148 | w = z; 149 | while (j > 0) 150 | { 151 | w = w.squared(); 152 | --j; 153 | } // w = z^2^(v-m-1) 154 | 155 | z = w.squared(); 156 | b = b * z; 157 | x = x * w; 158 | v = m; 159 | } 160 | 161 | return x; 162 | } 163 | 164 | } // namespace libff 165 | 166 | #endif // ALGORITHMS_TCC_ 167 | --------------------------------------------------------------------------------