Skip to content

Commit

Permalink
Switch to ed25519-zebra for consensus signature checks
Browse files Browse the repository at this point in the history
ed25519-zebra can validate all signatures pre-Canopy, and now that Canopy
is active on mainnet, we don't need to worry about consensus divergence.
  • Loading branch information
str4d committed Dec 4, 2020
1 parent 77c2a5f commit c3a91be
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 75 deletions.
34 changes: 6 additions & 28 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

#include "main.h"

#include "sodium.h"

#include "addrman.h"
#include "alert.h"
#include "arith_uint256.h"
Expand Down Expand Up @@ -46,6 +44,8 @@
#include <boost/math/distributions/poisson.hpp>
#include <boost/thread.hpp>

#include <rust/ed25519.h>

using namespace std;

#if defined(NDEBUG)
Expand Down Expand Up @@ -1053,39 +1053,17 @@ bool ContextualCheckTransaction(
}
}

int (*ed25519_verifier)(
const unsigned char *,
const unsigned char *,
unsigned long long ,
const unsigned char *
) = &crypto_sign_verify_detached;

// Switch from using the libsodium ed25519 verifier to using the
// ed25519-zebra Rust crate, which implements an ed25519 verifier that is
// compliant with ZIP 215.
if (canopyActive) {
ed25519_verifier = &librustzcash_zebra_crypto_sign_verify_detached;
}

if (!tx.vJoinSplit.empty())
{
static_assert(crypto_sign_PUBLICKEYBYTES == 32);

// We rely on libsodium to check that the signature is canonical.
// https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0
if (ed25519_verifier(tx.joinSplitSig.bytes,
dataToBeSigned.begin(), 32,
tx.joinSplitPubKey.bytes
) != 0) {
if (!ed25519_verify(&tx.joinSplitPubKey, &tx.joinSplitSig, dataToBeSigned.begin(), 32)) {
// Check whether the failure was caused by an outdated consensus
// branch ID; if so, inform the node that they need to upgrade. We
// only check the previous epoch's branch ID, on the assumption that
// users creating transactions will notice their transactions
// failing before a second network upgrade occurs.
if (ed25519_verifier(tx.joinSplitSig.bytes,
prevDataToBeSigned.begin(), 32,
tx.joinSplitPubKey.bytes
) == 0) {
if (ed25519_verify(&tx.joinSplitPubKey,
&tx.joinSplitSig,
prevDataToBeSigned.begin(), 32)) {
return state.DoS(
dosLevelPotentiallyRelaxing, false, REJECT_INVALID, strprintf(
"old-consensus-branch-id (Expected %s, found %s)",
Expand Down
7 changes: 0 additions & 7 deletions src/rust/include/librustzcash.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,13 +364,6 @@ extern "C" {
unsigned char *buf,
size_t buf_len
);

int librustzcash_zebra_crypto_sign_verify_detached(
const unsigned char *sig,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *pk
);
#ifdef __cplusplus
}
#endif
Expand Down
40 changes: 0 additions & 40 deletions src/rust/src/rustzcash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1250,43 +1250,3 @@ pub extern "C" fn librustzcash_getrandom(buf: *mut u8, buf_len: usize) {
let buf = unsafe { slice::from_raw_parts_mut(buf, buf_len) };
OsRng.fill_bytes(buf);
}

// The `librustzcash_zebra_crypto_sign_verify_detached` API attempts to
// mimic the `crypto_sign_verify_detached` API in libsodium, but uses
// the ed25519-zebra crate internally instead.
const LIBSODIUM_OK: isize = 0;
const LIBSODIUM_ERROR: isize = -1;

#[no_mangle]
pub extern "system" fn librustzcash_zebra_crypto_sign_verify_detached(
sig: *const [u8; 64],
m: *const u8,
mlen: u64,
pk: *const [u8; 32],
) -> isize {
use ed25519_zebra::{Signature, VerificationKey};
use std::convert::TryFrom;

let sig = Signature::from(*unsafe {
match sig.as_ref() {
Some(sig) => sig,
None => return LIBSODIUM_ERROR,
}
});

let pk = match VerificationKey::try_from(*match unsafe { pk.as_ref() } {
Some(pk) => pk,
None => return LIBSODIUM_ERROR,
}) {
Ok(pk) => pk,
Err(_) => return LIBSODIUM_ERROR,
};

let m = unsafe { slice::from_raw_parts(m, mlen as usize) };

if pk.verify(&sig, m).is_err() {
LIBSODIUM_ERROR
} else {
LIBSODIUM_OK
}
}

0 comments on commit c3a91be

Please sign in to comment.