Skip to content

Commit

Permalink
update marshalling, support curve elem constructor from non-natives, …
Browse files Browse the repository at this point in the history
…support curves and non native fields in print_circuit_output
  • Loading branch information
CblPOK-git authored and nkaskov committed Oct 2, 2023
1 parent 456baf1 commit 6b9aba3
Show file tree
Hide file tree
Showing 4 changed files with 360 additions and 103 deletions.
26 changes: 20 additions & 6 deletions include/nil/blueprint/curves/init.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,27 @@

namespace nil {
namespace blueprint {
template<typename VarType>
template<typename VarType, typename BlueprintFieldType>
void handle_curve_init(const llvm::CallInst *inst, stack_frame<VarType> &frame) {
VarType x = frame.scalars[inst->getOperand(0)];
VarType y = frame.scalars[inst->getOperand(1)];
frame.vectors[inst] = {x, y};
ASSERT(inst->getOperand(0)->getType() == inst->getOperand(1)->getType());
ASSERT(inst->getOperand(0)->getType()->isFieldTy());

std::size_t arg_num = field_arg_num<BlueprintFieldType>(inst->getOperand(0)->getType());
if (arg_num == 1) {
VarType x = frame.scalars[inst->getOperand(0)];
VarType y = frame.scalars[inst->getOperand(1)];
frame.vectors[inst] = {x, y};
}
else {
ASSERT(frame.vectors[inst->getOperand(0)].size() == frame.vectors[inst->getOperand(1)].size());
std::vector<VarType> vect0 = frame.vectors[inst->getOperand(0)];
std::vector<VarType> vect1 = frame.vectors[inst->getOperand(1)];
vect0.insert(vect0.end(), vect1.begin(), vect1.end());
frame.vectors[inst] = vect0;
}
}
}
}

} // namespace blueprint
} // namespace nil

#endif // CRYPTO3_ASSIGNER_NIL_BLUEPRINT_CURVE_INIT_HPP
169 changes: 169 additions & 0 deletions include/nil/blueprint/non_native_marshalling.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2022 Mikhail Komarov <[email protected]>
// Copyright (c) 2022 Nikita Kaskov <[email protected]>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//---------------------------------------------------------------------------//

#ifndef CRYPTO3_ASSIGNER_NON_NATIVE_MARSHALLING_HPP
#define CRYPTO3_ASSIGNER_NON_NATIVE_MARSHALLING_HPP

namespace nil {
namespace blueprint {

template<typename BlueprintFieldType>
std::size_t curve_arg_num(llvm::Type *arg_type) {
std::size_t size = 0;

switch (llvm::cast<llvm::EllipticCurveType>(arg_type)->getCurveKind()) {
case llvm::ELLIPTIC_CURVE_PALLAS: {
return 2;
}
case llvm::ELLIPTIC_CURVE_VESTA: {
UNREACHABLE("vesta curve is not supported for used native field yet");
}
case llvm::ELLIPTIC_CURVE_CURVE25519: {
return 2 * nil::blueprint::detail::basic_non_native_policy_field_type<BlueprintFieldType, typename nil::crypto3::algebra::curves::ed25519::base_field_type>::ratio;
}
case llvm::ELLIPTIC_CURVE_BLS12381: {
UNREACHABLE("bls12381 is not supported for used native field yet");
}
default:
UNREACHABLE("unsupported curve type");
return 0;
};
}

template<typename BlueprintFieldType>
std::size_t field_arg_num(llvm::Type *arg_type) {
std::size_t size = 0;
switch (llvm::cast<llvm::GaloisFieldType>(arg_type)->getFieldKind()) {
case llvm::GALOIS_FIELD_PALLAS_BASE: {
return 1;
}
case llvm::GALOIS_FIELD_PALLAS_SCALAR: {
return nil::blueprint::detail::basic_non_native_policy_field_type<BlueprintFieldType, typename nil::crypto3::algebra::curves::pallas::scalar_field_type>::ratio;
}
case llvm::GALOIS_FIELD_VESTA_BASE: {
UNREACHABLE("vesta base field is not supported for used native field yet");
}
case llvm::GALOIS_FIELD_VESTA_SCALAR: {
UNREACHABLE("vesta scalar field is not supported for used native field yet");
}
case llvm::GALOIS_FIELD_BLS12381_BASE: {
UNREACHABLE("bls12381 base field is not supported for used native field yet");
}
case llvm::GALOIS_FIELD_BLS12381_SCALAR: {
UNREACHABLE("bls12381 scalar field is not supported for used native field yet");
}
case llvm::GALOIS_FIELD_CURVE25519_BASE: {
return nil::blueprint::detail::basic_non_native_policy_field_type<BlueprintFieldType, typename nil::crypto3::algebra::curves::ed25519::base_field_type>::ratio;
}
case llvm::GALOIS_FIELD_CURVE25519_SCALAR: {
return nil::blueprint::detail::basic_non_native_policy_field_type<BlueprintFieldType, typename nil::crypto3::algebra::curves::ed25519::scalar_field_type>::ratio;
}

default:
UNREACHABLE("unsupported field operand type");
}
}


template<typename BlueprintFieldType, typename NonNativeFieldType>
std::vector<typename BlueprintFieldType::value_type> value_into_vector (typename NonNativeFieldType::value_type input) {
using non_native_policy = typename nil::blueprint::detail::basic_non_native_policy_field_type<BlueprintFieldType, NonNativeFieldType>;

if constexpr (non_native_policy::ratio == 1) {
std::vector<typename BlueprintFieldType::value_type> res;
res.push_back(typename BlueprintFieldType::value_type(typename BlueprintFieldType::integral_type(input.data)));
return res;
}
else {
auto res_arr = non_native_policy::chop_non_native(input);
return std::vector<typename BlueprintFieldType::value_type>(std::begin(res_arr), std::end(res_arr));
}
}

template<typename BlueprintFieldType, typename NonNativeFieldType>
typename NonNativeFieldType::value_type vector_into_value (std::vector<typename BlueprintFieldType::value_type> input) {
using non_native_policy = typename nil::blueprint::detail::basic_non_native_policy_field_type<BlueprintFieldType, NonNativeFieldType>;

if (input.size() != non_native_policy::ratio) {
std::cerr << "input.size(): " << input.size() << "\n";
std::cerr << "non_native_policy::ratio: " << non_native_policy::ratio << "\n";
UNREACHABLE("input.size() != non_native_policy::ratio");
}


if constexpr (non_native_policy::ratio == 1) {
UNREACHABLE("scalar, no need to use vector, conversion for ratio==1 is not implemented");
}
else {
typename non_native_policy::chopped_value_type chopped_field;
for (std::size_t i = 0; i < non_native_policy::ratio; i++) {
chopped_field[i] = input[i];
}
typename NonNativeFieldType::value_type res = non_native_policy::glue_non_native(chopped_field);
return res;
}
}

template<typename BlueprintFieldType, typename NonNativeFieldType>
std::vector<typename BlueprintFieldType::value_type> check_modulus_and_chop(typename BlueprintFieldType::extended_integral_type glued_non_native) {
if(glued_non_native >= NonNativeFieldType::modulus) {
std::cerr << std::hex;
std::cerr << "0x" << glued_non_native << " >=\n";
std::cerr << "0x" << NonNativeFieldType::modulus << "\n";
UNREACHABLE("value does not fit into field modulus!");
}
return value_into_vector<BlueprintFieldType, NonNativeFieldType>(typename NonNativeFieldType::value_type(glued_non_native));
}


template<typename BlueprintFieldType>
std::vector<typename BlueprintFieldType::value_type> extended_integral_into_vector (llvm::GaloisFieldKind arg_field_type, typename BlueprintFieldType::extended_integral_type glued_non_native) {
switch (arg_field_type) {
case llvm::GALOIS_FIELD_CURVE25519_BASE: {
using non_native_field_type = typename nil::crypto3::algebra::curves::ed25519::base_field_type;
return check_modulus_and_chop<BlueprintFieldType, non_native_field_type>(glued_non_native);
}
case llvm::GALOIS_FIELD_CURVE25519_SCALAR: {
using non_native_field_type = typename nil::crypto3::algebra::curves::ed25519::scalar_field_type;
return check_modulus_and_chop<BlueprintFieldType, non_native_field_type>(glued_non_native);
}
case llvm::GALOIS_FIELD_PALLAS_BASE: {
using non_native_field_type = typename nil::crypto3::algebra::curves::pallas::base_field_type;
return check_modulus_and_chop<BlueprintFieldType, non_native_field_type>(glued_non_native);
}
case llvm::GALOIS_FIELD_PALLAS_SCALAR: {
using non_native_field_type = typename nil::crypto3::algebra::curves::pallas::scalar_field_type;
return check_modulus_and_chop<BlueprintFieldType, non_native_field_type>(glued_non_native);
}

default:
UNREACHABLE("unsupported field operand type");
}
}

} // namespace blueprint
} // namespace nil

#endif // CRYPTO3_ASSIGNER_NON_NATIVE_MARSHALLING_HPP
Loading

0 comments on commit 6b9aba3

Please sign in to comment.