Skip to content

Commit

Permalink
add unit test for ipa
Browse files Browse the repository at this point in the history
  • Loading branch information
guozhengxuan committed Aug 30, 2024
1 parent 19dc675 commit 29c1ae4
Show file tree
Hide file tree
Showing 26 changed files with 391 additions and 68 deletions.
12 changes: 12 additions & 0 deletions bandersnatch/bandersnatch/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,26 @@ Element& Element::operator=(const Element& other)
Element::Element(const byte* in, size_t len)
{
if (len == 0 || len != (in[0]&0x80 ? 48 : 96))
{
throw BLST_BAD_ENCODING;
}

blst_p1_affine a;
BLST_ERROR err = blst_p1_deserialize(&a, in);

if (err != BLST_SUCCESS)
{
throw err;
}

blst_p1_from_affine(&m_point, &a);
}

bool Element::isInG1() const
{
return blst_p1_on_curve(&m_point) && blst_p1_in_g1(&m_point);
}

Element& Element::add(const Element& other)
{
blst_p1_add_or_double(&m_point, &m_point, &other.m_point);
Expand Down
6 changes: 6 additions & 0 deletions bandersnatch/bandersnatch/Element.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@
namespace verkle::bandersnatch
{
class Fr;
class PrecomputedElements;

class Element
{
public:
using ElementListPtr = std::shared_ptr<std::vector<Element>>;

Element();

// deserialize
Element(const Element& other);
[[nodiscard]] bool isInG1() const;

Element& operator=(const Element& other);

Element(const byte *in, size_t len);
Expand All @@ -39,5 +44,6 @@ class Element

private:
blst_p1 m_point;
friend class PrecomputedElements;
};
}
4 changes: 3 additions & 1 deletion bandersnatch/bandersnatch/Fr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ int Fr::cmp(const Fr& other) const
if (m_val.l[i] > other.m_val.l[i])
{
return 1;
} else if (m_val.l[i] < other.m_val.l[i])
}

if (m_val.l[i] < other.m_val.l[i])
{
return -1;
}
Expand Down
3 changes: 3 additions & 0 deletions bandersnatch/bandersnatch/Fr.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
//
#pragma once
#include <blst.h>
#include <memory>
#include <vector>

namespace verkle::bandersnatch
{
class Element;
class PrecomputedElements;

class Fr
{
Expand Down Expand Up @@ -49,5 +51,6 @@ class Fr
private:
blst_fr m_val{};
friend class Element;
friend class PrecomputedElements;
};
}
42 changes: 42 additions & 0 deletions bandersnatch/bandersnatch/PrecomputedElements.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Created by Zhengxuan Guo on 2024/8/30.
//
#include "PrecomputedElements.h"

using namespace verkle::bandersnatch;

PrecomputedElements::PrecomputedElements(Element::ElementListPtr const& points, size_t window)
: m_window(window),
m_numPoints(points->size()),
m_table(std::make_shared<blst_p1_affine[]>([window, this]() {
auto const bits = blst_p1s_mult_wbits_precompute_sizeof(window, m_numPoints);
return bits / sizeof(blst_p1_affine);
}()))
{
blst_p1_affine affinePoints[m_numPoints];
for (size_t i = 0; i < m_numPoints; ++i)
{
blst_p1_to_affine(&affinePoints[i], &points->at(i).m_point);
}

const blst_p1_affine* pointsArg[2] = {affinePoints, nullptr};
blst_p1s_mult_wbits_precompute(m_table.get(), m_window, pointsArg, m_numPoints);
}

Element PrecomputedElements::msm(Fr::FrListPtr const& scalars) const
{
size_t sz = blst_p1s_mult_wbits_scratch_sizeof(m_numPoints);
limb_t scratch[sz/sizeof(limb_t)];

blst_scalar baseScalars[m_numPoints];
for (size_t i = 0; i < m_numPoints; ++i)
{
blst_scalar_from_fr(&baseScalars[i], &scalars->at(i).m_val);
}

Element ret;
const byte* scalarsArg[2] = {reinterpret_cast<byte*>(baseScalars), nullptr};
blst_p1s_mult_wbits(&ret.m_point, m_table.get(), m_window, m_numPoints, scalarsArg, 255, scratch);

return ret;
}
21 changes: 21 additions & 0 deletions bandersnatch/bandersnatch/PrecomputedElements.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Created by Zhengxuan Guo on 2024/8/30.
//
#pragma once
#include "Element.h"
#include "Fr.h"

namespace verkle::bandersnatch
{
class PrecomputedElements {
public:
using Ptr = std::shared_ptr<PrecomputedElements>;
explicit PrecomputedElements(Element::ElementListPtr const& points, size_t window);
[[nodiscard]] Element msm(Fr::FrListPtr const& scalars) const;

private:
size_t m_window;
size_t m_numPoints;
std::shared_ptr<blst_p1_affine[]> m_table;
};
}
8 changes: 4 additions & 4 deletions bandersnatch/test/unittests/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#include "bandersnatch/Fr.h"
#include "bandersnatch/Element.h"

namespace verkle::test
namespace verkle::ipa::test
{
static inline const bandersnatch::Fr& FixedFr1()
static const bandersnatch::Fr& FixedFr1()
{
static uint64_t raw[4] = {
0xe5d76b4ca918a221,
Expand All @@ -16,7 +16,7 @@ static inline const bandersnatch::Fr& FixedFr1()
return fr1;
}

static inline const bandersnatch::Fr& FixedFr2()
static const bandersnatch::Fr& FixedFr2()
{
static uint64_t raw[4] = {
0xd894647091277b9c,
Expand All @@ -28,7 +28,7 @@ static inline const bandersnatch::Fr& FixedFr2()
return fr2;
}

static inline const bandersnatch::Element& FixedGenerator()
static const bandersnatch::Element& FixedGenerator()
{
static auto g = bandersnatch::Element::generator();
return g;
Expand Down
10 changes: 8 additions & 2 deletions bandersnatch/test/unittests/ElementTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@
#include <testutils/TestPromptFixture.h>
#include <boost/test/unit_test.hpp>

namespace verkle::test
namespace verkle::ipa::test
{
BOOST_FIXTURE_TEST_SUITE(ElementTest, TestPromptFixture)
BOOST_FIXTURE_TEST_SUITE(ElementTest, verkle::test::TestPromptFixture)

BOOST_AUTO_TEST_CASE(testInG1)
{
auto g = bandersnatch::Element::generator();
BOOST_ASSERT(g.isInG1());
}

BOOST_AUTO_TEST_CASE(testAdd)
{
Expand Down
4 changes: 2 additions & 2 deletions bandersnatch/test/unittests/FrTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
#include <testutils/TestPromptFixture.h>
#include <boost/test/unit_test.hpp>

namespace verkle::test
namespace verkle::ipa::test
{
BOOST_FIXTURE_TEST_SUITE(FrTest, TestPromptFixture)
BOOST_FIXTURE_TEST_SUITE(FrTest, verkle::test::TestPromptFixture)

BOOST_AUTO_TEST_CASE(testFromBytes)
{
Expand Down
42 changes: 42 additions & 0 deletions bandersnatch/test/unittests/PrecomputedElementsTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Created by Zhengxuan Guo on 2024/8/30.
//
#include <testutils/TestPromptFixture.h>
#include <boost/test/unit_test.hpp>

#include "bandersnatch/Fr.h"
#include "bandersnatch/Element.h"
#include "bandersnatch/PrecomputedElements.h"

using verkle::bandersnatch::Fr;
using verkle::bandersnatch::Element;
using verkle::bandersnatch::PrecomputedElements;

namespace verkle::ipa::test
{
BOOST_FIXTURE_TEST_SUITE(ElementTest, verkle::test::TestPromptFixture)

BOOST_AUTO_TEST_CASE(testPrecomputedMSM)
{
auto scalars = std::make_shared<std::vector<Fr>>(256);
auto points = std::make_shared<std::vector<Element>>(256);
auto exp = Element::zero();
for (size_t i = 0; i < 256; ++i)
{
auto randomFr = bandersnatch::Fr::random();
auto randomPoint = Element::generator().mult(randomFr);

// naive sum of multiple multiplication
exp.add(Element::mult(randomFr, randomPoint));

scalars->at(i) = randomFr;
points->at(i) = randomPoint;
}

auto const precomputed = PrecomputedElements(points, 8);
auto const res = precomputed.msm(scalars);
BOOST_ASSERT(res == exp);
}

BOOST_AUTO_TEST_SUITE_END()
}
12 changes: 10 additions & 2 deletions cmake/ProjectBLST.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,25 @@ if (NOT BASH_COMMAND)
message(FATAL_ERROR "bash not found")
endif ()

set(BLST_INSTALL_COMMAND
sh -c
"cp <SOURCE_DIR>/bindings/blst.h <INSTALL_DIR>/include/ &&
cp <SOURCE_DIR>/bindings/blst.hpp <INSTALL_DIR>/include/ &&
cp <SOURCE_DIR>/bindings/blst_aux.h <INSTALL_DIR>/include/ &&
cp <SOURCE_DIR>/libblst.a <INSTALL_DIR>/lib/"
)

ExternalProject_Add(blst_project
PREFIX ${CMAKE_SOURCE_DIR}/deps
GIT_REPOSITORY https://github.com/supranational/blst.git
GIT_TAG 3dd0f804b1819e5d03fb22ca2e6fac105932043a
GIT_TAG 52cc60d78591a56abb2f3d0bd1cdafc6ba242997
GIT_SHALLOW 0

CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ""
BUILD_COMMAND ${BLST_BUILD_COMMAND}
INSTALL_COMMAND sh -c "cp <SOURCE_DIR>/bindings/blst.h <INSTALL_DIR>/include/ && cp <SOURCE_DIR>/bindings/blst_aux.h <INSTALL_DIR>/include/ && cp <SOURCE_DIR>/libblst.a <INSTALL_DIR>/lib/"
INSTALL_COMMAND ${BLST_INSTALL_COMMAND}
LOG_BUILD true
LOG_INSTALL true
LOG_CONFIGURE true
Expand Down
22 changes: 21 additions & 1 deletion ipa/ipa/IPAConfig.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
#include "IPAConfig.h"
#include "IPAUtility.h"
#include "PrecomputedMSM.h"

using namespace verkle::ipa;

IPAConfig::IPAConfig():
m_srs(generateRandomPoints(common::vectorLength)),
m_Q(Element::generator()),
m_precomputed_msm(std::make_shared<PrecomputedMSM>(PrecomputedMSM(m_srs))),
m_precomputed_weights(std::make_shared<PrecomputedWeights>(PrecomputedWeights())),
m_rounds(computeNumRounds(common::vectorLength)) {}

IPAConfig const& IPAConfig::getConfig()
{
static auto config = IPAConfig();
return config;
}

Element IPAConfig::commit(const Fr::FrListPtr& scalars) const
{
return m_precomputed_msm->msm(scalars);
}

Fr::FrListPtr IPAConfig::computeBVector(Fr const& evalPoint) const
{
if (evalPoint.cmp(maxEvalPoinInsideDomain) > 0)
{
return m_precomputed_weights.computeBarycentricCoefficients(evalPoint);
return m_precomputed_weights->computeBarycentricCoefficients(evalPoint);
}

// We build b = [0, 0, 0, ... , 1, .., 0] where the 1 element is at the index of the evaluation point.
Expand Down
20 changes: 14 additions & 6 deletions ipa/ipa/IPAConfig.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "PrecomputedFrs.h"
#include "PrecomputedMSM.h"
#include "PrecomputedWeights.h"
#include "bandersnatch/Fr.h"
#include "bandersnatch/Element.h"

Expand All @@ -13,16 +14,23 @@ struct IPAConfig
using Ptr = std::shared_ptr<IPAConfig>;
Element::ElementListPtr m_srs;
Element m_Q;
PrecomputedFrs m_precomputed_weights;
uint32_t rounds;
PrecomputedMSM::Ptr m_precomputed_msm;
PrecomputedWeights::Ptr m_precomputed_weights;
uint32_t m_rounds{};

// TODO: precomputed points for acceleration
IPAConfig(IPAConfig const&) = delete;
void operator=(IPAConfig const&) = delete;

Element commitToPoly(const Fr::FrListPtr& scalars);
static IPAConfig const& getConfig();

Fr::FrListPtr computeBVector(Fr const& evalPoint) const;
[[nodiscard]] Element commit(const Fr::FrListPtr& scalars) const;

[[nodiscard]] Fr::FrListPtr computeBVector(Fr const& evalPoint) const;

static const Fr maxEvalPoinInsideDomain;

private:
IPAConfig();
};

inline const Fr IPAConfig::maxEvalPoinInsideDomain = Fr::fromUint64(255);
Expand Down
Loading

0 comments on commit 29c1ae4

Please sign in to comment.