mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 04:39:24 +00:00
Fully document crypto/
This commit is contained in:
@@ -22,6 +22,7 @@ macro_rules! dalek_curve {
|
||||
const CONTEXT: &'static [u8] = $CONTEXT;
|
||||
}
|
||||
|
||||
/// The challenge function for this ciphersuite.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct $Hram;
|
||||
impl Hram<$Curve> for $Hram {
|
||||
|
||||
@@ -11,11 +11,12 @@ impl Curve for Ed448 {
|
||||
const CONTEXT: &'static [u8] = CONTEXT;
|
||||
}
|
||||
|
||||
// The RFC-8032 Ed448 challenge function.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Ietf8032Ed448Hram;
|
||||
pub(crate) struct Ietf8032Ed448Hram;
|
||||
impl Ietf8032Ed448Hram {
|
||||
#[allow(non_snake_case)]
|
||||
pub fn hram(context: &[u8], R: &Point, A: &Point, m: &[u8]) -> Scalar {
|
||||
pub(crate) fn hram(context: &[u8], R: &Point, A: &Point, m: &[u8]) -> Scalar {
|
||||
Scalar::wide_reduce(
|
||||
Shake256_114::digest(
|
||||
[
|
||||
@@ -32,6 +33,7 @@ impl Ietf8032Ed448Hram {
|
||||
}
|
||||
}
|
||||
|
||||
/// The challenge function for FROST's Ed448 ciphersuite.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct IetfEd448Hram;
|
||||
impl Hram<Ed448> for IetfEd448Hram {
|
||||
|
||||
@@ -17,6 +17,7 @@ macro_rules! kp_curve {
|
||||
const CONTEXT: &'static [u8] = $CONTEXT;
|
||||
}
|
||||
|
||||
/// The challenge function for this ciphersuite.
|
||||
#[derive(Clone)]
|
||||
pub struct $Hram;
|
||||
impl Hram<$Curve> for $Hram {
|
||||
|
||||
@@ -33,10 +33,14 @@ pub use kp256::{P256, IetfP256Hram};
|
||||
#[cfg(feature = "ed448")]
|
||||
mod ed448;
|
||||
#[cfg(feature = "ed448")]
|
||||
pub use ed448::{Ed448, Ietf8032Ed448Hram, IetfEd448Hram};
|
||||
pub use ed448::{Ed448, IetfEd448Hram};
|
||||
#[cfg(all(test, feature = "ed448"))]
|
||||
pub(crate) use ed448::Ietf8032Ed448Hram;
|
||||
|
||||
/// FROST Ciphersuite, except for the signing algorithm specific H2, making this solely the curve,
|
||||
/// its associated hash function, and the functions derived from it.
|
||||
/// FROST Ciphersuite.
|
||||
///
|
||||
/// This exclude the signing algorithm specific H2, making this solely the curve, its associated
|
||||
/// hash function, and the functions derived from it.
|
||||
pub trait Curve: Ciphersuite {
|
||||
/// Context string for this curve.
|
||||
const CONTEXT: &'static [u8];
|
||||
@@ -98,6 +102,7 @@ pub trait Curve: Ciphersuite {
|
||||
res
|
||||
}
|
||||
|
||||
/// Read a point from a reader, rejecting identity.
|
||||
#[allow(non_snake_case)]
|
||||
fn read_G<R: Read>(reader: &mut R) -> io::Result<Self::G> {
|
||||
let res = <Self as Ciphersuite>::read_G(reader)?;
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
|
||||
//! A modular implementation of FROST for any curve with a ff/group API.
|
||||
//! Additionally, custom algorithms may be specified so any signature reducible to
|
||||
//! Schnorr-like may be used with FROST.
|
||||
//!
|
||||
//! A Schnorr algorithm is provided, of the form (R, s) where `s = r + cx`, which
|
||||
//! allows specifying the challenge format. This is intended to easily allow
|
||||
//! integrating with existing systems.
|
||||
//!
|
||||
//! This library offers ciphersuites compatible with the
|
||||
//! [IETF draft](https://github.com/cfrg/draft-irtf-cfrg-frost). Currently, version
|
||||
//! 11 is supported.
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
use core::fmt::Debug;
|
||||
use std::collections::HashMap;
|
||||
@@ -53,12 +41,9 @@ pub enum FrostError {
|
||||
InvalidPreprocess(Participant),
|
||||
#[error("invalid share (participant {0})")]
|
||||
InvalidShare(Participant),
|
||||
|
||||
#[error("internal error ({0})")]
|
||||
InternalError(&'static str),
|
||||
}
|
||||
|
||||
// Validate a map of values to have the expected included participants
|
||||
/// Validate a map of values to have the expected participants.
|
||||
pub fn validate_map<T>(
|
||||
map: &HashMap<Participant, T>,
|
||||
included: &[Participant],
|
||||
|
||||
@@ -43,9 +43,9 @@ impl<T: Writable> Writable for Vec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pairing of an Algorithm with a ThresholdKeys instance and this specific signing set.
|
||||
// Pairing of an Algorithm with a ThresholdKeys instance.
|
||||
#[derive(Clone, Zeroize)]
|
||||
pub struct Params<C: Curve, A: Algorithm<C>> {
|
||||
struct Params<C: Curve, A: Algorithm<C>> {
|
||||
// Skips the algorithm due to being too large a bound to feasibly enforce on users
|
||||
#[zeroize(skip)]
|
||||
algorithm: A,
|
||||
@@ -53,11 +53,11 @@ pub struct Params<C: Curve, A: Algorithm<C>> {
|
||||
}
|
||||
|
||||
impl<C: Curve, A: Algorithm<C>> Params<C, A> {
|
||||
pub fn new(algorithm: A, keys: ThresholdKeys<C>) -> Params<C, A> {
|
||||
fn new(algorithm: A, keys: ThresholdKeys<C>) -> Params<C, A> {
|
||||
Params { algorithm, keys }
|
||||
}
|
||||
|
||||
pub fn multisig_params(&self) -> ThresholdParams {
|
||||
fn multisig_params(&self) -> ThresholdParams {
|
||||
self.keys.params()
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,7 @@ impl<C: Curve, A: Algorithm<C>> Params<C, A> {
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct Preprocess<C: Curve, A: Addendum> {
|
||||
pub(crate) commitments: Commitments<C>,
|
||||
/// The addendum used by the algorithm.
|
||||
pub addendum: A,
|
||||
}
|
||||
|
||||
@@ -76,9 +77,11 @@ impl<C: Curve, A: Addendum> Writable for Preprocess<C, A> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A cached preprocess. A preprocess MUST only be used once. Reuse will enable third-party
|
||||
/// recovery of your private key share. Additionally, this MUST be handled with the same security
|
||||
/// as your private key share, as knowledge of it also enables recovery.
|
||||
/// A cached preprocess.
|
||||
///
|
||||
/// A preprocess MUST only be used once. Reuse will enable third-party recovery of your private
|
||||
/// key share. Additionally, this MUST be handled with the same security as your private key share,
|
||||
/// as knowledge of it also enables recovery.
|
||||
// Directly exposes the [u8; 32] member to void needing to route through std::io interfaces.
|
||||
// Still uses Zeroizing internally so when users grab it, they have a higher likelihood of
|
||||
// appreciating how to handle it and don't immediately start copying it just by grabbing it.
|
||||
@@ -510,6 +513,6 @@ impl<C: Curve, A: Algorithm<C>> SignatureMachine<A::Signature> for AlgorithmSign
|
||||
}
|
||||
|
||||
// If everyone has a valid share, and there were enough participants, this should've worked
|
||||
Err(FrostError::InternalError("everyone had a valid share yet the signature was still invalid"))
|
||||
panic!("everyone had a valid share yet the signature was still invalid");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ pub fn test_schnorr<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mut R) {
|
||||
assert!(sig.verify(group_key, H::hram(&sig.R, &group_key, MSG)));
|
||||
}
|
||||
|
||||
// Test an offset Schnorr signature.
|
||||
/// Test an offset Schnorr signature.
|
||||
pub fn test_offset_schnorr<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mut R) {
|
||||
const MSG: &[u8] = b"Hello, World!";
|
||||
|
||||
@@ -223,7 +223,7 @@ pub fn test_offset_schnorr<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &m
|
||||
assert!(sig.verify(offset_key, H::hram(&sig.R, &group_key, MSG)));
|
||||
}
|
||||
|
||||
// Test blame for an invalid Schnorr signature share.
|
||||
/// Test blame for an invalid Schnorr signature share.
|
||||
pub fn test_schnorr_blame<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mut R) {
|
||||
const MSG: &[u8] = b"Hello, World!";
|
||||
|
||||
@@ -245,7 +245,7 @@ pub fn test_schnorr_blame<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mu
|
||||
}
|
||||
}
|
||||
|
||||
// Run a variety of tests against a ciphersuite.
|
||||
/// Run a variety of tests against a ciphersuite.
|
||||
pub fn test_ciphersuite<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mut R) {
|
||||
test_schnorr::<R, C, H>(rng);
|
||||
test_offset_schnorr::<R, C, H>(rng);
|
||||
|
||||
@@ -22,6 +22,7 @@ use crate::{
|
||||
tests::{clone_without, recover_key, test_ciphersuite},
|
||||
};
|
||||
|
||||
/// Vectors for a ciphersuite.
|
||||
pub struct Vectors {
|
||||
pub threshold: u16,
|
||||
|
||||
@@ -141,6 +142,7 @@ fn vectors_to_multisig_keys<C: Curve>(vectors: &Vectors) -> HashMap<Participant,
|
||||
keys
|
||||
}
|
||||
|
||||
/// Test a Ciphersuite with its vectors.
|
||||
pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
||||
rng: &mut R,
|
||||
vectors: Vectors,
|
||||
|
||||
Reference in New Issue
Block a user