This commit is contained in:
Conrado Gouvea 2024-04-09 10:27:04 +01:00 committed by GitHub
commit 26cc50fce6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
43 changed files with 259 additions and 143 deletions

View File

@ -24,6 +24,22 @@ jobs:
with:
command: build
build_no_std:
name: build with no_std
runs-on: ubuntu-latest
# Skip ed448 which does not support it.
strategy:
matrix:
crate: [ristretto255, ed25519, p256, secp256k1, rerandomized]
steps:
- uses: actions/checkout@v4.1.1
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
targets: thumbv6m-none-eabi
- run: cargo build -p frost-${{ matrix.crate }} --no-default-features --target thumbv6m-none-eabi
- run: cargo build -p frost-${{ matrix.crate }} --no-default-features --features serialization --target thumbv6m-none-eabi
test_beta:
name: test on beta
runs-on: ubuntu-latest

View File

@ -4,6 +4,15 @@ Entries are listed in reverse chronological order.
## Unreleased
* Add no-std support to all crates except frost-ed448. To use, do not enable the
`std` feature that is enabled by default (i.e. use `default-features =
false`); Note that it always links to an external `alloc` crate (i.e. there is
no `alloc` feature). When disabling `std`, the only impact in the API is that
`Error` will no longer implement the `std::error::Error` trait. This is a
breaking change if you are disabling default features but rely on `Error`
implementing `std::error::Error`. In that case, simply enable the `std`
feature.
## Released
## 1.0.0

View File

@ -22,20 +22,21 @@ features = ["serde"]
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
byteorder = "1.4"
const-crc32 = "1.2.0"
byteorder = { version = "1.4", default-features = false }
const-crc32 = { version = "1.2.0", package = "const-crc32-nostd" }
document-features = "0.2.7"
debugless-unwrap = "0.0.4"
derive-getters = "0.3.0"
hex = "0.4.3"
postcard = { version = "1.0.0", features = ["use-std"], optional = true }
rand_core = "0.6"
serde = { version = "1.0.160", features = ["derive"], optional = true }
hex = { version = "0.4.3", default-features = false, features = ["alloc"] }
postcard = { version = "1.0.0", features = ["alloc"], optional = true }
rand_core = { version = "0.6", default-features = false }
serde = { version = "1.0.160", default-features = false, features = ["derive"], optional = true }
serdect = { version = "0.2.0", optional = true }
thiserror = "1.0"
thiserror-nostd-notrait = { version = "1.0", default-features = false }
thiserror = { version = "1.0", default-features = false, optional = true }
visibility = "0.1.0"
zeroize = { version = "1.5.4", default-features = false, features = ["derive"] }
itertools = "0.12.0"
itertools = { version = "0.12.0", default-features = false }
# Test dependencies used with the test-impl feature
proptest = { version = "1.0", optional = true }
@ -50,8 +51,10 @@ rand_chacha = "0.3"
serde_json = "1.0"
[features]
default = ["serialization", "cheater-detection"]
default = ["serialization", "cheater-detection", "std"]
#! ## Features
## Enable standard library support.
std = ["dep:thiserror"]
## Expose internal types, which do not have SemVer guarantees. This is an advanced
## feature which can be useful if you need to build a modified version of FROST.
## The docs won't list them, you will need to check the source code.
@ -62,7 +65,7 @@ internals = []
serde = ["dep:serde", "dep:serdect"]
serialization = ["serde", "dep:postcard"]
# Exposes ciphersuite-generic tests for other crates to use
test-impl = ["proptest", "serde_json", "criterion"]
test-impl = ["dep:proptest", "dep:serde_json", "dep:criterion"]
# Enable cheater detection
cheater-detection = []

View File

@ -7,8 +7,6 @@
//! of caller code (which must assemble a batch of signatures across
//! work-items), and loss of the ability to easily pinpoint failing signatures.
use std::iter::once;
use rand_core::{CryptoRng, RngCore};
use crate::{scalar_mul::VartimeMultiscalarMul, Ciphersuite, Element, *};
@ -132,7 +130,7 @@ where
VKs.push(item.vk.element);
}
let scalars = once(&P_coeff_acc)
let scalars = core::iter::once(&P_coeff_acc)
.chain(VK_coeffs.iter())
.chain(R_coeffs.iter());
@ -155,6 +153,8 @@ where
C: Ciphersuite,
{
fn default() -> Self {
Self { signatures: vec![] }
Self {
signatures: Vec::new(),
}
}
}

View File

@ -1,10 +1,12 @@
//! Ciphersuite-generic benchmark functions.
#![allow(clippy::unwrap_used)]
use std::collections::BTreeMap;
use core::iter;
use alloc::{collections::BTreeMap, format, vec::Vec};
use rand_core::{CryptoRng, RngCore};
use criterion::{BenchmarkId, Criterion, Throughput};
use rand_core::{CryptoRng, RngCore};
use crate as frost;
use crate::{batch, Ciphersuite, Signature, SigningKey, VerifyingKey};
@ -18,7 +20,7 @@ fn sigs_with_distinct_keys<C: Ciphersuite, R: RngCore + CryptoRng + Clone>(
rng: &mut R,
) -> impl Iterator<Item = Item<C>> {
let mut rng = rng.clone();
std::iter::repeat_with(move || {
iter::repeat_with(move || {
let msg = b"Bench";
let sk = SigningKey::new(&mut rng);
let vk = VerifyingKey::from(&sk);

View File

@ -1,7 +1,11 @@
//! FROST Error types
#[cfg(feature = "std")]
use thiserror::Error;
#[cfg(not(feature = "std"))]
use thiserror_nostd_notrait::Error;
use crate::{Ciphersuite, Identifier};
#[derive(Error, Debug, Clone, Copy, Eq, PartialEq)]

View File

@ -1,6 +1,6 @@
//! FROST participant identifiers
use std::{
use core::{
fmt::{self, Debug},
hash::{Hash, Hasher},
};
@ -117,7 +117,7 @@ impl<C> Ord for Identifier<C>
where
C: Ciphersuite,
{
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
let serialized_self = <<C::Group as Group>::Field>::little_endian_serialize(&self.0);
let serialized_other = <<C::Group as Group>::Field>::little_endian_serialize(&other.0);
// The default cmp uses lexicographic order; so we need the elements in big endian
@ -133,12 +133,12 @@ impl<C> PartialOrd for Identifier<C>
where
C: Ciphersuite,
{
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<C> std::ops::Mul<Scalar<C>> for Identifier<C>
impl<C> core::ops::Mul<Scalar<C>> for Identifier<C>
where
C: Ciphersuite,
{
@ -149,7 +149,7 @@ where
}
}
impl<C> std::ops::MulAssign<Identifier<C>> for Scalar<C>
impl<C> core::ops::MulAssign<Identifier<C>> for Scalar<C>
where
C: Ciphersuite,
{
@ -158,7 +158,7 @@ where
}
}
impl<C> std::ops::Sub for Identifier<C>
impl<C> core::ops::Sub for Identifier<C>
where
C: Ciphersuite,
{

View File

@ -1,12 +1,12 @@
//! FROST keys, keygen, key shares
#![allow(clippy::type_complexity)]
use std::{
collections::{BTreeMap, BTreeSet, HashSet},
convert::TryFrom,
default::Default,
use core::iter;
use alloc::vec::Vec;
use alloc::{
collections::{BTreeMap, BTreeSet},
fmt::{self, Debug},
iter,
};
use derive_getters::Getters;
@ -17,11 +17,12 @@ use rand_core::{CryptoRng, RngCore};
use zeroize::{DefaultIsZeroes, Zeroize};
use crate::{
serialization::{Deserialize, Serialize},
Ciphersuite, Element, Error, Field, Group, Header, Identifier, Scalar, SigningKey,
VerifyingKey,
Ciphersuite, Element, Error, Field, Group, Header, Identifier, Scalar, SigningKey, VerifyingKey,
};
#[cfg(feature = "serialization")]
use crate::serialization::{Deserialize, Serialize};
#[cfg(feature = "serde")]
use crate::serialization::{ElementSerialization, ScalarSerialization};
@ -126,7 +127,7 @@ impl<C> Debug for SigningShare<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("SigningShare").field(&"<redacted>").finish()
}
}
@ -325,7 +326,7 @@ impl<C> Debug for CoefficientCommitment<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("CoefficientCommitment")
.field(&hex::encode(self.serialize()))
.finish()
@ -900,7 +901,7 @@ pub(crate) fn generate_secret_shares<C: Ciphersuite>(
let (coefficients, commitment) =
generate_secret_polynomial(secret, max_signers, min_signers, coefficients)?;
let identifiers_set: HashSet<_> = identifiers.iter().collect();
let identifiers_set: BTreeSet<_> = identifiers.iter().collect();
if identifiers_set.len() != identifiers.len() {
return Err(Error::DuplicatedIdentifier);
}

View File

@ -30,7 +30,9 @@
//! [Feldman's VSS]: https://www.cs.umd.edu/~gasarch/TOPICS/secretsharing/feldmanVSS.pdf
//! [secure broadcast channel]: https://frost.zfnd.org/terminology.html#broadcast-channel
use std::{collections::BTreeMap, iter};
use core::iter;
use alloc::collections::BTreeMap;
use rand_core::{CryptoRng, RngCore};
@ -39,6 +41,9 @@ use crate::{
SigningKey, VerifyingKey,
};
#[cfg(feature = "serialization")]
use crate::serialization::{Deserialize, Serialize};
use super::{
evaluate_polynomial, generate_coefficients, generate_secret_polynomial,
validate_num_of_signers, KeyPackage, PublicKeyPackage, SecretShare, SigningShare,
@ -47,11 +52,10 @@ use super::{
/// DKG Round 1 structures.
pub mod round1 {
use alloc::vec::Vec;
use derive_getters::Getters;
use zeroize::Zeroize;
use crate::serialization::{Deserialize, Serialize};
use super::*;
/// The package that must be broadcast by each participant to all other participants
@ -135,11 +139,11 @@ pub mod round1 {
}
}
impl<C> std::fmt::Debug for SecretPackage<C>
impl<C> core::fmt::Debug for SecretPackage<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SecretPackage")
.field("identifier", &self.identifier)
.field("coefficients", &"<redacted>")
@ -167,7 +171,8 @@ pub mod round2 {
use derive_getters::Getters;
use zeroize::Zeroize;
use crate::serialization::{Deserialize, Serialize};
#[cfg(feature = "serialization")]
use alloc::vec::Vec;
use super::*;
@ -239,11 +244,11 @@ pub mod round2 {
pub(crate) max_signers: u16,
}
impl<C> std::fmt::Debug for SecretPackage<C>
impl<C> core::fmt::Debug for SecretPackage<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SecretPackage")
.field("identifier", &self.identifier)
.field("commitment", &self.commitment)

View File

@ -4,7 +4,9 @@
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
//! using a subset of the other signers know here as `helpers`.
use std::collections::{BTreeMap, BTreeSet};
use alloc::collections::{BTreeMap, BTreeSet};
use alloc::vec::Vec;
use crate::{
compute_lagrange_coefficient, Ciphersuite, CryptoRng, Error, Field, Group, Header, Identifier,

View File

@ -1,3 +1,4 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(non_snake_case)]
// It's emitting false positives; see https://github.com/rust-lang/rust-clippy/issues/9413
#![allow(clippy::derive_partial_eq_without_eq)]
@ -10,11 +11,15 @@
#![doc = include_str!("../README.md")]
#![doc = document_features::document_features!()]
use std::{
#[macro_use]
extern crate alloc;
use core::marker::PhantomData;
use alloc::{
collections::{BTreeMap, BTreeSet},
default::Default,
fmt::{self, Debug},
marker::PhantomData,
vec::Vec,
};
use derive_getters::Getters;
@ -87,7 +92,7 @@ impl<C> Debug for Challenge<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("Secret")
.field(&hex::encode(<<C::Group as Group>::Field>::serialize(
&self.0,
@ -111,7 +116,7 @@ fn challenge<C>(R: &Element<C>, verifying_key: &VerifyingKey<C>, msg: &[u8]) ->
where
C: Ciphersuite,
{
let mut preimage = vec![];
let mut preimage = Vec::new();
preimage.extend_from_slice(<C::Group>::serialize(R).as_ref());
preimage.extend_from_slice(<C::Group>::serialize(&verifying_key.element).as_ref());
@ -153,7 +158,7 @@ struct Header<C: Ciphersuite> {
serde(deserialize_with = "crate::serialization::ciphersuite_deserialize::<_, C>")
)]
ciphersuite: (),
#[serde(skip)]
#[cfg_attr(feature = "serde", serde(skip))]
phantom: PhantomData<C>,
}
@ -404,7 +409,7 @@ where
verifying_key: &VerifyingKey<C>,
additional_prefix: &[u8],
) -> Vec<(Identifier<C>, Vec<u8>)> {
let mut binding_factor_input_prefix = vec![];
let mut binding_factor_input_prefix = Vec::new();
// The length of a serialized verifying key of the same cipersuite does
// not change between runs of the protocol, so we don't need to hash to
@ -423,7 +428,7 @@ where
self.signing_commitments()
.keys()
.map(|identifier| {
let mut binding_factor_input = vec![];
let mut binding_factor_input = Vec::new();
binding_factor_input.extend_from_slice(&binding_factor_input_prefix);
binding_factor_input.extend_from_slice(identifier.serialize().as_ref());

View File

@ -1,10 +1,11 @@
//! FROST Round 1 functionality and types
use std::{
use alloc::{
collections::BTreeMap,
fmt::{self, Debug},
};
use alloc::vec::Vec;
use derive_getters::Getters;
#[cfg(any(test, feature = "test-impl"))]
use hex::FromHex;
@ -12,11 +13,10 @@ use hex::FromHex;
use rand_core::{CryptoRng, RngCore};
use zeroize::Zeroize;
use crate as frost;
use crate::{
serialization::{Deserialize, Serialize},
Ciphersuite, Element, Error, Field, Group, Header, Scalar,
};
use crate::{Ciphersuite, Element, Error, Field, Group, Header, Scalar};
#[cfg(feature = "serialization")]
use crate::serialization::{Deserialize, Serialize};
#[cfg(feature = "serde")]
use crate::serialization::{ElementSerialization, ScalarSerialization};
@ -295,7 +295,7 @@ impl<C> Debug for SigningNonces<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SigningNonces")
.field("hiding", &"<redacted>")
.field("binding", &"<redacted>")
@ -353,11 +353,12 @@ where
/// Computes the [signature commitment share] from these round one signing commitments.
///
/// [signature commitment share]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-14.html#name-signature-share-verificatio
#[cfg(feature = "cheater-detection")]
#[cfg_attr(feature = "internals", visibility::make(pub))]
#[cfg_attr(docsrs, doc(cfg(feature = "internals")))]
pub(super) fn to_group_commitment_share(
self,
binding_factor: &frost::BindingFactor<C>,
binding_factor: &crate::BindingFactor<C>,
) -> GroupCommitmentShare<C> {
GroupCommitmentShare::<C>(self.hiding.0 + (self.binding.0 * binding_factor.0))
}

View File

@ -1,6 +1,6 @@
//! FROST Round 2 functionality and types, for signature share generation
use std::fmt::{self, Debug};
use core::fmt::{self, Debug};
use crate as frost;
use crate::{
@ -81,6 +81,7 @@ where
/// This is the final step of [`verify_signature_share`] from the spec.
///
/// [`verify_signature_share`]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-14.html#name-signature-share-verificatio
#[cfg(feature = "cheater-detection")]
#[cfg_attr(feature = "internals", visibility::make(pub))]
#[cfg_attr(docsrs, doc(cfg(feature = "internals")))]
pub(crate) fn verify(

View File

@ -4,12 +4,14 @@
// constraints.
#![allow(clippy::indexing_slicing)]
use std::{
use core::{
borrow::Borrow,
fmt::{Debug, Result},
marker::PhantomData,
};
use alloc::vec::Vec;
use crate::{Ciphersuite, Element, Field, Group, Scalar};
/// Calculates the quotient of `self` and `rhs`, rounding the result towards positive infinity.
@ -243,7 +245,7 @@ impl<C: Ciphersuite, T: Copy> LookupTable5<C, T> {
}
impl<C: Ciphersuite, T: Debug> Debug for LookupTable5<C, T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result {
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result {
write!(f, "LookupTable5({:?})", self.bytes)
}
}

View File

@ -1,6 +1,13 @@
//! Serialization support.
use crate::{Ciphersuite, Error, Field, Group};
#[cfg(feature = "serialization")]
use alloc::vec::Vec;
#[cfg(feature = "serialization")]
use crate::Error;
#[cfg(feature = "serde")]
use crate::{Ciphersuite, Field, Group};
#[cfg(feature = "serde")]
#[cfg_attr(feature = "internals", visibility::make(pub))]
@ -89,6 +96,7 @@ where
// The short 4-byte ID. Derived as the CRC-32 of the UTF-8
// encoded ID in big endian format.
#[cfg(feature = "serde")]
const fn short_id<C>() -> [u8; 4]
where
C: Ciphersuite,
@ -120,7 +128,7 @@ where
C: Ciphersuite,
{
if deserializer.is_human_readable() {
let s: String = serde::de::Deserialize::deserialize(deserializer)?;
let s: alloc::string::String = serde::de::Deserialize::deserialize(deserializer)?;
if s != C::ID {
Err(serde::de::Error::custom("wrong ciphersuite"))
} else {
@ -172,13 +180,13 @@ pub(crate) trait Deserialize<C: Ciphersuite> {
/// Deserialize the struct from a slice of bytes.
fn deserialize(bytes: &[u8]) -> Result<Self, Error<C>>
where
Self: std::marker::Sized;
Self: core::marker::Sized;
}
#[cfg(feature = "serialization")]
impl<T: serde::Serialize, C: Ciphersuite> Serialize<C> for T {
fn serialize(&self) -> Result<Vec<u8>, Error<C>> {
postcard::to_stdvec(self).map_err(|_| Error::SerializationError)
postcard::to_allocvec(self).map_err(|_| Error::SerializationError)
}
}

View File

@ -1,5 +1,6 @@
//! Schnorr signatures over prime order groups (or subgroups)
use alloc::vec::Vec;
use debugless_unwrap::DebuglessUnwrap;
use crate::{Ciphersuite, Element, Error, Field, Group, Scalar};
@ -72,7 +73,7 @@ where
/// Converts this signature to its [`Ciphersuite::SignatureSerialization`] in bytes.
pub fn serialize(&self) -> C::SignatureSerialization {
let mut bytes = vec![];
let mut bytes = Vec::<u8>::new();
bytes.extend(<C::Group>::serialize(&self.R).as_ref());
bytes.extend(<<C::Group as Group>::Field>::serialize(&self.z).as_ref());
@ -117,8 +118,8 @@ where
}
}
impl<C: Ciphersuite> std::fmt::Debug for Signature<C> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
impl<C: Ciphersuite> core::fmt::Debug for Signature<C> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.debug_struct("Signature")
.field("R", &hex::encode(<C::Group>::serialize(&self.R).as_ref()))
.field(

View File

@ -70,11 +70,11 @@ where
}
}
impl<C> std::fmt::Debug for SigningKey<C>
impl<C> core::fmt::Debug for SigningKey<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("SigningKey").field(&"<redacted>").finish()
}
}

View File

@ -1,12 +1,14 @@
//! Ciphersuite-generic test functions.
#![allow(clippy::type_complexity)]
use std::{collections::BTreeMap, convert::TryFrom};
use alloc::collections::BTreeMap;
use crate as frost;
use crate::{
keys::PublicKeyPackage, Error, Field, Group, Identifier, Signature, SigningKey, VerifyingKey,
};
use alloc::borrow::ToOwned;
use alloc::vec::Vec;
use rand_core::{CryptoRng, RngCore};
use crate::Ciphersuite;
@ -326,6 +328,7 @@ fn check_aggregate_errors<C: Ciphersuite + PartialEq>(
);
}
#[cfg(feature = "cheater-detection")]
fn check_aggregate_corrupted_share<C: Ciphersuite + PartialEq>(
signing_package: frost::SigningPackage<C>,
mut signature_shares: BTreeMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
@ -365,7 +368,7 @@ pub fn check_sign_with_dkg<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
mut rng: R,
) -> (Vec<u8>, Signature<C>, VerifyingKey<C>)
where
C::Group: std::cmp::PartialEq,
C::Group: core::cmp::PartialEq,
{
////////////////////////////////////////////////////////////////////////////
// Key generation, Round 1

View File

@ -1,7 +1,5 @@
//! CoefficientCommitment functions
use std::convert::TryFrom;
use crate as frost;
use crate::{keys::CoefficientCommitment, tests::helpers::generate_element, Group};
use debugless_unwrap::DebuglessUnwrap;

View File

@ -1,6 +1,6 @@
//! Test for Repairable Threshold Scheme
use std::collections::BTreeMap;
use alloc::collections::BTreeMap;
use debugless_unwrap::DebuglessUnwrap;
use rand_core::{CryptoRng, RngCore};

View File

@ -1,5 +1,5 @@
//! Helper function for testing with test vectors.
use std::collections::BTreeMap;
use alloc::collections::BTreeMap;
use debugless_unwrap::DebuglessUnwrap;
use hex::{self, FromHex};

View File

@ -1,5 +1,5 @@
//! Helper function for testing with test vectors.
use std::collections::BTreeMap;
use alloc::{collections::BTreeMap, string::ToString};
use debugless_unwrap::DebuglessUnwrap;
use hex::{self};

View File

@ -1,7 +1,5 @@
//! VerifiableSecretSharingCommitment functions
use std::convert::TryFrom;
use crate::{
keys::{CoefficientCommitment, VerifiableSecretSharingCommitment},
tests::helpers::generate_element,

View File

@ -1,10 +1,11 @@
//! Traits used to abstract Ciphersuites.
use std::{
use core::{
fmt::Debug,
ops::{Add, Mul, Sub},
};
use alloc::vec::Vec;
use rand_core::{CryptoRng, RngCore};
use crate::{Error, FieldError, GroupError, Signature, VerifyingKey};

View File

@ -1,4 +1,7 @@
use std::fmt::{self, Debug};
use core::fmt::{self, Debug};
#[cfg(any(test, feature = "test-impl"))]
use alloc::vec::Vec;
#[cfg(any(test, feature = "test-impl"))]
use hex::FromHex;

View File

@ -25,10 +25,10 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
curve25519-dalek = { version = "=4.1.2", features = ["rand_core"] }
document-features = "0.2.7"
frost-core = { path = "../frost-core", version = "1.0.0" }
frost-rerandomized = { path = "../frost-rerandomized", version = "1.0.0" }
frost-core = { path = "../frost-core", version = "1.0.0", default-features = false }
frost-rerandomized = { path = "../frost-rerandomized", version = "1.0.0", default-features = false }
rand_core = "0.6"
sha2 = "0.10.2"
sha2 = { version = "0.10.2", default-features = false }
[dev-dependencies]
criterion = "0.5"
@ -45,15 +45,18 @@ serde_json = "1.0"
[features]
nightly = []
default = ["serialization", "cheater-detection"]
serialization = ["serde", "frost-core/serialization"]
default = ["serialization", "cheater-detection", "std"]
#! ## Features
## Enable standard library support.
std = ["frost-core/std"]
## Enable `serde` support for types that need to be communicated. You
## can use `serde` to serialize structs with any encoder that supports
## `serde` (e.g. JSON with `serde_json`).
serde = ["frost-core/serde"]
## Enable a default serialization format. Enables `serde`.
serialization = ["serde", "frost-core/serialization", "frost-rerandomized/serialization"]
## Enable cheater detection
cheater-detection = ["frost-core/cheater-detection"]
cheater-detection = ["frost-core/cheater-detection", "frost-rerandomized/cheater-detection"]
[lib]
# Disables non-criterion benchmark which is not used; prevents errors

View File

@ -4,7 +4,7 @@
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
//! using a subset of the other signers know here as `helpers`.
use std::collections::BTreeMap;
use alloc::collections::BTreeMap;
// This is imported separately to make `gencode` work.
// (if it were below, the position of the import would vary between ciphersuites

View File

@ -1,3 +1,4 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(non_snake_case)]
#![deny(missing_docs)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
@ -5,7 +6,9 @@
#![doc = include_str!("../README.md")]
#![doc = document_features::document_features!()]
use std::collections::BTreeMap;
extern crate alloc;
use alloc::collections::BTreeMap;
use curve25519_dalek::{
constants::ED25519_BASEPOINT_POINT,
@ -23,7 +26,9 @@ use frost_core as frost;
mod tests;
// Re-exports in our public API
pub use frost_core::{serde, Ciphersuite, Field, FieldError, Group, GroupError};
#[cfg(feature = "serde")]
pub use frost_core::serde;
pub use frost_core::{Ciphersuite, Field, FieldError, Group, GroupError};
pub use rand_core;
/// An error.
@ -227,8 +232,6 @@ pub type Identifier = frost::Identifier<E>;
/// FROST(Ed25519, SHA-512) keys, key generation, key shares.
pub mod keys {
use std::collections::BTreeMap;
use super::*;
/// The identifier list to use when generating key shares.

View File

@ -24,10 +24,10 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
document-features = "0.2.7"
ed448-goldilocks = { version = "0.9.0" }
frost-core = { path = "../frost-core", version = "1.0.0" }
frost-rerandomized = { path = "../frost-rerandomized", version = "1.0.0" }
frost-core = { path = "../frost-core", version = "1.0.0", default-features = false }
frost-rerandomized = { path = "../frost-rerandomized", version = "1.0.0", default-features = false }
rand_core = "0.6"
sha3 = "0.10.6"
sha3 = { version = "0.10.6", default-features = false }
[dev-dependencies]
criterion = "0.5"
@ -43,15 +43,18 @@ serde_json = "1.0"
[features]
nightly = []
default = ["serialization", "cheater-detection"]
serialization = ["serde", "frost-core/serialization"]
default = ["serialization", "cheater-detection", "std"]
#! ## Features
## Enable standard library support.
std = ["frost-core/std"]
## Enable `serde` support for types that need to be communicated. You
## can use `serde` to serialize structs with any encoder that supports
## `serde` (e.g. JSON with `serde_json`).
serde = ["frost-core/serde"]
## Enable a default serialization format. Enables `serde`.
serialization = ["serde", "frost-core/serialization", "frost-rerandomized/serialization"]
## Enable cheater detection
cheater-detection = ["frost-core/cheater-detection"]
cheater-detection = ["frost-core/cheater-detection", "frost-rerandomized/cheater-detection"]
[lib]
# Disables non-criterion benchmark which is not used; prevents errors

View File

@ -4,7 +4,7 @@
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
//! using a subset of the other signers know here as `helpers`.
use std::collections::BTreeMap;
use alloc::collections::BTreeMap;
// This is imported separately to make `gencode` work.
// (if it were below, the position of the import would vary between ciphersuites

View File

@ -5,6 +5,8 @@
#![doc = include_str!("../README.md")]
#![doc = document_features::document_features!()]
extern crate alloc;
use std::collections::BTreeMap;
use ed448_goldilocks::{
@ -24,7 +26,9 @@ use frost_core as frost;
mod tests;
// Re-exports in our public API
pub use frost_core::{serde, Ciphersuite, Field, FieldError, Group, GroupError};
#[cfg(feature = "serde")]
pub use frost_core::serde;
pub use frost_core::{Ciphersuite, Field, FieldError, Group, GroupError};
pub use rand_core;
/// An error.

View File

@ -24,11 +24,11 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
document-features = "0.2.7"
p256 = { version = "0.13.0", features = ["hash2curve"] }
frost-core = { path = "../frost-core", version = "1.0.0" }
frost-rerandomized = { path = "../frost-rerandomized", version = "1.0.0" }
p256 = { version = "0.13.0", features = ["hash2curve"], default-features = false }
frost-core = { path = "../frost-core", version = "1.0.0", default-features = false }
frost-rerandomized = { path = "../frost-rerandomized", version = "1.0.0", default-features = false }
rand_core = "0.6"
sha2 = "0.10.2"
sha2 = { version = "0.10.2", default-features = false }
[dev-dependencies]
criterion = "0.5"
@ -44,15 +44,18 @@ serde_json = "1.0"
[features]
nightly = []
default = ["serialization", "cheater-detection"]
serialization = ["serde", "frost-core/serialization"]
default = ["serialization", "cheater-detection", "std"]
#! ## Features
## Enable standard library support.
std = ["frost-core/std"]
## Enable `serde` support for types that need to be communicated. You
## can use `serde` to serialize structs with any encoder that supports
## `serde` (e.g. JSON with `serde_json`).
serde = ["frost-core/serde"]
## Enable a default serialization format. Enables `serde`.
serialization = ["serde", "frost-core/serialization", "frost-rerandomized/serialization"]
## Enable cheater detection
cheater-detection = ["frost-core/cheater-detection"]
cheater-detection = ["frost-core/cheater-detection", "frost-rerandomized/cheater-detection"]
[lib]
# Disables non-criterion benchmark which is not used; prevents errors

View File

@ -4,7 +4,7 @@
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
//! using a subset of the other signers know here as `helpers`.
use std::collections::BTreeMap;
use alloc::collections::BTreeMap;
// This is imported separately to make `gencode` work.
// (if it were below, the position of the import would vary between ciphersuites

View File

@ -1,3 +1,4 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(non_snake_case)]
#![deny(missing_docs)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
@ -5,7 +6,10 @@
#![doc = include_str!("../README.md")]
#![doc = document_features::document_features!()]
use std::collections::BTreeMap;
extern crate alloc;
use alloc::borrow::ToOwned;
use alloc::collections::BTreeMap;
use frost_rerandomized::RandomizedCiphersuite;
use p256::{
@ -25,7 +29,9 @@ use frost_core as frost;
mod tests;
// Re-exports in our public API
pub use frost_core::{serde, Ciphersuite, Field, FieldError, Group, GroupError};
#[cfg(feature = "serde")]
pub use frost_core::serde;
pub use frost_core::{Ciphersuite, Field, FieldError, Group, GroupError};
pub use rand_core;
/// An error.
@ -252,8 +258,6 @@ type P = P256Sha256;
pub type Identifier = frost::Identifier<P>;
/// FROST(P-256, SHA-256) keys, key generation, key shares.
pub mod keys {
use std::collections::BTreeMap;
use super::*;
/// The identifier list to use when generating key shares.

View File

@ -6,8 +6,11 @@ edition = "2021"
# - Update CHANGELOG.md
# - Create git tag.
version = "1.0.0"
authors = ["Deirdre Connolly <durumcrustulum@gmail.com>", "Chelsea Komlo <me@chelseakomlo.com>",
"Conrado Gouvea <conradoplg@gmail.com>"]
authors = [
"Deirdre Connolly <durumcrustulum@gmail.com>",
"Chelsea Komlo <me@chelseakomlo.com>",
"Conrado Gouvea <conradoplg@gmail.com>",
]
readme = "README.md"
license = "MIT OR Apache-2.0"
repository = "https://github.com/ZcashFoundation/frost"
@ -22,7 +25,9 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
derive-getters = "0.3.0"
document-features = "0.2.7"
frost-core = { path = "../frost-core", version = "1.0.0", features = ["internals"] }
frost-core = { path = "../frost-core", version = "1.0.0", features = [
"internals",
], default-features = false }
rand_core = "0.6"
[dev-dependencies]
@ -32,11 +37,13 @@ nightly = []
default = ["serialization", "cheater-detection"]
serialization = ["serde", "frost-core/serialization"]
#! ## Features
## Enable standard library support.
std = ["frost-core/std"]
## Enable `serde` support for types that need to be communicated. You
## can use `serde` to serialize structs with any encoder that supports
## `serde` (e.g. JSON with `serde_json`).
serde = ["frost-core/serde"]
# Exposes ciphersuite-generic tests for other crates to use
test-impl = ["frost-core/test-impl"]
test-impl = ["frost-core/test-impl", "serialization"]
## Enable cheater detection
cheater-detection = ["frost-core/cheater-detection"]

View File

@ -9,20 +9,25 @@
//! - Each participant should call [`sign`] and send the resulting
//! [`frost::round2::SignatureShare`] back to the Coordinator;
//! - The Coordinator should then call [`aggregate`].
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(non_snake_case)]
extern crate alloc;
#[cfg(any(test, feature = "test-impl"))]
pub mod tests;
use std::collections::BTreeMap;
use alloc::collections::BTreeMap;
use derive_getters::Getters;
pub use frost_core;
#[cfg(feature = "serialization")]
use frost_core::SigningPackage;
use frost_core::{
self as frost,
keys::{KeyPackage, PublicKeyPackage, SigningShare, VerifyingShare},
Ciphersuite, Error, Field, Group, Scalar, SigningPackage, VerifyingKey,
Ciphersuite, Error, Field, Group, Scalar, VerifyingKey,
};
#[cfg(feature = "serde")]
@ -32,6 +37,7 @@ use frost_core::serialization::ScalarSerialization;
// When pulled into `reddsa`, that has its own sibling `rand_core` import.
// For the time being, we do not re-export this `rand_core`.
#[cfg(feature = "serialization")]
use rand_core::{CryptoRng, RngCore};
/// Randomize the given key type for usage in a FROST signing with re-randomized keys,
@ -169,6 +175,7 @@ where
/// The [`SigningPackage`] must be the signing package being used in the
/// current FROST signing run. It is hashed into the randomizer calculation,
/// which binds it to that specific package.
#[cfg(feature = "serialization")]
pub fn new<R: RngCore + CryptoRng>(
mut rng: R,
signing_package: &SigningPackage<C>,
@ -179,6 +186,7 @@ where
/// Create a final Randomizer from a random Randomizer and a SigningPackage.
/// Function refactored out for testing, should always be private.
#[cfg(feature = "serialization")]
fn from_randomizer_and_signing_package(
rng_randomizer: <<<C as Ciphersuite>::Group as Group>::Field as Field>::Scalar,
signing_package: &SigningPackage<C>,
@ -266,6 +274,7 @@ where
{
/// Create a new [`RandomizedParams`] for the given [`VerifyingKey`] and
/// the given `participants`.
#[cfg(feature = "serialization")]
pub fn new<R: RngCore + CryptoRng>(
group_verifying_key: &VerifyingKey<C>,
signing_package: &SigningPackage<C>,

View File

@ -1,6 +1,8 @@
//! Ciphersuite-generic test functions for re-randomized FROST.
use std::collections::BTreeMap;
use alloc::borrow::ToOwned;
use alloc::collections::BTreeMap;
use alloc::vec::Vec;
use crate::{frost_core as frost, RandomizedCiphersuite, RandomizedParams, Randomizer};
use frost_core::{Field, Group, Signature, SigningPackage, VerifyingKey};

View File

@ -19,12 +19,12 @@ features = ["serde"]
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
curve25519-dalek = { version = "=4.1.2", features = ["serde", "rand_core"] }
curve25519-dalek = { version = "=4.1.2", features = ["rand_core"] }
document-features = "0.2.7"
frost-core = { path = "../frost-core", version = "1.0.0" }
frost-rerandomized = { path = "../frost-rerandomized", version = "1.0.0" }
frost-core = { path = "../frost-core", version = "1.0.0", default-features = false }
frost-rerandomized = { path = "../frost-rerandomized", version = "1.0.0", default-features = false }
rand_core = "0.6"
sha2 = "0.10.2"
sha2 = { version = "0.10.2", default-features = false }
[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
@ -41,15 +41,18 @@ serde_json = "1.0"
[features]
nightly = []
default = ["serialization", "cheater-detection"]
serialization = ["serde", "frost-core/serialization"]
default = ["serialization", "cheater-detection", "std"]
#! ## Features
## Enable standard library support.
std = ["frost-core/std"]
## Enable `serde` support for types that need to be communicated. You
## can use `serde` to serialize structs with any encoder that supports
## `serde` (e.g. JSON with `serde_json`).
serde = ["frost-core/serde"]
serde = ["frost-core/serde", "curve25519-dalek/serde"]
## Enable a default serialization format. Enables `serde`.
serialization = ["serde", "frost-core/serialization", "frost-rerandomized/serialization"]
## Enable cheater detection
cheater-detection = ["frost-core/cheater-detection"]
cheater-detection = ["frost-core/cheater-detection", "frost-rerandomized/cheater-detection"]
[lib]
# Disables non-criterion benchmark which is not used; prevents errors

View File

@ -4,7 +4,7 @@
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
//! using a subset of the other signers know here as `helpers`.
use std::collections::BTreeMap;
use alloc::collections::BTreeMap;
// This is imported separately to make `gencode` work.
// (if it were below, the position of the import would vary between ciphersuites

View File

@ -1,8 +1,11 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(non_snake_case)]
#![deny(missing_docs)]
#![doc = include_str!("../README.md")]
use std::collections::BTreeMap;
extern crate alloc;
use alloc::collections::BTreeMap;
use curve25519_dalek::{
constants::RISTRETTO_BASEPOINT_POINT,
@ -20,7 +23,9 @@ use frost_core as frost;
mod tests;
// Re-exports in our public API
pub use frost_core::{serde, Ciphersuite, Field, FieldError, Group, GroupError};
#[cfg(feature = "serde")]
pub use frost_core::serde;
pub use frost_core::{Ciphersuite, Field, FieldError, Group, GroupError};
pub use rand_core;
/// An error.
@ -214,7 +219,6 @@ pub type Identifier = frost::Identifier<R>;
/// FROST(ristretto255, SHA-512) keys, key generation, key shares.
pub mod keys {
use super::*;
use std::collections::BTreeMap;
/// The identifier list to use when generating key shares.
pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, R>;

View File

@ -23,11 +23,11 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
document-features = "0.2.7"
frost-core = { path = "../frost-core", version = "1.0.0" }
frost-rerandomized = { path = "../frost-rerandomized", version = "1.0.0" }
k256 = { version = "0.13.0", features = ["arithmetic", "expose-field", "hash2curve"] }
frost-core = { path = "../frost-core", version = "1.0.0", default-features = false }
frost-rerandomized = { path = "../frost-rerandomized", version = "1.0.0", default-features = false }
k256 = { version = "0.13.0", features = ["arithmetic", "expose-field", "hash2curve"], default-features = false }
rand_core = "0.6"
sha2 = "0.10.2"
sha2 = { version = "0.10.2", default-features = false }
[dev-dependencies]
criterion = "0.5"
@ -43,15 +43,18 @@ serde_json = "1.0"
[features]
nightly = []
default = ["serialization", "cheater-detection"]
serialization = ["serde", "frost-core/serialization"]
default = ["serialization", "cheater-detection", "std"]
#! ## Features
## Enable standard library support.
std = ["frost-core/std"]
## Enable `serde` support for types that need to be communicated. You
## can use `serde` to serialize structs with any encoder that supports
## `serde` (e.g. JSON with `serde_json`).
serde = ["frost-core/serde"]
## Enable a default serialization format. Enables `serde`.
serialization = ["serde", "frost-core/serialization", "frost-rerandomized/serialization"]
## Enable cheater detection
cheater-detection = ["frost-core/cheater-detection"]
cheater-detection = ["frost-core/cheater-detection", "frost-rerandomized/cheater-detection"]
[lib]
# Disables non-criterion benchmark which is not used; prevents errors

View File

@ -4,7 +4,7 @@
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
//! using a subset of the other signers know here as `helpers`.
use std::collections::BTreeMap;
use alloc::collections::BTreeMap;
// This is imported separately to make `gencode` work.
// (if it were below, the position of the import would vary between ciphersuites

View File

@ -1,3 +1,4 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(non_snake_case)]
#![deny(missing_docs)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
@ -5,7 +6,10 @@
#![doc = include_str!("../README.md")]
#![doc = document_features::document_features!()]
use std::collections::BTreeMap;
extern crate alloc;
use alloc::borrow::ToOwned;
use alloc::collections::BTreeMap;
use frost_rerandomized::RandomizedCiphersuite;
use k256::{
@ -26,7 +30,9 @@ use frost_core as frost;
mod tests;
// Re-exports in our public API
pub use frost_core::{serde, Ciphersuite, Field, FieldError, Group, GroupError};
#[cfg(feature = "serde")]
pub use frost_core::serde;
pub use frost_core::{Ciphersuite, Field, FieldError, Group, GroupError};
pub use rand_core;
/// An error.
@ -253,7 +259,6 @@ pub type Identifier = frost::Identifier<S>;
/// FROST(secp256k1, SHA-256) keys, key generation, key shares.
pub mod keys {
use super::*;
use std::collections::BTreeMap;
/// The identifier list to use when generating key shares.
pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, S>;