diff options
Diffstat (limited to 'src/crypto.h')
-rw-r--r-- | src/crypto.h | 386 |
1 files changed, 0 insertions, 386 deletions
diff --git a/src/crypto.h b/src/crypto.h deleted file mode 100644 index 2fbf745..0000000 --- a/src/crypto.h +++ /dev/null @@ -1,386 +0,0 @@ -#ifndef _HOTSTUFF_CRYPTO_H -#define _HOTSTUFF_CRYPTO_H - -#include "salticidae/crypto.h" -#include "salticidae/ref.h" -#include "secp256k1.h" -#include <openssl/rand.h> -#include "type.h" - -using salticidae::RcObj; -using salticidae::BoxObj; - -namespace hotstuff { - -using salticidae::SHA256; - -class PubKey: public Serializable, Cloneable { - public: - virtual ~PubKey() = default; - virtual PubKey *clone() override = 0; -}; - -using pubkey_bt = BoxObj<PubKey>; - -class PrivKey: public Serializable { - public: - virtual ~PrivKey() = default; - virtual pubkey_bt get_pubkey() const = 0; - virtual void from_rand() = 0; -}; - -using privkey_bt = BoxObj<PrivKey>; - -class PartCert: public Serializable, public Cloneable { - public: - virtual ~PartCert() = default; - virtual bool verify(const PubKey &pubkey) = 0; - virtual const uint256_t &get_blk_hash() const = 0; - virtual PartCert *clone() override = 0; -}; - -class ReplicaConfig; - -class QuorumCert: public Serializable, public Cloneable { - public: - virtual ~QuorumCert() = default; - virtual void add_part(ReplicaID replica, const PartCert &pc) = 0; - virtual void compute() = 0; - virtual bool verify(const ReplicaConfig &config) = 0; - virtual const uint256_t &get_blk_hash() const = 0; - virtual QuorumCert *clone() override = 0; -}; - -using part_cert_bt = BoxObj<PartCert>; -using quorum_cert_bt = BoxObj<QuorumCert>; - -class PubKeyDummy: public PubKey { - PubKeyDummy *clone() override { return new PubKeyDummy(*this); } - void serialize(DataStream &) const override {} - void unserialize(DataStream &) override {} -}; - -class PrivKeyDummy: public PrivKey { - pubkey_bt get_pubkey() const override { return new PubKeyDummy(); } - void serialize(DataStream &) const override {} - void unserialize(DataStream &) override {} - void from_rand() override {} -}; - -class PartCertDummy: public PartCert { - uint256_t blk_hash; - public: - PartCertDummy() {} - PartCertDummy(const uint256_t &blk_hash): - blk_hash(blk_hash) {} - - void serialize(DataStream &s) const override { - s << (uint32_t)0 << blk_hash; - } - - void unserialize(DataStream &s) override { - uint32_t tmp; - s >> tmp >> blk_hash; - } - - PartCert *clone() override { - return new PartCertDummy(blk_hash); - } - - bool verify(const PubKey &) override { return true; } - - const uint256_t &get_blk_hash() const override { return blk_hash; } -}; - -class QuorumCertDummy: public QuorumCert { - uint256_t blk_hash; - public: - QuorumCertDummy() {} - QuorumCertDummy(const ReplicaConfig &, const uint256_t &blk_hash): - blk_hash(blk_hash) {} - - void serialize(DataStream &s) const override { - s << (uint32_t)1 << blk_hash; - } - - void unserialize(DataStream &s) override { - uint32_t tmp; - s >> tmp >> blk_hash; - } - - QuorumCert *clone() override { - return new QuorumCertDummy(*this); - } - - void add_part(ReplicaID, const PartCert &) override {} - void compute() override {} - bool verify(const ReplicaConfig &) override { return true; } - - const uint256_t &get_blk_hash() const override { return blk_hash; } -}; - - -class Secp256k1Context { - secp256k1_context *ctx; - friend class PubKeySecp256k1; - friend class SigSecp256k1; - public: - Secp256k1Context(bool sign = false): - ctx(secp256k1_context_create( - sign ? SECP256K1_CONTEXT_SIGN : - SECP256K1_CONTEXT_VERIFY)) {} - - Secp256k1Context(const Secp256k1Context &) = delete; - - Secp256k1Context(Secp256k1Context &&other): ctx(other.ctx) { - other.ctx = nullptr; - } - - ~Secp256k1Context() { - if (ctx) secp256k1_context_destroy(ctx); - } -}; - -using secp256k1_context_t = RcObj<Secp256k1Context>; - -extern secp256k1_context_t secp256k1_default_sign_ctx; -extern secp256k1_context_t secp256k1_default_verify_ctx; - -class PrivKeySecp256k1; - -class PubKeySecp256k1: public PubKey { - static const auto _olen = 33; - friend class SigSecp256k1; - secp256k1_pubkey data; - secp256k1_context_t ctx; - - public: - PubKeySecp256k1(const secp256k1_context_t &ctx = - secp256k1_default_sign_ctx): - PubKey(), ctx(ctx) {} - - PubKeySecp256k1(const bytearray_t &raw_bytes, - const secp256k1_context_t &ctx = - secp256k1_default_sign_ctx): - PubKeySecp256k1(ctx) { from_bytes(raw_bytes); } - - inline PubKeySecp256k1(const PrivKeySecp256k1 &priv_key, - const secp256k1_context_t &ctx = - secp256k1_default_sign_ctx); - - void serialize(DataStream &s) const override { - static uint8_t output[_olen]; - size_t olen = _olen; - (void)secp256k1_ec_pubkey_serialize( - ctx->ctx, (unsigned char *)output, - &olen, &data, SECP256K1_EC_COMPRESSED); - s.put_data(output, output + _olen); - } - - void unserialize(DataStream &s) override { - static const auto _exc = std::invalid_argument("ill-formed public key"); - try { - if (!secp256k1_ec_pubkey_parse( - ctx->ctx, &data, s.get_data_inplace(_olen), _olen)) - throw _exc; - } catch (std::ios_base::failure &) { - throw _exc; - } - } - - PubKeySecp256k1 *clone() override { - return new PubKeySecp256k1(*this); - } -}; - -class PrivKeySecp256k1: public PrivKey { - static const auto nbytes = 32; - friend class PubKeySecp256k1; - friend class SigSecp256k1; - uint8_t data[nbytes]; - secp256k1_context_t ctx; - - public: - PrivKeySecp256k1(const secp256k1_context_t &ctx = - secp256k1_default_sign_ctx): - PrivKey(), ctx(ctx) {} - - PrivKeySecp256k1(const bytearray_t &raw_bytes, - const secp256k1_context_t &ctx = - secp256k1_default_sign_ctx): - PrivKeySecp256k1(ctx) { from_bytes(raw_bytes); } - - void serialize(DataStream &s) const override { - s.put_data(data, data + nbytes); - } - - void unserialize(DataStream &s) override { - static const auto _exc = std::invalid_argument("ill-formed private key"); - try { - memmove(data, s.get_data_inplace(nbytes), nbytes); - } catch (std::ios_base::failure &) { - throw _exc; - } - } - - void from_rand() override { - if (!RAND_bytes(data, nbytes)) - throw std::runtime_error("cannot get rand bytes from openssl"); - } - - inline pubkey_bt get_pubkey() const override; -}; - -pubkey_bt PrivKeySecp256k1::get_pubkey() const { - return new PubKeySecp256k1(*this, ctx); -} - -PubKeySecp256k1::PubKeySecp256k1( - const PrivKeySecp256k1 &priv_key, - const secp256k1_context_t &ctx): PubKey(), ctx(ctx) { - if (!secp256k1_ec_pubkey_create(ctx->ctx, &data, priv_key.data)) - throw std::invalid_argument("invalid secp256k1 private key"); -} - -class SigSecp256k1: public Serializable { - secp256k1_ecdsa_signature data; - secp256k1_context_t ctx; - - void check_msg_length(const bytearray_t &msg) { - if (msg.size() != 32) - throw std::invalid_argument("the message should be 32-bytes"); - } - - public: - SigSecp256k1(const secp256k1_context_t &ctx = - secp256k1_default_sign_ctx): - Serializable(), ctx(ctx) {} - SigSecp256k1(const uint256_t &digest, - const PrivKeySecp256k1 &priv_key, - secp256k1_context_t &ctx = - secp256k1_default_sign_ctx): - Serializable(), ctx(ctx) { - sign(digest, priv_key); - } - - void serialize(DataStream &s) const override { - static uint8_t output[64]; - (void)secp256k1_ecdsa_signature_serialize_compact( - ctx->ctx, (unsigned char *)output, - &data); - s.put_data(output, output + 64); - } - - void unserialize(DataStream &s) override { - static const auto _exc = std::invalid_argument("ill-formed signature"); - try { - if (!secp256k1_ecdsa_signature_parse_compact( - ctx->ctx, &data, s.get_data_inplace(64))) - throw _exc; - } catch (std::ios_base::failure &) { - throw _exc; - } - } - - void sign(const bytearray_t &msg, const PrivKeySecp256k1 &priv_key) { - check_msg_length(msg); - if (!secp256k1_ecdsa_sign( - ctx->ctx, &data, - (unsigned char *)&*msg.begin(), - (unsigned char *)priv_key.data, - NULL, // default nonce function - NULL)) - throw std::invalid_argument("failed to create secp256k1 signature"); - } - - bool verify(const bytearray_t &msg, const PubKeySecp256k1 &pub_key, - const secp256k1_context_t &_ctx) { - check_msg_length(msg); - return secp256k1_ecdsa_verify( - _ctx->ctx, &data, - (unsigned char *)&*msg.begin(), - &pub_key.data) == 1; - } - - bool verify(const bytearray_t &msg, const PubKeySecp256k1 &pub_key) { - return verify(msg, pub_key, ctx); - } -}; - -class PartCertSecp256k1: public SigSecp256k1, public PartCert { - uint256_t blk_hash; - - public: - PartCertSecp256k1() = default; - PartCertSecp256k1(const PrivKeySecp256k1 &priv_key, const uint256_t &blk_hash): - SigSecp256k1(blk_hash, priv_key), - PartCert(), - blk_hash(blk_hash) {} - - bool verify(const PubKey &pub_key) override { - return SigSecp256k1::verify(blk_hash, - static_cast<const PubKeySecp256k1 &>(pub_key), - secp256k1_default_verify_ctx); - } - - const uint256_t &get_blk_hash() const override { return blk_hash; } - - PartCertSecp256k1 *clone() override { - return new PartCertSecp256k1(*this); - } - - void serialize(DataStream &s) const override { - s << blk_hash; - this->SigSecp256k1::serialize(s); - } - - void unserialize(DataStream &s) override { - s >> blk_hash; - this->SigSecp256k1::unserialize(s); - } -}; - -class QuorumCertSecp256k1: public QuorumCert { - uint256_t blk_hash; - salticidae::Bits rids; - std::vector<SigSecp256k1> sigs; - - public: - QuorumCertSecp256k1() = default; - QuorumCertSecp256k1(const ReplicaConfig &config, const uint256_t &blk_hash); - - void add_part(ReplicaID rid, const PartCert &pc) override { - if (pc.get_blk_hash() != blk_hash) - throw std::invalid_argument("PartCert does match the block hash"); - if (!rids.get(rid)) - { - rids.set(rid); - sigs.push_back(static_cast<const PartCertSecp256k1 &>(pc)); - } - } - - void compute() override {} - - bool verify(const ReplicaConfig &config) override; - - const uint256_t &get_blk_hash() const override { return blk_hash; } - - QuorumCertSecp256k1 *clone() override { - return new QuorumCertSecp256k1(*this); - } - - void serialize(DataStream &s) const override { - s << blk_hash << rids; - for (const auto &sig: sigs) s << sig; - } - - void unserialize(DataStream &s) override { - s >> blk_hash >> rids; - sigs.resize(rids.size()); - for (auto &sig: sigs) s >> sig; - } -}; - -} - -#endif |