Skip to content

Commit

Permalink
msm api with issue for result type
Browse files Browse the repository at this point in the history
  • Loading branch information
yshekel committed Jun 2, 2024
1 parent 8c53b14 commit bbc654b
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 1 deletion.
24 changes: 24 additions & 0 deletions icicle_v3/backend/cpu/src/curve/cpu_msm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

#include "icicle/msm.h"
#include "icicle/errors.h"
#include "icicle/runtime.h"

#include "icicle/curves/projective.h"
#include "icicle/curves/curve_config.h"

using namespace curve_config;
using namespace icicle;

eIcicleError cpu_msm(
const Device& device,
const scalar_t* scalars,
const affine_t* bases,
int msm_size,
const MSMConfig& config,
ResType* results)
{
std::cerr << "cpu_ntt() not implemented" << std::endl;
return eIcicleError::API_NOT_IMPLEMENTED;
}

REGISTER_MSM_BACKEND("CPU", cpu_msm);
2 changes: 2 additions & 0 deletions icicle_v3/include/icicle/curves/projective.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#ifdef __CUDACC__
#include "gpu-utils/sharedmem.h"
#endif // __CUDACC__

#include "icicle/utils/modifiers.h"
#include "icicle/curves/affine.h"

template <typename FF, class SCALAR_FF, const FF& B_VALUE, const FF& GENERATOR_X, const FF& GENERATOR_Y>
Expand Down
136 changes: 136 additions & 0 deletions icicle_v3/include/icicle/msm.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,138 @@
#pragma once

#include <functional>

#include "icicle/errors.h"
#include "icicle/runtime.h"
#include "icicle/utils/utils.h"

#include "icicle/curves/affine.h"
#include "icicle/curves/projective.h"
#include "icicle/fields/field.h"
#include "icicle/curves/curve_config.h"

using namespace curve_config;

namespace icicle {

/*************************** Frontend APIs ***************************/
struct MSMConfig {
icicleStreamHandle stream; /**< stream for async execution. */
int nof_bases; /**< Number of bases in the MSM for batched MSM. Set to 0 if all MSMs use the same bases or set to
* 'batch X #scalars' otherwise. Default value: 0 (that is reuse bases for all batch elements). */
int precompute_factor; /**< The number of extra points to pre-compute for each point. See the
* [precompute_msm_bases](@ref precompute_msm_bases) function, `precompute_factor` passed
* there needs to be equal to the one used here. Larger values decrease the
* number of computations to make, on-line memory footprint, but increase the static
* memory footprint. Default value: 1 (i.e. don't pre-compute). */
int batch_size; /**< The number of MSMs to compute. Default value: 1. */
bool are_scalars_on_device; /**< True if scalars are on device and false if they're on host. Default value:
* false. */
bool are_scalars_montgomery_form; /**< True if scalars are in Montgomery form and false otherwise. Default value:
* true. */
bool are_points_on_device; /**< True if points are on device and false if they're on host. Default value: false. */
bool are_points_montgomery_form; /**< True if coordinates of points are in Montgomery form and false otherwise.
* Default value: true. */
bool are_results_on_device; /**< True if the results should be on device and false if they should be on host. If set
* to false, `is_async` won't take effect because a synchronization is needed to
* transfer results to the host. Default value: false. */
bool is_async; /**< Whether to run the MSM asynchronously. If set to true, the MSM function will be
* non-blocking and you'd need to synchronize it explicitly by running
* `cudaStreamSynchronize` or `cudaDeviceSynchronize`. If set to false, the MSM
* function will block the current CPU thread. */
};

/**
* A function that returns the default value of [MSMConfig](@ref MSMConfig) for the [MSM](@ref MSM) function.
* @return Default value of [MSMConfig](@ref MSMConfig).
*/
static MSMConfig default_msm_config()
{
MSMConfig config = {
nullptr, // stream
0, // nof_bases
1, // precompute_factor
1, // batch_size
false, // are_scalars_on_device
false, // are_scalars_montgomery_form
false, // are_points_on_device
false, // are_points_montgomery_form
false, // are_results_on_device
false, // is_async
};
return config;
}

/**
* A function that computes MSM: \f$ MSM(s_i, P_i) = \sum_{i=1}^N s_i \cdot P_i \f$.
* @param scalars Scalars \f$ s_i \f$. In case of batch MSM, the scalars from all MSMs are concatenated.
* @param bases Bases \f$ P_i \f$. In case of batch MSM, all *unique* points are concatenated.
* So, if for example all MSMs share the same base points, they can be repeated only once.
* @param msm_size MSM size \f$ N \f$. If a batch of MSMs (which all need to have the same size) is computed, this is
* the size of 1 MSM.
* @param config [MSMConfig](@ref MSMConfig) used in this MSM.
* @param results Buffer for the result (or results in the case of batch MSM).
* @tparam S Scalar field type.
* @tparam A The type of points \f$ \{P_i\} \f$ which is typically an [affine
* Weierstrass](https://hyperelliptic.org/EFD/g1p/auto-shortw.html) point.
* @tparam P Output type, which is typically a [projective
* Weierstrass](https://hyperelliptic.org/EFD/g1p/auto-shortw-projective.html) point in our codebase.
* @return `SUCCESS` if the execution was successful and an error code otherwise.
*
*/
template <typename S, typename A, typename P>
eIcicleError msm(const S* scalars, const A* bases, int msm_size, const MSMConfig& config, P* results);

/**
* A function that precomputes MSM bases by extending them with their shifted copies.
* e.g.:
* Original points: \f$ P_0, P_1, P_2, ... P_{size} \f$
* Extended points: \f$ P_0, P_1, P_2, ... P_{size}, 2^{l}P_0, 2^{l}P_1, ..., 2^{l}P_{size},
* 2^{2l}P_0, 2^{2l}P_1, ..., 2^{2cl}P_{size}, ... \f$
* @param bases Bases \f$ P_i \f$. In case of batch MSM, all *unique* points are concatenated.
* @param bases_size Number of bases.
* @param precompute_factor The number of total precomputed points for each base (including the base itself).
* @param _c This is currently unused, but in the future precomputation will need to be aware of
* the `c` value used in MSM (see [MSMConfig](@ref MSMConfig)). So to avoid breaking your code with this
* upcoming change, make sure to use the same value of `c` in this function and in respective MSMConfig.
* @param are_bases_on_device Whether the bases are on device.
* @param ctx Device context specifying device id and stream to use.
* @param output_bases Device-allocated buffer of size bases_size * precompute_factor for the extended bases.
* @tparam A The type of points \f$ \{P_i\} \f$ which is typically an [affine
* Weierstrass](https://hyperelliptic.org/EFD/g1p/auto-shortw.html) point.
* @return `SUCCESS` if the execution was successful and an error code otherwise.
*
*/
template <typename A, typename P>
eIcicleError precompute_msm_bases(
A* bases,
int bases_size,
int precompute_factor,
int c,
bool are_bases_on_device,
icicleStreamHandle stream,
A* output_bases);

/*************************** Backend registration ***************************/

#define ResType affine_t

using MsmImpl = std::function<eIcicleError(
const Device& device,
const scalar_t* scalars,
const affine_t* bases,
int msm_size,
const MSMConfig& config,
ResType* results)>;

void register_msm(const std::string& deviceType, MsmImpl impl);

#define REGISTER_MSM_BACKEND(DEVICE_TYPE, FUNC) \
namespace { \
static bool _reg_msm = []() -> bool { \
register_msm(DEVICE_TYPE, FUNC); \
return true; \
}(); \
}

}; // namespace icicle
26 changes: 25 additions & 1 deletion icicle_v3/src/msm.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
#include "icicle/msm.h"
#include "icicle/msm.h"
#include "icicle/dispatcher.h"
#include "icicle/curves/curve_config.h"

using namespace curve_config;

namespace icicle {

/*************************** MSM ***************************/
ICICLE_DISPATCHER_INST(MsmDispatcher, msm, MsmImpl);

extern "C" eIcicleError CONCAT_EXPAND(CURVE, msm)(
const scalar_t* scalars, const affine_t* bases, int msm_size, const MSMConfig& config, ResType* results)
{
return MsmDispatcher::execute(scalars, bases, msm_size, config, results);
}

template <>
eIcicleError
msm(const scalar_t* scalars, const affine_t* bases, int msm_size, const MSMConfig& config, ResType* results)
{
return CONCAT_EXPAND(CURVE, msm)(scalars, bases, msm_size, config, results);
}

} // namespace icicle

0 comments on commit bbc654b

Please sign in to comment.