CCF
Loading...
Searching...
No Matches
sharing.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
5#include <cstddef>
6#include <cstdint>
7#include <span>
8
9#define FMT_HEADER_ONLY
10#include "ccf/crypto/hkdf.h"
11#include "ccf/crypto/sha256.h"
12#include "ds/serialized.h"
13#include "openssl/crypto.h"
14
15#include <fmt/format.h>
16
18{
19 // We get (almost) 31 bits of entropy per limb, hence to get 256 bits of
20 // entropy of derived key material, with 80 bits of safety margin,
21 // ((256+80)/31) = 10 limbs.
22 static constexpr size_t LIMBS = 10;
23 static constexpr const char* key_label = "CCF Wrapping Key v1";
24
25 struct Share
26 {
27 // Index in a re-share, 0 is a full key, and 1+ is a partial share
28 uint32_t x = 0;
29 uint32_t y[LIMBS] = {};
30 constexpr static size_t serialised_size =
31 sizeof(uint32_t) + sizeof(uint32_t) * LIMBS;
32
33 Share() = default;
34 bool operator==(const Share& other) const = default;
35
37 {
38 OPENSSL_cleanse(y, sizeof(y));
39 };
40
41 [[nodiscard]] HashBytes key(size_t key_size) const
42 {
43 if (x != 0)
44 {
45 throw std::invalid_argument("Cannot derive a key from a partial share");
46 }
47 const std::span<const uint8_t> ikm(
48 reinterpret_cast<const uint8_t*>(y), sizeof(y));
49 const std::span<const uint8_t> label(
50 reinterpret_cast<const uint8_t*>(y), sizeof(y));
51 auto k = ccf::crypto::hkdf(
52 ccf::crypto::MDType::SHA256, key_size, ikm, {}, label);
53 return k;
54 }
55
56 void serialise(std::vector<uint8_t>& serialised) const
57 {
58 auto size = serialised_size;
59 if (serialised.size() != size)
60 {
61 throw std::invalid_argument("Invalid serialised share size");
62 }
63
64 auto* data = serialised.data();
65 serialized::write(data, size, x);
66 // NOLINTNEXTLINE(modernize-loop-convert)
67 for (size_t i = 0; i < LIMBS; ++i)
68 {
69 serialized::write(data, size, y[i]);
70 }
71 }
72
73 Share(const std::span<uint8_t const>& serialised)
74 {
75 if (serialised.size() != serialised_size)
76 {
77 throw std::invalid_argument("Invalid serialised share size");
78 }
79 const auto* data = serialised.data();
80 auto size = serialised.size();
81 x = serialized::read<uint32_t>(data, size);
82 // NOLINTNEXTLINE(modernize-loop-convert)
83 for (size_t i = 0; i < LIMBS; ++i)
84 {
85 y[i] = serialized::read<uint32_t>(data, size);
86 }
87 }
88
89 [[nodiscard]] std::string to_str() const
90 {
91 return fmt::format("x: {} y: {}", x, fmt::join(y, ", "));
92 }
93 };
94
95 // Exposed for testing only
96 using element = uint64_t;
98
112 Share& raw_secret, const std::span<Share>& shares, size_t threshold);
113
127 Share& raw_secret, const std::span<Share const>& shares, size_t threshold);
128}
Definition sharing.cpp:10
uint64_t element
Definition sharing.cpp:20
element ct_reduce(element x)
Definition sharing.cpp:37
void sample_secret_and_shares(Share &raw_secret, const std::span< Share > &shares, size_t threshold)
Definition sharing.cpp:136
void recover_unauthenticated_secret(Share &raw_secret, const std::span< Share const > &shares, size_t threshold)
Definition sharing.cpp:171
std::vector< uint8_t > hkdf(MDType md_type, size_t length, const std::span< const uint8_t > &ikm, const std::span< const uint8_t > &salt={}, const std::span< const uint8_t > &info={})
Definition hash.cpp:51
std::vector< uint8_t > HashBytes
Definition hash_bytes.h:10
void write(uint8_t *&data, size_t &size, const T &v)
Definition serialized.h:105
Definition sharing.h:26
bool operator==(const Share &other) const =default
static constexpr size_t serialised_size
Definition sharing.h:30
HashBytes key(size_t key_size) const
Definition sharing.h:41
Share(const std::span< uint8_t const > &serialised)
Definition sharing.h:73
uint32_t y[LIMBS]
Definition sharing.h:29
void serialise(std::vector< uint8_t > &serialised) const
Definition sharing.h:56
~Share()
Definition sharing.h:36
std::string to_str() const
Definition sharing.h:89
uint32_t x
Definition sharing.h:28