Skip to content

Commit

Permalink
Merge pull request #17 from AntelopeIO/c++20_update
Browse files Browse the repository at this point in the history
Update bn256 to `c++20`
  • Loading branch information
greg7mdp authored Aug 2, 2023
2 parents bec6883 + b4263f9 commit eae77bf
Show file tree
Hide file tree
Showing 15 changed files with 120 additions and 156 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ jobs:
- uses: actions/checkout@v2
with:
submodules: true
- name: 'setup'
if: contains(matrix.config.vm_image, '20.04')
run: |
sudo apt-get install -y g++-10 libstdc++-10-dev
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 100 \
--slave /usr/bin/gcc gcc /usr/bin/gcc-10
- name: 'configure'
run: |
cmake -DCMAKE_BUILD_TYPE=${{ matrix.config.mode }} -Bbuild -S.
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "third-party/Catch2"]
path = third-party/Catch2
url = https://github.com/catchorg/Catch2
[submodule "third-party/span"]
path = third-party/span
url = https://github.com/martinmoene/span-lite
21 changes: 9 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.8)
project(bn256 VERSION 1.0.0)
cmake_minimum_required(VERSION 3.12)

set(CMAKE_CXX_STANDARD 17)
project(bn256 VERSION 2.0.0)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_compile_options(-Wall)
Expand All @@ -18,14 +19,10 @@ if(BN256_ENABLE_TEST)
endif()

include(GNUInstallDirs)
set(version 1.0.0)
set_property(TARGET bn256 PROPERTY VERSION ${version})
set_property(TARGET bn256 PROPERTY SOVERSION 1)
set_property(TARGET bn256 PROPERTY
INTERFACE_bn256_MAJOR_VERSION 1)
set_property(TARGET bn256 APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING bn256_MAJOR_VERSION
)
set_property(TARGET bn256 PROPERTY VERSION ${bn256_VERSION})
set_property(TARGET bn256 PROPERTY SOVERSION ${bn256_VERSION_MAJOR})
set_property(TARGET bn256 PROPERTY INTERFACE_bn256_MAJOR_VERSION ${bn256_VERSION_MAJOR})
set_property(TARGET bn256 APPEND PROPERTY COMPATIBLE_INTERFACE_STRING bn256_MAJOR_VERSION)

install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(DIRECTORY third-party/span/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/bn256)
Expand Down Expand Up @@ -53,7 +50,7 @@ install(FILES

write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/bn256-config-version.cmake"
VERSION "${version}"
VERSION "${bn256_VERSION}"
COMPATIBILITY AnyNewerVersion
)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# BN256 Cryptographic Library
## Version : 1.0
## Version : 2.0

This library implements the bilinear group `BN256` in the C++ language. It is based off of the [cloudflare/bn256](https://github.com/ethereum/go-ethereum/tree/master/crypto/bn256/cloudflare) implementation.

Expand Down
2 changes: 1 addition & 1 deletion include/bn256/bn256.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <cstring>
#include <functional>
#include <cstdint>
#include <bn256/span.h>
#include <span>

namespace bn256 {

Expand Down
12 changes: 0 additions & 12 deletions include/bn256/span.h

This file was deleted.

81 changes: 20 additions & 61 deletions src/array.h
Original file line number Diff line number Diff line change
@@ -1,51 +1,10 @@
#pragma once
#include <cstddef>
#include <cstring>
#if __cplusplus > 201703L
#include <span>
#include <cstdint>
#include <tuple>
#include <array>
namespace bn256 {
template <typename T, std::size_t S>
using array = std::array<T, S>;
}
#else
#include <bn256/span.h>

namespace bn256 {
// std::array in C++17 cannot be used in constexpr context; therefore we rollout our own.
template <typename T, std::size_t N>
struct array {
T v_[N];
constexpr T& operator[](std::size_t i) noexcept { return v_[i]; }
constexpr const T& operator[](std::size_t i) const noexcept { return v_[i]; }
constexpr std::size_t size() const noexcept { return N; }
constexpr T* data() noexcept { return v_; }
constexpr const T* data() const noexcept { return v_; }

constexpr const T* begin() const noexcept { return v_; }
constexpr const T* end() const noexcept { return v_+N; }

constexpr bool operator==(const array<T, N>& other) const noexcept {
for (std::size_t i = 0; i < N; ++i)
if (v_[i] != other[i])
return false;
return true;
}

constexpr bool operator!=(const array& other) const noexcept { return !(*this == other); }

constexpr operator std::span<T,N> () noexcept {
return std::span<T,N> {v_};
}

constexpr operator std::span<const T,N> () const noexcept {
return std::span<const T,N> {v_};
}
};
} // namespace bn256
#endif
#include <span>
#include <cstdint>
#include <tuple>
#include <array>

namespace bn256 {
template <std::size_t N>
Expand All @@ -62,22 +21,22 @@ constexpr int bitlen(std::span<const uint64_t, N> a) {
return bit_length - __builtin_clzll(all_sign_bits == 0 ? a[i] : -a[i]);
}

static_assert(bitlen<4>(array<uint64_t,4>{0, 0, 0, 0x0FFFFFFFFFFFFFFF}) == 252);
static_assert(bitlen<4>(array<uint64_t,4>{0, 0, 0x0FFFFFFFFFFFFFFF, 0}) == 188);
static_assert(bitlen<4>(array<uint64_t,4>{0x0FFFFFFFFFFFFFFF, 0, 0, 0}) == 60);
static_assert(bitlen<4>(array<uint64_t,4>{0, 0, 0, 0x8FFFFFFFFFFFFFFF}) == 255);
static_assert(bitlen<4>(array<uint64_t,4>{0, 0, 0, 0x7FFFFFFFFFFFFFFF}) == 255);
static_assert(bitlen<4>(array<uint64_t,4>{0, 0, 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}) == 192);
static_assert(bitlen<4>(array<uint64_t,4>{0, 0, 0x7FFFFFFFFFFFFFFF, 0}) == 191);
static_assert(bitlen<4>(array<uint64_t,4>{0, 0, 0x8FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}) == 191);
static_assert(bitlen<4>(array<uint64_t,4>{0, 0, 0x8FFFFFFFFFFFFFFF, 0}) == 192);
static_assert(bitlen<4>(array<uint64_t,4>{0x7FFFFFFFFFFFFFFF, 0, 0, 0}) == 63);
static_assert(bitlen<4>(array<uint64_t,4>{0x8FFFFFFFFFFFFFFF, 0, 0, 0}) == 64);
static_assert(bitlen<4>(array<uint64_t,4>{0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}) == 64);
static_assert(bitlen<4>(array<uint64_t,4>{0x8FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}) == 63);
static_assert(bitlen<4>(array<uint64_t,4>{0, 0, 0, 0}) == 0);

constexpr int bitlen(const array<uint64_t, 4>& a) {
static_assert(bitlen<4>(std::array<uint64_t,4>{0, 0, 0, 0x0FFFFFFFFFFFFFFF}) == 252);
static_assert(bitlen<4>(std::array<uint64_t,4>{0, 0, 0x0FFFFFFFFFFFFFFF, 0}) == 188);
static_assert(bitlen<4>(std::array<uint64_t,4>{0x0FFFFFFFFFFFFFFF, 0, 0, 0}) == 60);
static_assert(bitlen<4>(std::array<uint64_t,4>{0, 0, 0, 0x8FFFFFFFFFFFFFFF}) == 255);
static_assert(bitlen<4>(std::array<uint64_t,4>{0, 0, 0, 0x7FFFFFFFFFFFFFFF}) == 255);
static_assert(bitlen<4>(std::array<uint64_t,4>{0, 0, 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}) == 192);
static_assert(bitlen<4>(std::array<uint64_t,4>{0, 0, 0x7FFFFFFFFFFFFFFF, 0}) == 191);
static_assert(bitlen<4>(std::array<uint64_t,4>{0, 0, 0x8FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}) == 191);
static_assert(bitlen<4>(std::array<uint64_t,4>{0, 0, 0x8FFFFFFFFFFFFFFF, 0}) == 192);
static_assert(bitlen<4>(std::array<uint64_t,4>{0x7FFFFFFFFFFFFFFF, 0, 0, 0}) == 63);
static_assert(bitlen<4>(std::array<uint64_t,4>{0x8FFFFFFFFFFFFFFF, 0, 0, 0}) == 64);
static_assert(bitlen<4>(std::array<uint64_t,4>{0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}) == 64);
static_assert(bitlen<4>(std::array<uint64_t,4>{0x8FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}) == 63);
static_assert(bitlen<4>(std::array<uint64_t,4>{0, 0, 0, 0}) == 0);

constexpr int bitlen(const std::array<uint64_t, 4>& a) {
return bitlen<4>(std::span<const uint64_t, 4>(a));
}

Expand Down
2 changes: 1 addition & 1 deletion src/curve.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ struct curve_point {
curve_point mul(std::span<const uint64_t, 4> scalar) const noexcept {
const curve_point& a = *this;

array<curve_point, 4> precomp{};
std::array<curve_point, 4> precomp{};

precomp[1] = a;
precomp[2] = a;
Expand Down
20 changes: 10 additions & 10 deletions src/gfp.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@
#include <iosfwd>
#include <string>
#include <system_error>
#include <bn256/span.h>
#include <span>

namespace bn256 {

enum class unmarshal_error { NO_ERROR = 0, COORDINATE_EXCEEDS_MODULUS = 1, COORDINATE_EQUALS_MODULUS, MALFORMED_POINT };

namespace constants {
// rn1 is R^-1 where R = 2^256 mod p.
inline constexpr array<uint64_t, 4> rn1 = { 0xed84884a014afa37, 0xeb2022850278edf8, 0xcf63e9cfb74492d9,
0x2e67157159e5c639 };
inline constexpr std::array<uint64_t, 4> rn1 = { 0xed84884a014afa37, 0xeb2022850278edf8, 0xcf63e9cfb74492d9,
0x2e67157159e5c639 };

// r2 is R^2 where R = 2^256 mod p.
inline constexpr array<uint64_t, 4> r2 = { 0xf32cfc5b538afa89, 0xb5e71911d44501fb, 0x47ab1eff0a417ff6,
0x06d89f71cab8351f };
inline constexpr std::array<uint64_t, 4> r2 = { 0xf32cfc5b538afa89, 0xb5e71911d44501fb, 0x47ab1eff0a417ff6,
0x06d89f71cab8351f };

// r3 is R^3 where R = 2^256 mod p.
inline constexpr array<uint64_t, 4> r3 = { 0xb1cd6dafda1530df, 0x62f210e6a7283db6, 0xef7f0b0c0ada0afb,
0x20fd6e902d592544 };
inline constexpr std::array<uint64_t, 4> r3 = { 0xb1cd6dafda1530df, 0x62f210e6a7283db6, 0xef7f0b0c0ada0afb,
0x20fd6e902d592544 };
} // namespace constants

struct gfp : array<uint64_t, 4> {
struct gfp : std::array<uint64_t, 4> {

static constexpr gfp zero() noexcept { return {}; }

Expand All @@ -36,8 +36,8 @@ struct gfp : array<uint64_t, 4> {
constexpr gfp mul(const gfp& other) const noexcept { return { gfp_mul(*this, other) }; }

constexpr gfp invert() const noexcept {
constexpr array<uint64_t, 4> bits = { 0x3c208c16d87cfd45, 0x97816a916871ca8d, 0xb85045b68181585d,
0x30644e72e131a029 };
constexpr std::array<uint64_t, 4> bits = { 0x3c208c16d87cfd45, 0x97816a916871ca8d, 0xb85045b68181585d,
0x30644e72e131a029 };

gfp sum{ constants::rn1 };
auto power = *this;
Expand Down
36 changes: 18 additions & 18 deletions src/gfp_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,51 +6,51 @@ namespace bn256 {

namespace constants {
// p2 is p, represented as little-endian 64-bit words.
inline constexpr array<uint64_t, 4> p2 = { 0x3c208c16d87cfd47, 0x97816a916871ca8d, 0xb85045b68181585d,
0x30644e72e131a029 };
inline constexpr std::array<uint64_t, 4> p2 = { 0x3c208c16d87cfd47, 0x97816a916871ca8d, 0xb85045b68181585d,
0x30644e72e131a029 };

// np is the negative inverse of p, mod 2^256.
inline constexpr array<uint64_t, 4> np = { 0x87d20782e4866389, 0x9ede7d651eca6ac9, 0xd8afcbd01833da80,
0xf57a22b791888c6b };
inline constexpr std::array<uint64_t, 4> np = { 0x87d20782e4866389, 0x9ede7d651eca6ac9, 0xd8afcbd01833da80,
0xf57a22b791888c6b };

} // namespace constants

constexpr array<uint64_t, 4> gfp_carry(const array<uint64_t, 4>& a, uint64_t head) noexcept {
array<uint64_t, 4> b{};
constexpr std::array<uint64_t, 4> gfp_carry(const std::array<uint64_t, 4>& a, uint64_t head) noexcept {
std::array<uint64_t, 4> b{};

bool carry = subborrow_u256(false, a.data(), constants::p2.data(), b.data());
carry = subborrow_u64(carry, head, 0, &head);

return carry ? a : b;
}

constexpr array<uint64_t, 4> gfp_neg(const array<uint64_t, 4>& a) noexcept {
array<uint64_t, 4> b{};
constexpr std::array<uint64_t, 4> gfp_neg(const std::array<uint64_t, 4>& a) noexcept {
std::array<uint64_t, 4> b{};
subborrow_u256(false, constants::p2.data(), a.data(), b.data());
return gfp_carry(b, 0);
}

constexpr array<uint64_t, 4> gfp_add(const array<uint64_t, 4>& a, const array<uint64_t, 4>& b) noexcept {
array<uint64_t, 4> c{};
constexpr std::array<uint64_t, 4> gfp_add(const std::array<uint64_t, 4>& a, const std::array<uint64_t, 4>& b) noexcept {
std::array<uint64_t, 4> c{};
bool carry = addcarry_u256(false, a.data(), b.data(), c.data());
return gfp_carry(c, carry);
}

constexpr array<uint64_t, 4> gfp_sub(const array<uint64_t, 4>& a, const array<uint64_t, 4>& b) noexcept {
array<uint64_t, 4> t{};
constexpr std::array<uint64_t, 4> gfp_sub(const std::array<uint64_t, 4>& a, const std::array<uint64_t, 4>& b) noexcept {
std::array<uint64_t, 4> t{};
subborrow_u256(false, constants::p2.data(), b.data(), t.data());
array<uint64_t, 4> c{};
std::array<uint64_t, 4> c{};
uint64_t carry = addcarry_u256(false, a.data(), t.data(), c.data());
return gfp_carry(c, carry);
}

[[gnu::hot]]
constexpr array<uint64_t, 4> gfp_mul(const array<uint64_t, 4>& a, const array<uint64_t, 4>& b) noexcept {
array<uint64_t, 8> T = {};
constexpr std::array<uint64_t, 4> gfp_mul(const std::array<uint64_t, 4>& a, const std::array<uint64_t, 4>& b) noexcept {
std::array<uint64_t, 8> T = {};
full_mul_u256(a.data(), b.data(), T.data());
array<uint64_t, 4> m = {};
std::array<uint64_t, 4> m = {};
half_mul_u256(T.data(), constants::np.data(), m.data());
array<uint64_t, 8> t = {};
std::array<uint64_t, 8> t = {};
full_mul_u256(m.data(), constants::p2.data(), t.data());

bool carry = false;
Expand All @@ -60,4 +60,4 @@ constexpr array<uint64_t, 4> gfp_mul(const array<uint64_t, 4>& a, const array<ui
return gfp_carry({ T[4], T[5], T[6], T[7] }, carry);
}

} // namespace bn256
} // namespace bn256
2 changes: 1 addition & 1 deletion src/int512.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace bn256 {
constexpr uint64_t signbits(int64_t a) { return a < 0 ? UINT64_MAX : 0; }

struct int512_t {
array<uint64_t, 8> limbs_;
std::array<uint64_t, 8> limbs_;

constexpr int512_t(int64_t a = 0)
: limbs_{
Expand Down
6 changes: 3 additions & 3 deletions src/lattice.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct lattice {

// decompose takes a scalar mod order as input and finds a short,
// positive decomposition of it wrt to the lattice basis.
constexpr array<int512_t, N> decompose(std::span<const uint64_t, 4> scalar) const noexcept{
constexpr std::array<int512_t, N> decompose(std::span<const uint64_t, 4> scalar) const noexcept{
int512_t k = {scalar[0], scalar[1], scalar[2], scalar[3], 0, 0, 0, 0};
// int512_t k = to_i512(scalar);
int512_t c[N] = {};
Expand All @@ -24,8 +24,8 @@ struct lattice {
}

// Transform vectors according to c and subtract <k,0,0,...>.
array<int512_t, N> out;
int512_t temp;
std::array<int512_t, N> out;
int512_t temp;
for (std::size_t i = 0; i < N; i++) {
out[i] = 0;
for (std::size_t j = 0; j < N; j++) {
Expand Down
9 changes: 5 additions & 4 deletions src/optate.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,10 @@ constexpr void mul_line(gfp12& ret, const gfp2& a, const gfp2& b, const gfp2& c)
}

// sixuPlus2NAF is 6u+2 in non-adjacent form.
constexpr array<int8_t, 65> six_u_plus_2_naf = { 0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0, 0, 1, 1, 0, -1, 0,
0, 1, 0, -1, 0, 0, 0, 0, 1, 1, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0,
-1, 0, 0, 1, 1, 0, 0, -1, 0, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, 1, 1 };
constexpr std::array<int8_t, 65> six_u_plus_2_naf = {
0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0, 0, 1, 1, 0, -1, 0,
0, 1, 0, -1, 0, 0, 0, 0, 1, 1, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0,
-1, 0, 0, 1, 1, 0, 0, -1, 0, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, 1, 1 };

// miller implements the Miller loop for calculating the Optimal Ate pairing.
// See algorithm 1 from http://cryptojedi.org/papers/dclxvi-20100714.pdf
Expand Down Expand Up @@ -292,4 +293,4 @@ inline gfp12 optimal_ate(const twist_point& a, const curve_point& b) noexcept {
}
return ret;
}
} // namespace bn256
} // namespace bn256
Loading

0 comments on commit eae77bf

Please sign in to comment.