Skip to content

Commit

Permalink
feat: the G1 curve should support element conversion ( PROOF-666 ) (#22)
Browse files Browse the repository at this point in the history
* feat: the bls12-381 base field have an operation to move uint8_t elements ( PROOF-666 )

* feat: the g1 curve should be able to move affine elements ( PROOF-666 )

* refactor: the g1 affine element should use uint8_t to represent infinity ( PROOF-666 )

* feat: add converstion between g1 projective and affine elements ( PROOF-666 )

* chore: remove unnecessary namespace prefix ( PROOF-666 )

* feat: add affine to projective element conversion ( PROOF-666 )

* chore: correct test section name ( PROOF-666 )

* refactor: rewrite convert to match conversion_ultilty in curve21 package ( PROOF-666 )

* refactor: move curve_g1 affine identity to element_affine component ( PROOF-666 )

* refactor: move coversion_ultility component to type package ( PROOF-666 )

* remove element_affine cmov function to avoid circular dependencies

* refactor: move generic cmov to base/num package ( PROOF-666 )
  • Loading branch information
jacobtrombetta authored Sep 29, 2023
1 parent d1e8fad commit d7ef890
Show file tree
Hide file tree
Showing 18 changed files with 342 additions and 39 deletions.
10 changes: 10 additions & 0 deletions sxt/base/num/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ load(
"sxt_cc_component",
)

sxt_cc_component(
name = "cmov",
test_deps = [
"//sxt/base/test:unit_test",
],
deps = [
"//sxt/base/macro:cuda_callable",
],
)

sxt_cc_component(
name = "constexpr_switch",
test_deps = [
Expand Down
2 changes: 1 addition & 1 deletion sxt/curve_g1/constant/identity.cc → sxt/base/num/cmov.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sxt/curve_g1/constant/identity.h"
#include "sxt/base/num/cmov.h"
24 changes: 15 additions & 9 deletions sxt/curve_g1/constant/identity.h → sxt/base/num/cmov.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,21 @@
*/
#pragma once

#include "sxt/curve_g1/type/element_affine.h"
#include "sxt/curve_g1/type/element_p2.h"
#include "sxt/field12/constant/one.h"
#include "sxt/field12/constant/zero.h"
#include "sxt/field12/type/element.h"
#include "sxt/base/macro/cuda_callable.h"

namespace sxt::cg1cn {
namespace sxt::basn {
//--------------------------------------------------------------------------------------------------
// identity_affine_v
// cmov
//--------------------------------------------------------------------------------------------------
static constexpr cg1t::element_affine identity_affine_v{f12cn::zero_v, f12cn::one_v, true};
} // namespace sxt::cg1cn
/*
Replace (f,g) with (g,g) if b == 1.
Replace (f,g) with (f,g) if b == 0.
*
Preconditions: b in {0,1}.
*/
template <std::integral T>
CUDA_CALLABLE inline void cmov(T& f, const T g, unsigned int b) noexcept {
const T mask = static_cast<T>(-static_cast<T>(b));
f = f ^ (mask & (f ^ g));
}
} // namespace sxt::basn
84 changes: 84 additions & 0 deletions sxt/base/num/cmov.t.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/** Proofs GPU - Space and Time's cryptographic proof algorithms on the CPU and GPU.
*
* Copyright 2023-present Space and Time Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sxt/base/num/cmov.h"

#include "sxt/base/test/unit_test.h"

using namespace sxt;
using namespace sxt::basn;

TEST_CASE("cmov correctly moves") {
SECTION("uint8_t elements") {
uint8_t h{0};
uint8_t g{0};
constexpr uint8_t i{1};

cmov(h, i, true);
cmov(g, i, false);

REQUIRE(h == i);
REQUIRE(g == 0);
}

SECTION("uint16_t elements") {
uint16_t h{0};
uint16_t g{0};
constexpr uint16_t i{1};

cmov(h, i, true);
cmov(g, i, false);

REQUIRE(h == i);
REQUIRE(g == 0);
}

SECTION("uint32_t elements") {
uint32_t h{0};
uint32_t g{0};
constexpr uint32_t i{1};

cmov(h, i, true);
cmov(g, i, false);

REQUIRE(h == i);
REQUIRE(g == 0);
}

SECTION("uint64_t elements") {
uint64_t h{0};
uint64_t g{0};
constexpr uint64_t i{1};

cmov(h, i, true);
cmov(g, i, false);

REQUIRE(h == 1);
REQUIRE(g == 0);
}

SECTION("signed int elements") {
int h{0};
int g{0};
constexpr int i{-1};

cmov(h, i, true);
cmov(g, i, false);

REQUIRE(h == i);
REQUIRE(g == 0);
}
}
12 changes: 0 additions & 12 deletions sxt/curve_g1/constant/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,3 @@ sxt_cc_component(
"//sxt/field12/type:element",
],
)

sxt_cc_component(
name = "identity",
with_test = False,
deps = [
"//sxt/curve_g1/type:element_affine",
"//sxt/curve_g1/type:element_p2",
"//sxt/field12/constant:one",
"//sxt/field12/constant:zero",
"//sxt/field12/type:element",
],
)
4 changes: 3 additions & 1 deletion sxt/curve_g1/operation/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ sxt_cc_component(
":double",
"//sxt/base/test:unit_test",
"//sxt/curve_g1/constant:generator",
"//sxt/curve_g1/constant:identity",
"//sxt/curve_g1/property:curve",
"//sxt/curve_g1/property:identity",
"//sxt/curve_g1/type:element_affine",
"//sxt/field12/type:element",
],
deps = [
Expand All @@ -33,13 +33,15 @@ sxt_cc_component(
sxt_cc_component(
name = "cmov",
impl_deps = [
"//sxt/curve_g1/type:element_affine",
"//sxt/curve_g1/type:element_p2",
"//sxt/field12/operation:cmov",
],
is_cuda = True,
test_deps = [
"//sxt/base/test:unit_test",
"//sxt/curve_g1/constant:generator",
"//sxt/curve_g1/type:element_affine",
"//sxt/curve_g1/type:element_p2",
],
deps = [
Expand Down
6 changes: 3 additions & 3 deletions sxt/curve_g1/operation/add.t.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@

#include "sxt/base/test/unit_test.h"
#include "sxt/curve_g1/constant/generator.h"
#include "sxt/curve_g1/constant/identity.h"
#include "sxt/curve_g1/operation/double.h"
#include "sxt/curve_g1/property/curve.h"
#include "sxt/curve_g1/property/identity.h"
#include "sxt/curve_g1/type/element_affine.h"
#include "sxt/curve_g1/type/element_p2.h"
#include "sxt/field12/operation/mul.h"
#include "sxt/field12/type/element.h"
Expand Down Expand Up @@ -97,7 +97,7 @@ TEST_CASE("addition with projective elements") {
TEST_CASE("addition with mixed elements") {
SECTION("keeps the identity on the curve") {
cg1t::element_p2 ret;
add(ret, cg1t::element_p2::identity(), cg1cn::identity_affine_v);
add(ret, cg1t::element_p2::identity(), cg1t::element_affine::identity());

REQUIRE(cg1p::is_identity(ret));
REQUIRE(cg1p::is_on_curve(ret));
Expand All @@ -113,7 +113,7 @@ TEST_CASE("addition with mixed elements") {
const cg1t::element_p2 projected_generator{x, y, z};
cg1t::element_p2 ret;

add(ret, projected_generator, cg1cn::identity_affine_v);
add(ret, projected_generator, cg1t::element_affine::identity());

REQUIRE(!cg1p::is_identity(ret));
REQUIRE(cg1p::is_on_curve(ret));
Expand Down
3 changes: 2 additions & 1 deletion sxt/curve_g1/operation/cmov.t.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@

#include "sxt/base/test/unit_test.h"
#include "sxt/curve_g1/constant/generator.h"
#include "sxt/curve_g1/type/element_affine.h"
#include "sxt/curve_g1/type/element_p2.h"

using namespace sxt;
using namespace sxt::cg1o;

TEST_CASE("cmov returns expected perspective coordinates") {
TEST_CASE("cmov returns the expected projective coordinates") {
cg1t::element_p2 expect_generator{cg1cn::generator_p2_v};
cg1t::element_p2 expect_identity{cg1t::element_p2::identity()};

Expand Down
2 changes: 0 additions & 2 deletions sxt/curve_g1/property/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ sxt_cc_component(
"//sxt/base/test:unit_test",
"//sxt/curve_g1/constant:b",
"//sxt/curve_g1/constant:generator",
"//sxt/curve_g1/constant:identity",
"//sxt/curve_g1/type:element_affine",
"//sxt/curve_g1/type:element_p2",
"//sxt/field12/constant:one",
Expand All @@ -34,7 +33,6 @@ sxt_cc_component(
test_deps = [
"//sxt/base/test:unit_test",
"//sxt/curve_g1/constant:generator",
"//sxt/curve_g1/constant:identity",
],
deps = [
"//sxt/base/macro:cuda_callable",
Expand Down
3 changes: 1 addition & 2 deletions sxt/curve_g1/property/curve.t.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "sxt/base/test/unit_test.h"
#include "sxt/curve_g1/constant/b.h"
#include "sxt/curve_g1/constant/generator.h"
#include "sxt/curve_g1/constant/identity.h"
#include "sxt/curve_g1/type/element_affine.h"
#include "sxt/curve_g1/type/element_p2.h"
#include "sxt/field12/constant/one.h"
Expand All @@ -35,7 +34,7 @@ TEST_CASE("an affine element") {
}

SECTION("equal to the identity is on the curve") {
REQUIRE(is_on_curve(cg1cn::identity_affine_v));
REQUIRE(is_on_curve(cg1t::element_affine::identity()));
}

SECTION("equal to (1,1) is not on the curve") {
Expand Down
4 changes: 2 additions & 2 deletions sxt/curve_g1/property/identity.t.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@

#include "sxt/base/test/unit_test.h"
#include "sxt/curve_g1/constant/generator.h"
#include "sxt/curve_g1/constant/identity.h"
#include "sxt/curve_g1/type/element_affine.h"
#include "sxt/curve_g1/type/element_p2.h"

using namespace sxt;
using namespace sxt::cg1p;

TEST_CASE("the identity can be identified") {
SECTION("as an affine element") {
REQUIRE(is_identity(cg1cn::identity_affine_v));
REQUIRE(is_identity(cg1t::element_affine::identity()));
REQUIRE(!is_identity(cg1cn::generator_affine_v));
}

Expand Down
21 changes: 19 additions & 2 deletions sxt/curve_g1/type/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,31 @@ load(
"sxt_cc_component",
)

sxt_cc_component(
name = "conversion_utility",
test_deps = [
"//sxt/base/test:unit_test",
],
deps = [
":element_affine",
":element_p2",
"//sxt/base/macro:cuda_callable",
"//sxt/base/num:cmov",
"//sxt/field12/operation:cmov",
"//sxt/field12/operation:invert",
"//sxt/field12/operation:mul",
"//sxt/field12/type:element",
],
)

sxt_cc_component(
name = "element_affine",
test_deps = [
"//sxt/base/test:unit_test",
"//sxt/field12/constant:one",
"//sxt/field12/constant:zero",
],
deps = [
"//sxt/field12/constant:one",
"//sxt/field12/constant:zero",
"//sxt/field12/type:element",
],
)
Expand Down
17 changes: 17 additions & 0 deletions sxt/curve_g1/type/conversion_utility.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/** Proofs GPU - Space and Time's cryptographic proof algorithms on the CPU and GPU.
*
* Copyright 2023-present Space and Time Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sxt/curve_g1/type/conversion_utility.h"
Loading

0 comments on commit d7ef890

Please sign in to comment.