switch to thiserror for secp

This commit is contained in:
scilio 2022-08-22 13:53:06 -04:00
parent 405928713f
commit eb2d30aeed
3 changed files with 38 additions and 140 deletions

View file

@ -1,7 +1,5 @@
use failure::{self, Context, Fail};
use grin_wallet_libwallet as libwallet;
use std::fmt::{self, Display};
use std::io;
/// MWixnet error definition
#[derive(Debug)]
@ -14,27 +12,6 @@ pub type Result<T> = std::result::Result<T, Error>;
/// MWixnet error types
#[derive(Debug, Fail)]
pub enum ErrorKind {
/// Error from secp256k1-zkp library
#[fail(display = "Secp Error")]
SecpError,
/// Wraps an io error produced when reading or writing
#[fail(display = "IO Error: {}", _0)]
IOErr(String, io::ErrorKind),
/// Error from grin's api crate
#[fail(display = "GRIN API Error: {}", _0)]
GrinApiError(String),
/// Error from grin core
#[fail(display = "GRIN Core Error: {}", _0)]
GrinCoreError(String),
/// Error from grin-wallet's libwallet
#[fail(display = "libwallet error: {}", _0)]
LibWalletError(String),
/// Error from serde-json
#[fail(display = "serde json error: {}", _0)]
SerdeJsonError(String),
/// Error from invalid signature
#[fail(display = "invalid signature")]
InvalidSigError,
/// Wallet error
#[fail(display = "wallet error: {}", _0)]
WalletError(crate::wallet::WalletError),
@ -45,102 +22,12 @@ pub enum ErrorKind {
impl std::error::Error for Error {}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
ErrorKind::IOErr(format!("{}", e), e.kind()).into()
}
}
impl From<io::ErrorKind> for Error {
fn from(e: io::ErrorKind) -> Error {
ErrorKind::IOErr(format!("{}", io::Error::from(e)), e).into()
}
}
impl From<grin_core::ser::Error> for Error {
fn from(e: grin_core::ser::Error) -> Error {
Error {
inner: Context::new(ErrorKind::GrinCoreError(e.to_string())),
}
}
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.inner, f)
}
}
impl Error {
pub fn new(kind: ErrorKind) -> Error {
Error {
inner: Context::new(kind),
}
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Error {
Error {
inner: Context::new(kind),
}
}
}
impl From<Context<ErrorKind>> for Error {
fn from(inner: Context<ErrorKind>) -> Error {
Error { inner }
}
}
impl From<secp256k1zkp::Error> for Error {
fn from(_error: secp256k1zkp::Error) -> Error {
Error {
inner: Context::new(ErrorKind::SecpError),
}
}
}
impl From<grin_api::Error> for Error {
fn from(e: grin_api::Error) -> Error {
Error {
inner: Context::new(ErrorKind::GrinApiError(e.to_string())),
}
}
}
impl From<grin_api::json_rpc::Error> for Error {
fn from(e: grin_api::json_rpc::Error) -> Error {
Error {
inner: Context::new(ErrorKind::GrinApiError(e.to_string())),
}
}
}
impl From<grin_core::core::transaction::Error> for Error {
fn from(e: grin_core::core::transaction::Error) -> Error {
Error {
inner: Context::new(ErrorKind::GrinCoreError(e.to_string())),
}
}
}
impl From<libwallet::Error> for Error {
fn from(e: libwallet::Error) -> Error {
Error {
inner: Context::new(ErrorKind::LibWalletError(e.to_string())),
}
}
}
impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Error {
Error {
inner: Context::new(ErrorKind::SerdeJsonError(e.to_string())),
}
}
}
impl From<crate::wallet::WalletError> for Error {
fn from(e: crate::wallet::WalletError) -> Error {
Error {

View file

@ -6,7 +6,7 @@ use crate::server::{Server, ServerImpl, SwapError};
use crate::wallet::Wallet;
use grin_util::StopState;
use jsonrpc_core::{Result, Value};
use jsonrpc_core::Value;
use jsonrpc_derive::rpc;
use jsonrpc_http_server::jsonrpc_core::*;
use jsonrpc_http_server::*;
@ -25,11 +25,11 @@ pub struct SwapReq {
#[rpc(server)]
pub trait API {
#[rpc(name = "swap")]
fn swap(&self, swap: SwapReq) -> Result<Value>;
fn swap(&self, swap: SwapReq) -> jsonrpc_core::Result<Value>;
// milestone 3: Used by mwixnet coinswap servers to communicate with each other
// fn derive_outputs(&self, entries: Vec<Onion>) -> Result<Value>;
// fn derive_kernel(&self, tx: Tx) -> Result<Value>;
// fn derive_outputs(&self, entries: Vec<Onion>) -> jsonrpc_core::Result<Value>;
// fn derive_kernel(&self, tx: Tx) -> jsonrpc_core::Result<Value>;
}
#[derive(Clone)]
@ -73,7 +73,7 @@ impl From<SwapError> for Error {
impl API for RPCServer {
/// Implements the 'swap' API
fn swap(&self, swap: SwapReq) -> Result<Value> {
fn swap(&self, swap: SwapReq) -> jsonrpc_core::Result<Value> {
self.server
.lock()
.unwrap()

View file

@ -8,12 +8,11 @@ pub use secp256k1zkp::key::{PublicKey, SecretKey, ZERO_KEY};
pub use secp256k1zkp::pedersen::{Commitment, RangeProof};
pub use secp256k1zkp::{ContextFlag, Message, Secp256k1, Signature};
use crate::error::{Error, ErrorKind, Result};
use blake2::blake2b::Blake2b;
use byteorder::{BigEndian, ByteOrder};
use grin_core::ser::{self, Readable, Reader, Writeable, Writer};
use secp256k1zkp::rand::thread_rng;
use thiserror::Error;
/// A generalized Schnorr signature with a pedersen commitment value & blinding factors as the keys
#[derive(Clone)]
@ -23,6 +22,21 @@ pub struct ComSignature {
t: SecretKey,
}
/// Error types for Commitment Signatures
#[derive(Error, Debug)]
pub enum ComSigError {
#[error("Commitment signature is invalid")]
InvalidSig,
#[error("Secp256k1zkp error: {0:?}")]
Secp256k1zkp(secp256k1zkp::Error),
}
impl From<secp256k1zkp::Error> for ComSigError {
fn from(err: secp256k1zkp::Error) -> ComSigError {
ComSigError::Secp256k1zkp(err)
}
}
impl ComSignature {
pub fn new(pub_nonce: &Commitment, s: &SecretKey, t: &SecretKey) -> ComSignature {
ComSignature {
@ -33,7 +47,11 @@ impl ComSignature {
}
#[allow(dead_code)]
pub fn sign(amount: u64, blind: &SecretKey, msg: &Vec<u8>) -> Result<ComSignature> {
pub fn sign(
amount: u64,
blind: &SecretKey,
msg: &Vec<u8>,
) -> Result<ComSignature, ComSigError> {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
let mut amt_bytes = [0; 32];
@ -62,7 +80,7 @@ impl ComSignature {
}
#[allow(non_snake_case)]
pub fn verify(&self, commit: &Commitment, msg: &Vec<u8>) -> Result<()> {
pub fn verify(&self, commit: &Commitment, msg: &Vec<u8>) -> Result<(), ComSigError> {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
let S1 = secp.commit_blind(self.s.clone(), self.t.clone())?;
@ -75,7 +93,7 @@ impl ComSignature {
let S2 = secp.commit_sum(commits, Vec::new())?;
if S1 != S2 {
return Err(Error::new(ErrorKind::InvalidSigError));
return Err(ComSigError::InvalidSig);
}
Ok(())
@ -86,7 +104,7 @@ impl ComSignature {
commit: &Commitment,
nonce_commit: &Commitment,
msg: &Vec<u8>,
) -> Result<SecretKey> {
) -> Result<SecretKey, ComSigError> {
let mut challenge_hasher = Blake2b::new(32);
challenge_hasher.update(&commit.0);
challenge_hasher.update(&nonce_commit.0);
@ -131,7 +149,7 @@ pub mod comsig_serde {
#[allow(non_snake_case)]
impl Readable for ComSignature {
fn read<R: Reader>(reader: &mut R) -> std::result::Result<Self, ser::Error> {
fn read<R: Reader>(reader: &mut R) -> Result<Self, ser::Error> {
let R = Commitment::read(reader)?;
let s = read_secret_key(reader)?;
let t = read_secret_key(reader)?;
@ -140,7 +158,7 @@ impl Readable for ComSignature {
}
impl Writeable for ComSignature {
fn write<W: Writer>(&self, writer: &mut W) -> std::result::Result<(), ser::Error> {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
writer.write_fixed_bytes(self.pub_nonce.0)?;
writer.write_fixed_bytes(self.s.0)?;
writer.write_fixed_bytes(self.t.0)?;
@ -155,7 +173,7 @@ pub fn random_secret() -> SecretKey {
}
/// Deserialize a SecretKey from a Reader
pub fn read_secret_key<R: Reader>(reader: &mut R) -> std::result::Result<SecretKey, ser::Error> {
pub fn read_secret_key<R: Reader>(reader: &mut R) -> Result<SecretKey, ser::Error> {
let buf = reader.read_fixed_bytes(SECRET_KEY_SIZE)?;
let secp = Secp256k1::with_caps(ContextFlag::None);
let pk = SecretKey::from_slice(&secp, &buf).map_err(|_| ser::Error::CorruptedData)?;
@ -163,10 +181,7 @@ pub fn read_secret_key<R: Reader>(reader: &mut R) -> std::result::Result<SecretK
}
/// Build a Pedersen Commitment using the provided value and blinding factor
pub fn commit(
value: u64,
blind: &SecretKey,
) -> std::result::Result<Commitment, secp256k1zkp::Error> {
pub fn commit(value: u64, blind: &SecretKey) -> Result<Commitment, secp256k1zkp::Error> {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
let commit = secp.commit(value, blind.clone())?;
Ok(commit)
@ -176,7 +191,7 @@ pub fn commit(
pub fn add_excess(
commitment: &Commitment,
excess: &SecretKey,
) -> std::result::Result<Commitment, secp256k1zkp::Error> {
) -> Result<Commitment, secp256k1zkp::Error> {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
let excess_commit: Commitment = secp.commit(0, excess.clone())?;
@ -186,10 +201,7 @@ pub fn add_excess(
}
/// Subtracts a value (v*H) from an existing commitment
pub fn sub_value(
commitment: &Commitment,
value: u64,
) -> std::result::Result<Commitment, secp256k1zkp::Error> {
pub fn sub_value(commitment: &Commitment, value: u64) -> Result<Commitment, secp256k1zkp::Error> {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
let neg_commit: Commitment = secp.commit(value, ZERO_KEY)?;
let sum = secp.commit_sum(vec![commitment.clone()], vec![neg_commit.clone()])?;
@ -197,7 +209,7 @@ pub fn sub_value(
}
/// Signs the message with the provided SecretKey
pub fn sign(sk: &SecretKey, msg: &Message) -> std::result::Result<Signature, secp256k1zkp::Error> {
pub fn sign(sk: &SecretKey, msg: &Message) -> Result<Signature, secp256k1zkp::Error> {
let secp = Secp256k1::with_caps(ContextFlag::Full);
let pubkey = PublicKey::from_secret_key(&secp, &sk)?;
let sig = aggsig::sign_single(&secp, &msg, &sk, None, None, None, Some(&pubkey), None)?;
@ -206,15 +218,14 @@ pub fn sign(sk: &SecretKey, msg: &Message) -> std::result::Result<Signature, sec
#[cfg(test)]
mod tests {
use super::{ComSignature, ContextFlag, Secp256k1, SecretKey};
use crate::error::Result;
use super::{ComSigError, ComSignature, ContextFlag, Secp256k1, SecretKey};
use rand::Rng;
use secp256k1zkp::rand::{thread_rng, RngCore};
/// Test signing and verification of ComSignatures
#[test]
fn verify_comsig() -> Result<()> {
fn verify_comsig() -> Result<(), ComSigError> {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
let amount = thread_rng().next_u64();