diff --git a/sxt/curve_bng1/operation/BUILD b/sxt/curve_bng1/operation/BUILD new file mode 100644 index 000000000..170f71cce --- /dev/null +++ b/sxt/curve_bng1/operation/BUILD @@ -0,0 +1,68 @@ +load( + "//bazel:sxt_build_system.bzl", + "sxt_cc_component", +) + +sxt_cc_component( + name = "cmov", + impl_deps = [ + "//sxt/curve_bng1/type:element_affine", + "//sxt/curve_bng1/type:element_p2", + "//sxt/field25/operation:cmov", + ], + is_cuda = True, + test_deps = [ + "//sxt/base/test:unit_test", + "//sxt/curve_bng1/constant:generator", + "//sxt/curve_bng1/type:element_affine", + "//sxt/curve_bng1/type:element_p2", + ], + deps = [ + "//sxt/base/macro:cuda_callable", + ], +) + +sxt_cc_component( + name = "double", + impl_deps = [ + ":cmov", + ":mul_by_3b", + "//sxt/curve_bng1/property:identity", + "//sxt/curve_bng1/type:element_p2", + "//sxt/field25/operation:add", + "//sxt/field25/operation:mul", + "//sxt/field25/operation:square", + "//sxt/field25/operation:sub", + "//sxt/field25/type:element", + ], + is_cuda = True, + test_deps = [ + "//sxt/base/test:unit_test", + "//sxt/curve_bng1/constant:generator", + "//sxt/curve_bng1/property:curve", + "//sxt/curve_bng1/property:identity", + "//sxt/curve_bng1/type:element_p2", + "//sxt/field25/constant:zero", + ], + deps = [ + "//sxt/base/macro:cuda_callable", + ], +) + +sxt_cc_component( + name = "mul_by_3b", + impl_deps = [ + "//sxt/field25/operation:add", + "//sxt/field25/type:element", + ], + is_cuda = True, + test_deps = [ + "//sxt/base/test:unit_test", + "//sxt/field25/constant:one", + "//sxt/field25/type:element", + "//sxt/field25/type:literal", + ], + deps = [ + "//sxt/base/macro:cuda_callable", + ], +) diff --git a/sxt/curve_bng1/operation/cmov.cc b/sxt/curve_bng1/operation/cmov.cc new file mode 100644 index 000000000..1bf7cfe67 --- /dev/null +++ b/sxt/curve_bng1/operation/cmov.cc @@ -0,0 +1,32 @@ +/** 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_bng1/operation/cmov.h" + +#include "sxt/curve_bng1/type/element_p2.h" +#include "sxt/field25/operation/cmov.h" + +namespace sxt::cn1o { +//-------------------------------------------------------------------------------------------------- +// cmov +//-------------------------------------------------------------------------------------------------- +CUDA_CALLABLE +void cmov(cn1t::element_p2& f, const cn1t::element_p2& g, unsigned int b) noexcept { + f25o::cmov(f.X, g.X, b); + f25o::cmov(f.Y, g.Y, b); + f25o::cmov(f.Z, g.Z, b); +} +} // namespace sxt::cn1o diff --git a/sxt/curve_bng1/operation/cmov.h b/sxt/curve_bng1/operation/cmov.h new file mode 100644 index 000000000..e4cde067a --- /dev/null +++ b/sxt/curve_bng1/operation/cmov.h @@ -0,0 +1,37 @@ +/** 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. + */ +#pragma once + +#include "sxt/base/macro/cuda_callable.h" + +namespace sxt::cn1t { +struct element_p2; +} + +namespace sxt::cn1o { +//-------------------------------------------------------------------------------------------------- +// cmov +//-------------------------------------------------------------------------------------------------- +/** + * Replace (f,g) with (g,g) if b == 1; + * replace (f,g) with (f,g) if b == 0. + * + * Preconditions: b in {0,1}. + */ +CUDA_CALLABLE +void cmov(cn1t::element_p2& f, const cn1t::element_p2& g, unsigned int b) noexcept; +} // namespace sxt::cn1o diff --git a/sxt/curve_bng1/operation/cmov.t.cc b/sxt/curve_bng1/operation/cmov.t.cc new file mode 100644 index 000000000..7eb0494f7 --- /dev/null +++ b/sxt/curve_bng1/operation/cmov.t.cc @@ -0,0 +1,36 @@ +/** 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_bng1/operation/cmov.h" + +#include "sxt/base/test/unit_test.h" +#include "sxt/curve_bng1/constant/generator.h" +#include "sxt/curve_bng1/type/element_affine.h" +#include "sxt/curve_bng1/type/element_p2.h" + +using namespace sxt; +using namespace sxt::cn1o; + +TEST_CASE("cmov returns the expected projective coordinates") { + cn1t::element_p2 expect_generator{cn1cn::generator_p2_v}; + cn1t::element_p2 expect_identity{cn1t::element_p2::identity()}; + + cn1o::cmov(expect_generator, cn1t::element_p2::identity(), 0); + cn1o::cmov(expect_identity, cn1t::element_p2::identity(), 1); + + REQUIRE(expect_generator == cn1cn::generator_p2_v); + REQUIRE(expect_identity == cn1t::element_p2::identity()); +} diff --git a/sxt/curve_bng1/operation/double.cc b/sxt/curve_bng1/operation/double.cc new file mode 100644 index 000000000..31aa36a4f --- /dev/null +++ b/sxt/curve_bng1/operation/double.cc @@ -0,0 +1,72 @@ +/** 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. + */ +/** + * Adopted from zkcrypto/bls12_381 + * + * Copyright (c) 2021 + * Sean Bowe + * Jack Grigg + * + * See third_party/license/zkcrypto.LICENSE + */ +#include "sxt/curve_bng1/operation/double.h" + +#include "sxt/curve_bng1/operation/cmov.h" +#include "sxt/curve_bng1/operation/mul_by_3b.h" +#include "sxt/curve_bng1/property/identity.h" +#include "sxt/curve_bng1/type/element_p2.h" +#include "sxt/field25/operation/add.h" +#include "sxt/field25/operation/mul.h" +#include "sxt/field25/operation/square.h" +#include "sxt/field25/operation/sub.h" +#include "sxt/field25/type/element.h" + +namespace sxt::cn1o { +//-------------------------------------------------------------------------------------------------- +// double_element +//-------------------------------------------------------------------------------------------------- +CUDA_CALLABLE +void double_element(cn1t::element_p2& h, const cn1t::element_p2& p) noexcept { + f25t::element t0, t1, t2; + f25t::element x3, y3, z3; + + f25o::square(t0, p.Y); + f25o::add(z3, t0, t0); + f25o::add(z3, z3, z3); + f25o::add(z3, z3, z3); + f25o::mul(t1, p.Y, p.Z); + f25o::square(t2, p.Z); + mul_by_3b(t2, t2); + f25o::mul(x3, t2, z3); + f25o::add(y3, t0, t2); + f25o::mul(z3, t1, z3); + f25o::add(t1, t2, t2); + f25o::add(t2, t1, t2); + f25o::sub(t0, t0, t2); + f25o::mul(y3, t0, y3); + f25o::add(y3, x3, y3); + f25o::mul(t1, p.X, p.Y); + f25o::mul(x3, t0, t1); + f25o::add(x3, x3, x3); + + h.X = x3; + h.Y = y3; + h.Z = z3; + + cmov(h, cn1t::element_p2::identity(), cn1p::is_identity(p)); +} +} // namespace sxt::cn1o diff --git a/sxt/curve_bng1/operation/double.h b/sxt/curve_bng1/operation/double.h new file mode 100644 index 000000000..61ae41b7e --- /dev/null +++ b/sxt/curve_bng1/operation/double.h @@ -0,0 +1,35 @@ +/** 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. + */ +#pragma once + +#include "sxt/base/macro/cuda_callable.h" + +namespace sxt::cn1t { +struct element_p2; +} + +namespace sxt::cn1o { +//-------------------------------------------------------------------------------------------------- +// double_element +//-------------------------------------------------------------------------------------------------- +/** + * Computes the doubling of element. + * Algorithm 9, https://eprint.iacr.org/2015/1060.pdf + */ +CUDA_CALLABLE +void double_element(cn1t::element_p2& h, const cn1t::element_p2& p) noexcept; +} // namespace sxt::cn1o diff --git a/sxt/curve_bng1/operation/double.t.cc b/sxt/curve_bng1/operation/double.t.cc new file mode 100644 index 000000000..874d21b24 --- /dev/null +++ b/sxt/curve_bng1/operation/double.t.cc @@ -0,0 +1,69 @@ +/** 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_bng1/operation/double.h" + +#include "sxt/base/test/unit_test.h" +#include "sxt/curve_bng1/constant/generator.h" +#include "sxt/curve_bng1/property/curve.h" +#include "sxt/curve_bng1/property/identity.h" +#include "sxt/curve_bng1/type/element_p2.h" +#include "sxt/field25/constant/zero.h" + +using namespace sxt; +using namespace sxt::cn1o; + +TEST_CASE("doubling a projective element") { + SECTION("preserves the identity") { + cn1t::element_p2 identity_double; + + double_element(identity_double, cn1t::element_p2::identity()); + + REQUIRE(cn1p::is_identity(identity_double)); + REQUIRE(cn1p::is_on_curve(identity_double)); + } + + SECTION("preserves the generator") { + cn1t::element_p2 generator_double; + + double_element(generator_double, cn1cn::generator_p2_v); + + REQUIRE(!cn1p::is_identity(generator_double)); + REQUIRE(cn1p::is_on_curve(generator_double)); + } + + SECTION("produces double the generator") { + constexpr cn1t::element_p2 expected{ + {0xe10460b6c3e7ea38, 0xbc0b548b438e5469, 0xc2822db40c0ac2ec, 0x13227397098d014d}, + {0x3c208c16d87cfd47, 0x97816a916871ca8d, 0xb85045b68181585d, 0x04644e72e131a029}, + {0xd35d438dc58f0d9d, 0x0a78eb28f5c70b3d, 0x666ea36f7879462c, 0xe0a77c19a07df2f}}; + cn1t::element_p2 generator_double; + + double_element(generator_double, cn1cn::generator_p2_v); + + REQUIRE(expected == generator_double); + } + + SECTION("produces the identity when Z is the zero element") { + constexpr cn1t::element_p2 p{cn1cn::generator_p2_v.X, cn1cn::generator_p2_v.Y, f25cn::zero_v}; + cn1t::element_p2 expect_identity; + + double_element(expect_identity, p); + + REQUIRE(cn1p::is_on_curve(p)); + REQUIRE(expect_identity == cn1t::element_p2::identity()); + } +} diff --git a/sxt/curve_bng1/operation/mul_by_3b.cc b/sxt/curve_bng1/operation/mul_by_3b.cc new file mode 100644 index 000000000..f0a277a64 --- /dev/null +++ b/sxt/curve_bng1/operation/mul_by_3b.cc @@ -0,0 +1,37 @@ +/** 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_bng1/operation/mul_by_3b.h" + +#include "sxt/field25/operation/add.h" +#include "sxt/field25/type/element.h" + +namespace sxt::cn1o { +//-------------------------------------------------------------------------------------------------- +// mul_by_3b +//-------------------------------------------------------------------------------------------------- +CUDA_CALLABLE +void mul_by_3b(f25t::element& h, const f25t::element& p) noexcept { + f25t::element p2; + f25t::element p4; + f25t::element p8; + + f25o::add(p2, p, p); + f25o::add(p4, p2, p2); + f25o::add(p8, p4, p4); + f25o::add(h, p8, p); +} +} // namespace sxt::cn1o diff --git a/sxt/curve_bng1/operation/mul_by_3b.h b/sxt/curve_bng1/operation/mul_by_3b.h new file mode 100644 index 000000000..895fdbeaa --- /dev/null +++ b/sxt/curve_bng1/operation/mul_by_3b.h @@ -0,0 +1,35 @@ +/** 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. + */ +#pragma once + +#include "sxt/base/macro/cuda_callable.h" + +namespace sxt::f25t { +class element; +} + +namespace sxt::cn1o { +//-------------------------------------------------------------------------------------------------- +// mul_by_3b +//-------------------------------------------------------------------------------------------------- +/** + * For the bn254 curve, since b = 3, 3b = 9. + * See Algorithm 9 for details, https://eprint.iacr.org/2015/1060.pdf + */ +CUDA_CALLABLE +void mul_by_3b(f25t::element& h, const f25t::element& p) noexcept; +} // namespace sxt::cn1o diff --git a/sxt/curve_bng1/operation/mul_by_3b.t.cc b/sxt/curve_bng1/operation/mul_by_3b.t.cc new file mode 100644 index 000000000..a04243819 --- /dev/null +++ b/sxt/curve_bng1/operation/mul_by_3b.t.cc @@ -0,0 +1,36 @@ +/** 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_bng1/operation/mul_by_3b.h" + +#include "sxt/base/test/unit_test.h" +#include "sxt/field25/constant/one.h" +#include "sxt/field25/type/element.h" +#include "sxt/field25/type/literal.h" + +using namespace sxt; +using namespace sxt::cn1o; +using namespace sxt::f25t; + +TEST_CASE("multiply by 3b") { + SECTION("returns nine if one in Montgomery form is the input") { + f25t::element ret; + + mul_by_3b(ret, f25cn::one_v); + + REQUIRE(0x9_f25 == ret); + } +}