Skip to content

Commit

Permalink
SKALE-1154-rewrite-dkg-algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
olehnikolaiev committed Jun 9, 2019
1 parent 204bbc5 commit 770a942
Show file tree
Hide file tree
Showing 6 changed files with 431 additions and 32 deletions.
206 changes: 206 additions & 0 deletions dkg/dkg_te.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
/*
Copyright (C) 2018-2019 SKALE Labs
This file is part of libBLS.
libBLS is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
libBLS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with libBLS. If not, see <https://www.gnu.org/licenses/>.
@file dkg_te.cpp
@author Oleh Nikolaiev
@date 2019
*/

#include <dkg/dkg_te.h>

#include <iostream>

namespace encryption {

typedef std::vector<element_wrapper> Polynomial;

DkgTe::DkgTe(const size_t t, const size_t n) : t_(t), n_(n) {
pairing_init_set_str(this->pairing_, aparam);

element_init_G1(this->generator_, this->pairing_);

element_random(this->generator_);
while (element_is0(this->generator_)) {
element_random(this->generator_);
}
}

Polynomial DkgTe::GeneratePolynomial() {
Polynomial pol(this->t_);

for (size_t i = 0; i < this->t_; ++i) {
element_t g;
element_init_Zr(g, this->pairing_);
element_random(g);

while (i == this->t_ - 1 && element_is0(g)) {
element_random(g);
}

pol[i] = element_wrapper(g);

element_clear(g);
}

return pol;
}

std::vector<element_wrapper> DkgTe::CreateVerificationVector(
const std::vector<element_wrapper>& polynomial) {
std::vector<element_wrapper> verification_vector(this->t_);

for (size_t i = 0; i < this->t_; ++i) {
element_t tmp;
element_init_G1(tmp, this->pairing_);
element_mul_zn(tmp, this->generator_, polynomial[i].el_);

verification_vector[i] = element_wrapper(tmp);

element_clear(tmp);
}

return verification_vector;
}

element_wrapper DkgTe::ComputePolynomialValue(const std::vector<element_wrapper>& polynomial,
const element_wrapper& point) {
element_t value;
element_init_Zr(value, this->pairing_);
element_set0(value);

element_t pow;
element_init_Zr(pow, this->pairing_);
element_set1(pow);

for (size_t i = 0; i < this->t_; ++i) {
if (i == this->t_ - 1 && element_is0(polynomial[i].el_)) {
throw std::runtime_error("Error, incorrect degree of a polynomial");
}
element_t tmp;
element_init_Zr(tmp, this->pairing_);
element_mul(tmp, polynomial[i].el_, pow);

element_t tmp1;
element_init_Zr(tmp1, this->pairing_);
element_set(tmp1, value);

element_add(value, tmp1, tmp);

element_clear(tmp1);

element_clear(tmp);

element_init_Zr(tmp, this->pairing_);
element_set(tmp, pow);

element_mul(pow, tmp, point.el_);

element_clear(tmp);
}

element_clear(pow);

return element_wrapper(value);
}

std::vector<element_wrapper> DkgTe::CreateSecretKeyContribution(
const std::vector<element_wrapper>& polynomial) {
std::vector<element_wrapper> secret_key_contribution(this->n_);
for (size_t i = 0; i < this->n_; ++i) {
element_t point;
element_init_Zr(point, this->pairing_);
element_set_si(point, i + 1);

secret_key_contribution[i] = ComputePolynomialValue(polynomial, point);
}

return secret_key_contribution;
}

element_wrapper DkgTe::CreateSecretKeyShare(
const std::vector<element_wrapper>& secret_key_contribution) {
element_t secret_key_share;
element_init_Zr(secret_key_share, this->pairing_);
element_set0(secret_key_share);

for (size_t i = 0; i < this->n_; ++i) {
element_t tmp;
element_init_Zr(tmp, this->pairing_);

element_set(tmp, secret_key_share);
element_add(secret_key_share, tmp, secret_key_contribution[i].el_);
}

if (element_is0(secret_key_share)) {
throw std::runtime_error("Error, at least one secret key share is equal to zero");
}

return secret_key_share;
}

bool DkgTe::Verify(size_t idx, const element_wrapper& share,
const std::vector<element_wrapper>& verification_vector) {
element_t value;
element_init_G1(value, this->pairing_);

for (size_t i = 0; i < this->t_; ++i) {
element_t tmp1;
element_init_Zr(tmp1, this->pairing_);
element_set_si(tmp1, idx + 1);

element_t tmp2;
element_init_Zr(tmp2, this->pairing_);
element_set_si(tmp2, i);

element_t tmp3;
element_init_Zr(tmp3, this->pairing_);
element_pow_zn(tmp3, tmp1, tmp2);

element_t tmp4;
element_init_G1(tmp4, this->pairing_);
element_mul_zn(tmp4, verification_vector[i].el_, tmp3);

if (i == 0) {
element_set(value, tmp4);
} else {
element_t tmp;
element_init_G1(tmp, this->pairing_);
element_set(tmp, value);

element_clear(value);
element_init_G1(value, this->pairing_);

element_add(value, tmp, tmp4);

element_clear(tmp);
}

element_clear(tmp1);
element_clear(tmp2);
element_clear(tmp3);
element_clear(tmp4);
}

element_t mul;
element_init_G1(mul, this->pairing_);
element_mul_zn(mul, this->generator_, share.el_);

return (element_cmp(value, mul) == 0);
}

} // namespace encryption
61 changes: 61 additions & 0 deletions dkg/dkg_te.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
Copyright (C) 2018-2019 SKALE Labs
This file is part of libBLS.
libBLS is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
libBLS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with libBLS. If not, see <https://www.gnu.org/licenses/>.
@file dkg_te.h
@author Oleh Nikolaiev
@date 2019
*/

#pragma once

#include <threshold_encryption.h>

namespace encryption {

class DkgTe {
public:
pairing_t pairing_;

DkgTe(const size_t t, const size_t n);

std::vector<element_wrapper> GeneratePolynomial();

std::vector<element_wrapper> CreateVerificationVector(
const std::vector<element_wrapper>& polynomial);

element_wrapper ComputePolynomialValue(const std::vector<element_wrapper>& polynomial,
const element_wrapper& point);

std::vector<element_wrapper> CreateSecretKeyContribution(
const std::vector<element_wrapper>& polynomial);

element_wrapper CreateSecretKeyShare(
const std::vector<element_wrapper>& secret_key_contribution);

bool Verify(size_t idx, const element_wrapper& share,
const std::vector<element_wrapper>& verification_vector);

private:
const size_t t_ = 0;

const size_t n_ = 0;

element_t generator_ = {0};
};

} // namespace encryption
118 changes: 118 additions & 0 deletions test/unit_tests_dkg_te.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
Copyright (C) 2018-2019 SKALE Labs
This file is part of libBLS.
libBLS is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
libBLS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with libBLS. If not, see <http:https://www.gnu.org/licenses/>.
@file unit_tests_dkg_te.cpp
@author Oleh Nikolaiev
@date 2019
*/

#include <dkg/dkg_te.h>

#define BOOST_TEST_MODULE

#include <boost/test/included/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(DkgTeAlgorithm)

BOOST_AUTO_TEST_CASE(PolynomialValue) {
encryption::DkgTe obj = encryption::DkgTe(3, 4);
std::vector<encryption::element_wrapper> polynomial;

for (size_t i = 0; i < 3; ++i) {
element_t tmp;
element_init_Zr(tmp, obj.pairing_);
element_set_si(tmp, (i % 2 == 0 ? 1 : 0));

polynomial.push_back(encryption::element_wrapper(tmp));
}

element_t five;
element_init_Zr(five, obj.pairing_);
element_set_si(five, 5);

encryption::element_wrapper value = obj.ComputePolynomialValue(polynomial, encryption::element_wrapper(five));

element_t twenty_six;
element_init_Zr(twenty_six, obj.pairing_);
element_set_si(twenty_six, 26);

BOOST_REQUIRE(!element_cmp(twenty_six, value.el_)); // element_cmp(a, b) returns false iff a == b

value.clear();
polynomial.clear();

for (size_t i = 0; i < 3; ++i) {
element_t tmp;
element_init_Zr(tmp, obj.pairing_);
element_set_si(tmp, (i % 2 == 0 ? 0 : 1));

polynomial.push_back(encryption::element_wrapper(tmp));
}

bool is_exception_caught = false;

try {
value = obj.ComputePolynomialValue(polynomial, encryption::element_wrapper(five));
} catch(std::runtime_error) {
is_exception_caught = true;
}

BOOST_REQUIRE(is_exception_caught);

std::cout << "OK\n";
}

BOOST_AUTO_TEST_CASE(Verification) {
encryption::DkgTe obj = encryption::DkgTe(2, 2);

auto polynomial_fst = obj.GeneratePolynomial();
auto polynomial_snd = obj.GeneratePolynomial();

auto verification_vector_fst = obj.CreateVerificationVector(polynomial_fst);
auto verification_vector_snd = obj.CreateVerificationVector(polynomial_snd);

encryption::element_wrapper shared_by_fst_to_snd = obj.CreateSecretKeyContribution(polynomial_snd)[1];
encryption::element_wrapper shared_by_snd_to_fst = obj.CreateSecretKeyContribution(polynomial_fst)[0];

BOOST_REQUIRE(obj.Verify(0, shared_by_snd_to_fst, verification_vector_fst));
BOOST_REQUIRE(obj.Verify(1, shared_by_fst_to_snd, verification_vector_snd));

element_t rand;
element_init_Zr(rand, obj.pairing_);
element_random(rand);

element_t sum;
element_init_Zr(sum, obj.pairing_);
element_add(sum, rand, shared_by_snd_to_fst.el_);

BOOST_REQUIRE(obj.Verify(0, sum, verification_vector_fst) == false);

std::cout << "OK\n";

element_clear(sum);
element_clear(rand);

element_init_Zr(rand, obj.pairing_);
element_random(rand);

element_init_Zr(sum, obj.pairing_);
element_add(sum, rand, shared_by_fst_to_snd.el_);
BOOST_REQUIRE(obj.Verify(1, sum, verification_vector_snd) == false);
}

BOOST_AUTO_TEST_SUITE_END()
Loading

0 comments on commit 770a942

Please sign in to comment.