Skip to content

Commit e275235

Browse files
author
Yura Zarudniy
authored
Feature/vrf (#56)
* start impl Signed-off-by: Yura Zarudniy <[email protected]> * continue Signed-off-by: Yura Zarudniy <[email protected]> * correct interface Signed-off-by: Yura Zarudniy <[email protected]> * fix Signed-off-by: Yura Zarudniy <[email protected]> * refactor Signed-off-by: Yura Zarudniy <[email protected]> * add vrfhash tests * add sketch for vrf provider test Signed-off-by: Yura Zarudniy <[email protected]> * fix sketch Signed-off-by: Yura Zarudniy <[email protected]> * remove debug output Signed-off-by: Yura Zarudniy <[email protected]> * implement vrf provider tests Signed-off-by: Yura Zarudniy <[email protected]> * fix review issues, refactore Signed-off-by: Yura Zarudniy <[email protected]> * remove structures already implemented in other PR Signed-off-by: Yura Zarudniy <[email protected]> * fix review issues, refactore Signed-off-by: Yura Zarudniy <[email protected]> * fix review issues Signed-off-by: Yura Zarudniy <[email protected]>
1 parent efd9f41 commit e275235

16 files changed

+544
-1
lines changed

core/common/blob.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ namespace fc::common {
101101
* @return
102102
*/
103103
static outcome::result<Blob<size_>> fromSpan(
104-
const gsl::span<uint8_t> &span) {
104+
const gsl::span<const uint8_t> &span) {
105105
if (span.size() != size_) {
106106
return BlobError::INCORRECT_LENGTH;
107107
}

core/crypto/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ add_subdirectory(blake2)
77
add_subdirectory(bls)
88
add_subdirectory(murmur)
99
add_subdirectory(randomness)
10+
add_subdirectory(vrf)

core/crypto/vrf/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
add_library(vrf_provider
5+
impl/vrf_provider_impl.cpp
6+
vrf_hash_encoder.cpp
7+
vrf_types.cpp
8+
)
9+
target_link_libraries(vrf_provider
10+
address
11+
blob
12+
buffer
13+
p2p::p2p_sha
14+
)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include "crypto/vrf/impl/vrf_provider_impl.hpp"
7+
#include "crypto/vrf/vrf_hash_encoder.hpp"
8+
9+
#include "common/outcome.hpp"
10+
11+
namespace fc::crypto::vrf {
12+
13+
VRFProviderImpl::VRFProviderImpl(
14+
std::shared_ptr<bls::BlsProvider> bls_provider)
15+
: bls_provider_(std::move(bls_provider)) {
16+
BOOST_ASSERT_MSG(bls_provider_ != nullptr, "bls provider is nullptr");
17+
}
18+
19+
outcome::result<VRFResult> VRFProviderImpl::computeVRF(
20+
const VRFSecretKey &secret_key, const VRFParams &params) const {
21+
OUTCOME_TRY(hash, encodeVrfParams(params));
22+
23+
auto &&result = bls_provider_->sign(hash, secret_key);
24+
if (!result) {
25+
return VRFError::SIGN_FAILED;
26+
}
27+
return result.value();
28+
}
29+
30+
outcome::result<bool> VRFProviderImpl::verifyVRF(
31+
const VRFPublicKey &public_key,
32+
const VRFParams &params,
33+
const VRFProof &proof) const {
34+
OUTCOME_TRY(hash, encodeVrfParams(params));
35+
auto &&res = bls_provider_->verifySignature(hash, proof, public_key);
36+
if (res.has_failure()) {
37+
return VRFError::VERIFICATION_FAILED;
38+
}
39+
return res.value();
40+
}
41+
} // namespace fc::crypto::vrf
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef CPP_FILECOIN_CORE_CRYPTO_VRF_IMPL_VRF_PROVIDER_IMPL_HPP
7+
#define CPP_FILECOIN_CORE_CRYPTO_VRF_IMPL_VRF_PROVIDER_IMPL_HPP
8+
9+
#include "crypto/bls/bls_provider.hpp"
10+
#include "crypto/vrf/vrf_provider.hpp"
11+
12+
namespace fc::crypto::vrf {
13+
14+
class VRFProviderImpl : public VRFProvider {
15+
public:
16+
~VRFProviderImpl() override = default;
17+
18+
explicit VRFProviderImpl(std::shared_ptr<bls::BlsProvider> bls_provider);
19+
20+
outcome::result<VRFResult> computeVRF(
21+
const VRFSecretKey &secret_key, const VRFParams &params) const override;
22+
23+
outcome::result<bool> verifyVRF(const VRFPublicKey &public_key,
24+
const VRFParams &message,
25+
const VRFProof &vrf_proof) const override;
26+
27+
private:
28+
std::shared_ptr<bls::BlsProvider> bls_provider_;
29+
};
30+
31+
} // namespace fc::crypto::vrf
32+
33+
#endif // CPP_FILECOIN_CORE_CRYPTO_VRF_IMPL_VRF_PROVIDER_IMPL_HPP

core/crypto/vrf/vrf_hash_encoder.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include "crypto/vrf/vrf_hash_encoder.hpp"
7+
8+
#include <libp2p/crypto/sha/sha256.hpp>
9+
#include "common/le_encoder.hpp"
10+
#include "primitives/address/address_codec.hpp"
11+
12+
namespace fc::crypto::vrf {
13+
using primitives::address::Protocol;
14+
15+
outcome::result<VRFHash> encodeVrfParams(const VRFParams &params) {
16+
if (params.miner_address.getProtocol() != Protocol::BLS) {
17+
return VRFError::ADDRESS_IS_NOT_BLS;
18+
}
19+
auto &&miner_bytes = primitives::address::encode(params.miner_address);
20+
21+
common::Buffer out{};
22+
auto required_bytes = sizeof(uint64_t) + 2 * sizeof(uint8_t)
23+
+ params.message.size() + miner_bytes.size();
24+
out.reserve(required_bytes);
25+
common::encodeInteger(static_cast<uint64_t>(params.personalization_tag),
26+
out);
27+
out.putUint8(0u);
28+
out.putBuffer(params.message);
29+
out.putUint8(0u);
30+
out.put(miner_bytes);
31+
32+
auto hash = libp2p::crypto::sha256(out);
33+
34+
return VRFHash::fromSpan(hash);
35+
}
36+
37+
} // namespace fc::crypto::vrf

core/crypto/vrf/vrf_hash_encoder.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef CPP_FILECOIN_CORE_CRYPTO_VRF_VRF_HASH_ENCODER_HPP
7+
#define CPP_FILECOIN_CORE_CRYPTO_VRF_VRF_HASH_ENCODER_HPP
8+
9+
#include "crypto/vrf/vrf_types.hpp"
10+
11+
namespace fc::crypto::vrf {
12+
13+
/**
14+
* @brief encodeVrfParams function used to create VRFHash according to lotus
15+
* hash implementation:
16+
* https://github.com/filecoin-project/lotus/blob/1914412adf3c81028fcc305b887ca8ad189bc2dc/chain/gen/gen.go#L579
17+
* @param params vrf parameters
18+
* @return hash value or error
19+
*/
20+
outcome::result<VRFHash> encodeVrfParams(const VRFParams &params);
21+
} // namespace fc::crypto::vrf
22+
23+
#endif // CPP_FILECOIN_CORE_CRYPTO_VRF_VRF_HASH_ENCODER_HPP

core/crypto/vrf/vrf_provider.hpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef CPP_FILECOIN_CORE_CRYPTO_VRF_VRF_PROVIDER_HPP
7+
#define CPP_FILECOIN_CORE_CRYPTO_VRF_VRF_PROVIDER_HPP
8+
9+
#include "crypto/vrf/vrf_types.hpp"
10+
11+
namespace fc::crypto::vrf {
12+
13+
/**
14+
* @class VRFProvider provides VRF functionality according to
15+
* https://github.com/filecoin-project/lotus/blob/1914412adf3c81028fcc305b887ca8ad189bc2dc/chain/gen/gen.go#L597
16+
*/
17+
class VRFProvider {
18+
public:
19+
using Address = primitives::address::Address;
20+
using Buffer = common::Buffer;
21+
22+
virtual ~VRFProvider() = default;
23+
24+
/**
25+
* @brief calculates vrf signature
26+
* @param secret_key worker's secret key
27+
* @param params vrf parameters
28+
* @return generated signature or error
29+
*/
30+
virtual outcome::result<VRFResult> computeVRF(
31+
const VRFSecretKey &secret_key, const VRFParams &params) const = 0;
32+
33+
/**
34+
* @brief verifies message against signature and public key
35+
* @param public_key worker's public key
36+
* @param params vrf parameters
37+
* @param proof vrf proof
38+
* @return result of verification or error
39+
*/
40+
virtual outcome::result<bool> verifyVRF(const VRFPublicKey &public_key,
41+
const VRFParams &params,
42+
const VRFProof &proof) const = 0;
43+
};
44+
45+
} // namespace fc::crypto::vrf
46+
47+
#endif // CPP_FILECOIN_CORE_CRYPTO_VRF_VRF_PROVIDER_HPP

core/crypto/vrf/vrf_types.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include "crypto/vrf/vrf_types.hpp"
7+
8+
OUTCOME_CPP_DEFINE_CATEGORY(fc::crypto::vrf, VRFError, e) {
9+
using fc::crypto::vrf::VRFError;
10+
switch (e) {
11+
case (VRFError::MINER_ADDRESS_NOT_ID):
12+
return "miner address has to be of ID type to calculate hash";
13+
case VRFError::VERIFICATION_FAILED:
14+
return "VRF verification failed";
15+
case VRFError::SIGN_FAILED:
16+
return "VRF message sign failed";
17+
case VRFError::ADDRESS_IS_NOT_BLS:
18+
return "cannot make VRF hash on address, which is not BLS";
19+
}
20+
21+
return "unknown error";
22+
}

core/crypto/vrf/vrf_types.hpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef CPP_FILECOIN_CORE_CRYPTO_VRF_VRF_TYPES_HPP
7+
#define CPP_FILECOIN_CORE_CRYPTO_VRF_VRF_TYPES_HPP
8+
9+
#include "common/blob.hpp"
10+
#include "common/buffer.hpp"
11+
#include "crypto/bls/bls_types.hpp"
12+
#include "crypto/randomness/randomness_types.hpp"
13+
#include "primitives/address/address.hpp"
14+
15+
namespace fc::crypto::vrf {
16+
17+
/**
18+
* @brief vrf public key type
19+
*/
20+
using VRFPublicKey = bls::PublicKey;
21+
/**
22+
* @brief vrf secret key type
23+
*/
24+
using VRFSecretKey = bls::PrivateKey;
25+
/**
26+
* @brief vrf proof value
27+
*/
28+
using VRFProof = bls::Signature;
29+
30+
/**
31+
* @brief result of computing vrf
32+
*/
33+
using VRFResult = bls::Signature;
34+
35+
/**
36+
* @brief return value of vrf hash encode
37+
*/
38+
using VRFHash = common::Hash256;
39+
40+
/**
41+
* @brief vrf parameters structure
42+
*/
43+
struct VRFParams {
44+
randomness::DomainSeparationTag personalization_tag;
45+
primitives::address::Address miner_address;
46+
common::Buffer message;
47+
};
48+
49+
/**
50+
* @brief VRF key pair definition
51+
*/
52+
struct VRFKeyPair {
53+
VRFPublicKey public_key;
54+
VRFSecretKey secret_key;
55+
};
56+
57+
/**
58+
* @brief vrf errors enumeration
59+
*/
60+
enum class VRFError {
61+
MINER_ADDRESS_NOT_ID =
62+
1, // miner address need to be id type to calculate hash
63+
VERIFICATION_FAILED, // vrf verification failed
64+
SIGN_FAILED, // vrf sing message failed
65+
ADDRESS_IS_NOT_BLS, // vrf hash can be based only on bls
66+
};
67+
} // namespace fc::crypto::vrf
68+
69+
OUTCOME_HPP_DECLARE_ERROR(fc::crypto::vrf, VRFError)
70+
71+
#endif // CPP_FILECOIN_CORE_CRYPTO_VRF_VRF_TYPES_HPP

0 commit comments

Comments
 (0)