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
17namespace ccf::crypto
18{
19 namespace sharing
20 {
21 // We get (almost) 31 bits of entropy per limb, hence to get 256 bits of
22 // entropy of derived key material, with 80 bits of safety margin,
23 // ((256+80)/31) = 10 limbs.
24 static constexpr size_t LIMBS = 10;
25 static constexpr const char* key_label = "CCF Wrapping Key v1";
26
27 struct Share
28 {
29 // Index in a re-share, 0 is a full key, and 1+ is a partial share
30 uint32_t x = 0;
31 uint32_t y[LIMBS];
32 constexpr static size_t serialised_size =
33 sizeof(uint32_t) + sizeof(uint32_t) * LIMBS;
34
35 Share() = default;
36 bool operator==(const Share& other) const = default;
37
39 {
40 OPENSSL_cleanse(y, sizeof(y));
41 };
42
43 HashBytes key(size_t key_size) const
44 {
45 if (x != 0)
46 {
47 throw std::invalid_argument(
48 "Cannot derive a key from a partial share");
49 }
50 const std::span<const uint8_t> ikm(
51 reinterpret_cast<const uint8_t*>(y), sizeof(y));
52 const std::span<const uint8_t> label(
53 reinterpret_cast<const uint8_t*>(y), sizeof(y));
54 auto k = ccf::crypto::hkdf(
55 ccf::crypto::MDType::SHA256, key_size, ikm, {}, label);
56 return k;
57 }
58
59 void serialise(std::vector<uint8_t>& serialised) const
60 {
61 auto size = serialised_size;
62 if (serialised.size() != size)
63 {
64 throw std::invalid_argument("Invalid serialised share size");
65 }
66
67 auto data = serialised.data();
68 serialized::write(data, size, x);
69 for (size_t i = 0; i < LIMBS; ++i)
70 {
71 serialized::write(data, size, y[i]);
72 }
73 }
74
75 Share(const std::span<uint8_t const>& serialised)
76 {
77 if (serialised.size() != serialised_size)
78 {
79 throw std::invalid_argument("Invalid serialised share size");
80 }
81 auto data = serialised.data();
82 auto size = serialised.size();
83 x = serialized::read<uint32_t>(data, size);
84 for (size_t i = 0; i < LIMBS; ++i)
85 {
86 y[i] = serialized::read<uint32_t>(data, size);
87 }
88 }
89
90 std::string to_str() const
91 {
92 return fmt::format("x: {} y: {}", x, fmt::join(y, ", "));
93 }
94 };
95
96 // Exposed for testing only
97 using element = uint64_t;
99
113 Share& raw_secret, const std::span<Share>& shares, size_t threshold);
114
128 Share& raw_secret,
129 const std::span<Share const>& shares,
130 size_t threshold);
131 }
132}
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
Definition base64.h:10
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:106
Definition sharing.h:28
bool operator==(const Share &other) const =default
static constexpr size_t serialised_size
Definition sharing.h:32
HashBytes key(size_t key_size) const
Definition sharing.h:43
Share(const std::span< uint8_t const > &serialised)
Definition sharing.h:75
uint32_t y[LIMBS]
Definition sharing.h:31
void serialise(std::vector< uint8_t > &serialised) const
Definition sharing.h:59
~Share()
Definition sharing.h:38
std::string to_str() const
Definition sharing.h:90
uint32_t x
Definition sharing.h:30