mirror of
https://github.com/mimblewimble/mwixnet.git
synced 2025-01-20 19:11:09 +03:00
switch to thiserror for secp
This commit is contained in:
parent
405928713f
commit
eb2d30aeed
3 changed files with 38 additions and 140 deletions
113
src/error.rs
113
src/error.rs
|
@ -1,7 +1,5 @@
|
||||||
use failure::{self, Context, Fail};
|
use failure::{self, Context, Fail};
|
||||||
use grin_wallet_libwallet as libwallet;
|
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::io;
|
|
||||||
|
|
||||||
/// MWixnet error definition
|
/// MWixnet error definition
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -14,27 +12,6 @@ pub type Result<T> = std::result::Result<T, Error>;
|
||||||
/// MWixnet error types
|
/// MWixnet error types
|
||||||
#[derive(Debug, Fail)]
|
#[derive(Debug, Fail)]
|
||||||
pub enum ErrorKind {
|
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
|
/// Wallet error
|
||||||
#[fail(display = "wallet error: {}", _0)]
|
#[fail(display = "wallet error: {}", _0)]
|
||||||
WalletError(crate::wallet::WalletError),
|
WalletError(crate::wallet::WalletError),
|
||||||
|
@ -45,102 +22,12 @@ pub enum ErrorKind {
|
||||||
|
|
||||||
impl std::error::Error for Error {}
|
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 {
|
impl Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
Display::fmt(&self.inner, f)
|
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 {
|
impl From<crate::wallet::WalletError> for Error {
|
||||||
fn from(e: crate::wallet::WalletError) -> Error {
|
fn from(e: crate::wallet::WalletError) -> Error {
|
||||||
Error {
|
Error {
|
||||||
|
|
10
src/rpc.rs
10
src/rpc.rs
|
@ -6,7 +6,7 @@ use crate::server::{Server, ServerImpl, SwapError};
|
||||||
use crate::wallet::Wallet;
|
use crate::wallet::Wallet;
|
||||||
|
|
||||||
use grin_util::StopState;
|
use grin_util::StopState;
|
||||||
use jsonrpc_core::{Result, Value};
|
use jsonrpc_core::Value;
|
||||||
use jsonrpc_derive::rpc;
|
use jsonrpc_derive::rpc;
|
||||||
use jsonrpc_http_server::jsonrpc_core::*;
|
use jsonrpc_http_server::jsonrpc_core::*;
|
||||||
use jsonrpc_http_server::*;
|
use jsonrpc_http_server::*;
|
||||||
|
@ -25,11 +25,11 @@ pub struct SwapReq {
|
||||||
#[rpc(server)]
|
#[rpc(server)]
|
||||||
pub trait API {
|
pub trait API {
|
||||||
#[rpc(name = "swap")]
|
#[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
|
// milestone 3: Used by mwixnet coinswap servers to communicate with each other
|
||||||
// fn derive_outputs(&self, entries: Vec<Onion>) -> Result<Value>;
|
// fn derive_outputs(&self, entries: Vec<Onion>) -> jsonrpc_core::Result<Value>;
|
||||||
// fn derive_kernel(&self, tx: Tx) -> Result<Value>;
|
// fn derive_kernel(&self, tx: Tx) -> jsonrpc_core::Result<Value>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -73,7 +73,7 @@ impl From<SwapError> for Error {
|
||||||
|
|
||||||
impl API for RPCServer {
|
impl API for RPCServer {
|
||||||
/// Implements the 'swap' API
|
/// Implements the 'swap' API
|
||||||
fn swap(&self, swap: SwapReq) -> Result<Value> {
|
fn swap(&self, swap: SwapReq) -> jsonrpc_core::Result<Value> {
|
||||||
self.server
|
self.server
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
55
src/secp.rs
55
src/secp.rs
|
@ -8,12 +8,11 @@ pub use secp256k1zkp::key::{PublicKey, SecretKey, ZERO_KEY};
|
||||||
pub use secp256k1zkp::pedersen::{Commitment, RangeProof};
|
pub use secp256k1zkp::pedersen::{Commitment, RangeProof};
|
||||||
pub use secp256k1zkp::{ContextFlag, Message, Secp256k1, Signature};
|
pub use secp256k1zkp::{ContextFlag, Message, Secp256k1, Signature};
|
||||||
|
|
||||||
use crate::error::{Error, ErrorKind, Result};
|
|
||||||
|
|
||||||
use blake2::blake2b::Blake2b;
|
use blake2::blake2b::Blake2b;
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
use grin_core::ser::{self, Readable, Reader, Writeable, Writer};
|
use grin_core::ser::{self, Readable, Reader, Writeable, Writer};
|
||||||
use secp256k1zkp::rand::thread_rng;
|
use secp256k1zkp::rand::thread_rng;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
/// A generalized Schnorr signature with a pedersen commitment value & blinding factors as the keys
|
/// A generalized Schnorr signature with a pedersen commitment value & blinding factors as the keys
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -23,6 +22,21 @@ pub struct ComSignature {
|
||||||
t: SecretKey,
|
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 {
|
impl ComSignature {
|
||||||
pub fn new(pub_nonce: &Commitment, s: &SecretKey, t: &SecretKey) -> ComSignature {
|
pub fn new(pub_nonce: &Commitment, s: &SecretKey, t: &SecretKey) -> ComSignature {
|
||||||
ComSignature {
|
ComSignature {
|
||||||
|
@ -33,7 +47,11 @@ impl ComSignature {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[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 secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||||
|
|
||||||
let mut amt_bytes = [0; 32];
|
let mut amt_bytes = [0; 32];
|
||||||
|
@ -62,7 +80,7 @@ impl ComSignature {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[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 secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||||
|
|
||||||
let S1 = secp.commit_blind(self.s.clone(), self.t.clone())?;
|
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())?;
|
let S2 = secp.commit_sum(commits, Vec::new())?;
|
||||||
|
|
||||||
if S1 != S2 {
|
if S1 != S2 {
|
||||||
return Err(Error::new(ErrorKind::InvalidSigError));
|
return Err(ComSigError::InvalidSig);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -86,7 +104,7 @@ impl ComSignature {
|
||||||
commit: &Commitment,
|
commit: &Commitment,
|
||||||
nonce_commit: &Commitment,
|
nonce_commit: &Commitment,
|
||||||
msg: &Vec<u8>,
|
msg: &Vec<u8>,
|
||||||
) -> Result<SecretKey> {
|
) -> Result<SecretKey, ComSigError> {
|
||||||
let mut challenge_hasher = Blake2b::new(32);
|
let mut challenge_hasher = Blake2b::new(32);
|
||||||
challenge_hasher.update(&commit.0);
|
challenge_hasher.update(&commit.0);
|
||||||
challenge_hasher.update(&nonce_commit.0);
|
challenge_hasher.update(&nonce_commit.0);
|
||||||
|
@ -131,7 +149,7 @@ pub mod comsig_serde {
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
impl Readable for ComSignature {
|
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 R = Commitment::read(reader)?;
|
||||||
let s = read_secret_key(reader)?;
|
let s = read_secret_key(reader)?;
|
||||||
let t = read_secret_key(reader)?;
|
let t = read_secret_key(reader)?;
|
||||||
|
@ -140,7 +158,7 @@ impl Readable for ComSignature {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Writeable 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.pub_nonce.0)?;
|
||||||
writer.write_fixed_bytes(self.s.0)?;
|
writer.write_fixed_bytes(self.s.0)?;
|
||||||
writer.write_fixed_bytes(self.t.0)?;
|
writer.write_fixed_bytes(self.t.0)?;
|
||||||
|
@ -155,7 +173,7 @@ pub fn random_secret() -> SecretKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize a SecretKey from a Reader
|
/// 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 buf = reader.read_fixed_bytes(SECRET_KEY_SIZE)?;
|
||||||
let secp = Secp256k1::with_caps(ContextFlag::None);
|
let secp = Secp256k1::with_caps(ContextFlag::None);
|
||||||
let pk = SecretKey::from_slice(&secp, &buf).map_err(|_| ser::Error::CorruptedData)?;
|
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
|
/// Build a Pedersen Commitment using the provided value and blinding factor
|
||||||
pub fn commit(
|
pub fn commit(value: u64, blind: &SecretKey) -> Result<Commitment, secp256k1zkp::Error> {
|
||||||
value: u64,
|
|
||||||
blind: &SecretKey,
|
|
||||||
) -> std::result::Result<Commitment, secp256k1zkp::Error> {
|
|
||||||
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||||
let commit = secp.commit(value, blind.clone())?;
|
let commit = secp.commit(value, blind.clone())?;
|
||||||
Ok(commit)
|
Ok(commit)
|
||||||
|
@ -176,7 +191,7 @@ pub fn commit(
|
||||||
pub fn add_excess(
|
pub fn add_excess(
|
||||||
commitment: &Commitment,
|
commitment: &Commitment,
|
||||||
excess: &SecretKey,
|
excess: &SecretKey,
|
||||||
) -> std::result::Result<Commitment, secp256k1zkp::Error> {
|
) -> Result<Commitment, secp256k1zkp::Error> {
|
||||||
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||||
let excess_commit: Commitment = secp.commit(0, excess.clone())?;
|
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
|
/// Subtracts a value (v*H) from an existing commitment
|
||||||
pub fn sub_value(
|
pub fn sub_value(commitment: &Commitment, value: u64) -> Result<Commitment, secp256k1zkp::Error> {
|
||||||
commitment: &Commitment,
|
|
||||||
value: u64,
|
|
||||||
) -> std::result::Result<Commitment, secp256k1zkp::Error> {
|
|
||||||
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||||
let neg_commit: Commitment = secp.commit(value, ZERO_KEY)?;
|
let neg_commit: Commitment = secp.commit(value, ZERO_KEY)?;
|
||||||
let sum = secp.commit_sum(vec![commitment.clone()], vec![neg_commit.clone()])?;
|
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
|
/// 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 secp = Secp256k1::with_caps(ContextFlag::Full);
|
||||||
let pubkey = PublicKey::from_secret_key(&secp, &sk)?;
|
let pubkey = PublicKey::from_secret_key(&secp, &sk)?;
|
||||||
let sig = aggsig::sign_single(&secp, &msg, &sk, None, None, None, Some(&pubkey), None)?;
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{ComSignature, ContextFlag, Secp256k1, SecretKey};
|
use super::{ComSigError, ComSignature, ContextFlag, Secp256k1, SecretKey};
|
||||||
use crate::error::Result;
|
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use secp256k1zkp::rand::{thread_rng, RngCore};
|
use secp256k1zkp::rand::{thread_rng, RngCore};
|
||||||
|
|
||||||
/// Test signing and verification of ComSignatures
|
/// Test signing and verification of ComSignatures
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_comsig() -> Result<()> {
|
fn verify_comsig() -> Result<(), ComSigError> {
|
||||||
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||||
|
|
||||||
let amount = thread_rng().next_u64();
|
let amount = thread_rng().next_u64();
|
||||||
|
|
Loading…
Reference in a new issue