added sign and verify

This commit is contained in:
Paul 2022-09-05 21:07:02 +03:00
parent d3ad5e14b8
commit 3ebec5f349
2 changed files with 98 additions and 72 deletions

View File

@ -5,7 +5,7 @@ use nonempty::NonEmpty;
use rand::{CryptoRng, RngCore};
use std::fmt;
use crate::keys::IssuerValidatingKey;
use crate::keys::{IssuerAuthorizingKey, IssuerValidatingKey};
use crate::note::note_type::MAX_ASSET_DESCRIPTION_SIZE;
use crate::note::{NoteType, Nullifier};
use crate::value::NoteValue;
@ -31,13 +31,39 @@ impl IssueAction<Unauthorized> {
/// inject the `sighash` for signature into the bundle.
pub fn prepare(self, sighash: [u8; 32]) -> IssueAction<Prepared> {
return IssueAction {
IssueAction {
ik: self.ik,
asset_desc: self.asset_desc,
notes: self.notes,
finalize: self.finalize,
authorization: Prepared { sighash },
};
}
}
}
impl IssueAction<Prepared> {
/// Sign the sighash using the provided `IssuerValidatingKey`.
///
/// # Panics
///
/// Panics if the provided `IssuerAuthorizingKey` does not match the action's `IssuerValidatingKey`.
pub fn sign<R: RngCore + CryptoRng>(
self,
mut rng: R,
isk: &IssuerAuthorizingKey,
) -> IssueAction<Signed> {
let expected_ik: IssuerValidatingKey = (isk).into();
assert_eq!(expected_ik, self.ik);
IssueAction {
ik: self.ik,
asset_desc: self.asset_desc,
notes: self.notes,
finalize: self.finalize,
authorization: Signed {
signature: isk.sign(&mut rng, &self.authorization.sighash),
},
}
}
}
@ -353,12 +379,7 @@ impl IssueBundle<Unauthorized> {
Ok(())
}
/// Loads the sighash into this bundle, preparing it for signing.
///
/// This API ensures that all signatures are created over the same sighash.
/// pub fn prepare<R: RngCore + CryptoRng>(
// self,
// mut rng: R,
/// Loads the sighash into each action in the bundle, as preparation for signing.
pub fn prepare(self, sighash: [u8; 32]) -> IssueBundle<Prepared> {
IssueBundle {
actions: self
@ -370,6 +391,24 @@ impl IssueBundle<Unauthorized> {
}
}
impl IssueBundle<Prepared> {
/// Sign all the relevant actions
pub fn sign<R: RngCore + CryptoRng>(
self,
mut rng: R,
isk: &IssuerAuthorizingKey,
) -> IssueBundle<Signed> {
// todo: check ik fits isk
IssueBundle {
actions: self
.actions
.into_iter()
.map(|a| a.sign(&mut rng, isk))
.collect(),
}
}
}
/// Errors produced during the issuance process
#[derive(Debug, PartialEq, Eq)]
pub enum Error {
@ -388,6 +427,7 @@ mod tests {
};
use crate::value::NoteValue;
use rand::rngs::OsRng;
use rand::RngCore;
#[test]
fn issue_bundle_basic() {
@ -555,69 +595,48 @@ mod tests {
)
.unwrap();
let fake_sighash = [1; 32];
let mut fake_sighash = [0; 32];
rng.fill_bytes(&mut fake_sighash);
let prepared = bundle.prepare(fake_sighash);
let action = prepared
let action = prepared.get_action(ik, String::from("Frost")).unwrap();
assert_eq!(action.authorization().sighash, fake_sighash);
}
#[test]
fn issue_bundle_sign() {
let mut rng = OsRng;
let sk = SpendingKey::random(&mut rng);
let isk: IssuerAuthorizingKey = (&sk).into();
let ik: IssuerValidatingKey = (&isk).into();
let fvk = FullViewingKey::from(&sk);
let recipient = fvk.address_at(0u32, Scope::External);
let mut bundle = IssueBundle::new();
bundle
.add_recipient(
ik.clone(),
String::from("Frost"),
recipient,
NoteValue::from_raw(5),
false,
rng,
)
.unwrap();
let mut rnd_sighash = [0; 32];
rng.fill_bytes(&mut rnd_sighash);
let signed = bundle.prepare(rnd_sighash).sign(rng, &isk);
let action = signed
.get_action(ik.clone(), String::from("Frost"))
.unwrap();
let auth = action.authorization();
assert_eq!(auth.sighash, fake_sighash);
ik.verify(&rnd_sighash, &action.authorization.signature)
.expect("signature should be valid");
}
}
// mod tests {
// use rand::rngs::OsRng;
//
// use super::Builder;
// // use crate::keys::{IssuerAuthorizingKey, IssuerValidatingKey};
// use crate::note::NoteType;
// use crate::{
// bundle::{Authorized, Bundle, Flags},
// circuit::ProvingKey,
// constants::MERKLE_DEPTH_ORCHARD,
// keys::{FullViewingKey, Scope, SpendingKey},
// tree::EMPTY_ROOTS,
// value::NoteValue,
// };
// use crate::builder::Builder;
//
// #[test]
// fn shielding_bundle() {
// let pk = ProvingKey::build();
// let mut rng = OsRng;
//
// let sk = SpendingKey::random(&mut rng);
// let fvk = FullViewingKey::from(&sk);
// let recipient = fvk.address_at(0u32, Scope::External);
//
// let mut builder = Builder::new(
// Flags::from_parts(true, true),
// EMPTY_ROOTS[MERKLE_DEPTH_ORCHARD].into(),
// );
//
// builder
// .add_recipient(
// None,
// recipient,
// NoteValue::from_raw(5000),
// NoteType::native(),
// None,
// )
// .unwrap();
//
//
// let bundle: Bundle<Authorized, i64> = builder
// .build(&mut rng)
// .unwrap()
// .create_proof(&pk, &mut rng)
// .unwrap()
// .prepare(&mut rng, [0; 32])
// .sign()
// .finalize()
// .unwrap();
// assert_eq!(bundle.value_balance(), &(-5000));
//
// verify_bundle(&bundle, &vk)
// }
// }

View File

@ -209,9 +209,7 @@ impl IssuerAuthorizingKey {
to_scalar(PrfExpand::ZsaIsk.expand(&sk.0))
}
/// RXXXX
///
/// XXXXX
/// Sign the provided message using the `IssuerAuthorizingKey`.
pub fn sign(
&self,
rng: &mut (impl RngCore + CryptoRng),
@ -280,6 +278,15 @@ impl IssuerValidatingKey {
.and_then(check_structural_validity)
.map(IssuerValidatingKey)
}
/// Verifies a purported `signature` over `msg` made by this verification key.
pub fn verify(
&self,
msg: &[u8],
signature: &redpallas::Signature<SpendAuth>,
) -> Result<(), reddsa::Error> {
self.0.verify(msg, signature)
}
}
/// A function to check structural validity of the validating keys for authorizing transfers and