redjubjub/src/verification_key.rs

105 lines
3.7 KiB
Rust
Raw Normal View History

// -*- mode: rust; -*-
//
// This file is part of redjubjub.
// Copyright (c) 2019-2021 Zcash Foundation
// See LICENSE for licensing information.
//
// Authors:
// - Deirdre Connolly <deirdre@zfnd.org>
// - Henry de Valence <hdevalence@hdevalence.ca>
2023-02-01 15:22:37 -08:00
use std::{convert::TryFrom, hash::Hash};
2021-03-01 06:54:52 -08:00
use crate::{Error, Randomizer, SigType, Signature, SpendAuth};
2019-12-02 21:58:19 -08:00
2019-12-03 15:59:24 -08:00
/// A refinement type for `[u8; 32]` indicating that the bytes represent
/// an encoding of a RedJubJub verification key.
2019-12-03 15:59:24 -08:00
///
/// This is useful for representing a compressed verification key; the
/// [`VerificationKey`] type in this library holds other decompressed state
2019-12-03 15:59:24 -08:00
/// used in signature verification.
2023-02-01 15:22:37 -08:00
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2023-02-01 15:22:37 -08:00
pub struct VerificationKeyBytes<T: SigType>(
pub(crate) reddsa::VerificationKeyBytes<T::RedDSASigType>,
);
2019-12-02 21:58:19 -08:00
impl<T: SigType> From<[u8; 32]> for VerificationKeyBytes<T> {
fn from(bytes: [u8; 32]) -> VerificationKeyBytes<T> {
2023-02-01 15:22:37 -08:00
VerificationKeyBytes(reddsa::VerificationKeyBytes::from(bytes))
2019-12-02 21:58:19 -08:00
}
}
impl<T: SigType> From<VerificationKeyBytes<T>> for [u8; 32] {
fn from(refined: VerificationKeyBytes<T>) -> [u8; 32] {
2023-02-01 15:22:37 -08:00
refined.0.into()
}
}
/// A valid RedJubJub verification key.
2019-12-04 17:36:01 -08:00
///
/// This type holds decompressed state used in signature verification; if the
/// verification key may not be used immediately, it is probably better to use
/// [`VerificationKeyBytes`], which is a refinement type for `[u8; 32]`.
///
/// ## Consensus properties
///
/// The `TryFrom<VerificationKeyBytes>` conversion performs the following Zcash
/// consensus rule checks:
///
/// 1. The check that the bytes are a canonical encoding of a verification key;
/// 2. The check that the verification key is not a point of small order.
Implement the messages spec (#114) * start messages and validation * add missing docs to constants * change validation to matches, fix constant doc Co-authored-by: teor <teor@riseup.net> * fix the build * validate share_commitment * add new constants and validations * fix validation * derive serde Serialize and Deserialize in all messages structs * update created structs Co-authored-by: teor <teor@riseup.net> * fix build * define and use a new MAX_SIGNERS constant * change group_public type * add some test cases * add validation and serialization tests for SigningCommitments * add validation and serialization test to SigningPackage * change some fields order matching the spec * fix field order in tests according to last updates to the spec * implement serialize and deserialize for ParticipantId * move serde-json to dev-dependencies section * change to pub(crate) * fix serialize of VerificationKey * add assert to serialize * add note, fix typo * improve some code in tests * test serialization of individual fields * start messages and validation * add missing docs to constants * change validation to matches, fix constant doc Co-authored-by: teor <teor@riseup.net> * fix the build * validate share_commitment * add new constants and validations * fix validation * define and use a new MAX_SIGNERS constant * change group_public type * change some fields order matching the spec * change message fields to new spec * remove some non needed conversions * use a BTreeMap to guarantee the order * remove some calls to `clone()` by implementing `Copy` * change message type in frost and add validate_signatureshare test * change `share_commitment` to BTreeMap * add `serialize_signatureshare` test * add aggregatesignature tests * add some test header messages utility functions * add a setup utility * move the general serialization checks into an utility function * fi some typos * add and use a `generate_share_commitment` utility * add create_signing_commitments utility function * improve the serialization tests * make room for prop tests * add arbitrary tests for serialization * remove allow dead code from messages * fix some imports * make signature module public only to the crate * simplify a bit the frost tests * improve the generated docs * add a `prop_filter` to Header arbitrary * (ab)use proptest_derive * improve validation for Message * improve some utility functions * change frost to serialization id conversion * add a quick btreemap test * change the `MsgType` to `u32` * add no leftover bytes checks * add a full_setup utility * add map len checks Co-authored-by: teor <teor@riseup.net>
2021-06-16 12:13:23 -07:00
#[derive(PartialEq, Copy, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(try_from = "VerificationKeyBytes<T>"))]
#[cfg_attr(feature = "serde", serde(into = "VerificationKeyBytes<T>"))]
#[cfg_attr(feature = "serde", serde(bound = "T: SigType"))]
2023-02-01 15:22:37 -08:00
pub struct VerificationKey<T: SigType>(pub(crate) reddsa::VerificationKey<T::RedDSASigType>);
2019-12-02 21:58:19 -08:00
impl<T: SigType> From<VerificationKey<T>> for VerificationKeyBytes<T> {
fn from(pk: VerificationKey<T>) -> VerificationKeyBytes<T> {
2023-02-01 15:22:37 -08:00
VerificationKeyBytes(pk.0.into())
2019-12-02 21:58:19 -08:00
}
}
impl<T: SigType> From<VerificationKey<T>> for [u8; 32] {
fn from(pk: VerificationKey<T>) -> [u8; 32] {
2023-02-01 15:22:37 -08:00
pk.0.into()
2019-12-04 17:36:01 -08:00
}
}
impl<T: SigType> TryFrom<VerificationKeyBytes<T>> for VerificationKey<T> {
2019-12-02 21:58:19 -08:00
type Error = Error;
fn try_from(bytes: VerificationKeyBytes<T>) -> Result<Self, Self::Error> {
2023-02-01 15:22:37 -08:00
let reddsa_vk = reddsa::VerificationKey::try_from(bytes.0)?;
Ok(VerificationKey(reddsa_vk))
2019-12-02 21:58:19 -08:00
}
}
2019-12-02 22:20:21 -08:00
impl<T: SigType> TryFrom<[u8; 32]> for VerificationKey<T> {
2019-12-04 17:36:01 -08:00
type Error = Error;
fn try_from(bytes: [u8; 32]) -> Result<Self, Self::Error> {
use std::convert::TryInto;
VerificationKeyBytes::from(bytes).try_into()
2019-12-04 17:36:01 -08:00
}
}
impl VerificationKey<SpendAuth> {
/// Randomize this verification key with the given `randomizer`.
2019-12-04 17:00:55 -08:00
///
/// Randomization is only supported for `SpendAuth` keys.
pub fn randomize(&self, randomizer: &Randomizer) -> VerificationKey<SpendAuth> {
2023-02-01 15:22:37 -08:00
VerificationKey(self.0.randomize(randomizer))
2019-12-04 17:00:55 -08:00
}
}
impl<T: SigType> VerificationKey<T> {
/// Verify a purported `signature` over `msg` made by this verification key.
// This is similar to impl signature::Verifier but without boxed errors
2019-12-04 11:59:31 -08:00
pub fn verify(&self, msg: &[u8], signature: &Signature<T>) -> Result<(), Error> {
2023-02-01 15:22:37 -08:00
self.0.verify(msg, &signature.0).map_err(|e| e.into())
2019-12-02 22:20:21 -08:00
}
}