Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ecdsa adaptor #1

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions background-processor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ Utilities to perform required background tasks for Rust Lightning.
edition = "2018"

[dependencies]
bitcoin = "0.26"
lightning = { version = "0.0.13", path = "../lightning", features = ["allow_wallclock_use"] }
bitcoin = {version="0.26.0-adaptor.0", git = "https://github.com/p2pderivatives/rust-bitcoin", branch = "ecdsa-adaptor", package="bitcoin"}
lightning = { version = "0.0.13-adaptor.0", path = "../lightning" }
lightning-persister = { version = "0.0.13", path = "../lightning-persister" }

[dev-dependencies]
lightning = { version = "0.0.13", path = "../lightning", features = ["_test_utils"] }
lightning = { version = "0.0.13-adaptor.0", path = "../lightning", features = ["_test_utils"] }

[dev-dependencies.bitcoin]
version = "0.26"
version = "0.26.0-adaptor.0"
git = "https://github.com/p2pderivatives/rust-bitcoin"
branch = "ecdsa-adaptor"
features = ["bitcoinconsensus"]
4 changes: 2 additions & 2 deletions lightning-block-sync/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ rest-client = [ "serde", "serde_json", "chunked_transfer" ]
rpc-client = [ "serde", "serde_json", "chunked_transfer" ]

[dependencies]
bitcoin = "0.26"
lightning = { version = "0.0.13", path = "../lightning" }
bitcoin = {version="0.26.0-adaptor.0", git = "https://github.com/p2pderivatives/rust-bitcoin", branch = "ecdsa-adaptor", package="bitcoin"}
lightning = { version = "0.0.13-adaptor.0", path = "../lightning" }
tokio = { version = "1.0", features = [ "io-util", "net" ], optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0", optional = true }
Expand Down
6 changes: 3 additions & 3 deletions lightning-net-tokio/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "lightning-net-tokio"
version = "0.0.13"
version = "0.0.13-adaptor.0"
authors = ["Matt Corallo"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-bitcoin/rust-lightning/"
Expand All @@ -11,8 +11,8 @@ For Rust-Lightning clients which wish to make direct connections to Lightning P2
edition = "2018"

[dependencies]
bitcoin = "0.26"
lightning = { version = "0.0.13", path = "../lightning" }
bitcoin = {version="0.26.0-adaptor.0", git = "https://github.com/p2pderivatives/rust-bitcoin", branch = "ecdsa-adaptor", package="bitcoin"}
lightning = { version = "0.0.13-adaptor.0", path = "../lightning" }
tokio = { version = "1.0", features = [ "io-util", "macros", "rt", "sync", "net", "time" ] }

[dev-dependencies]
Expand Down
10 changes: 6 additions & 4 deletions lightning-persister/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ Utilities to manage Rust-Lightning channel data persistence and retrieval.
unstable = ["lightning/unstable"]

[dependencies]
bitcoin = "0.26"
lightning = { version = "0.0.13", path = "../lightning" }
bitcoin = {version="0.26.0-adaptor.0", git = "https://github.com/p2pderivatives/rust-bitcoin", branch = "ecdsa-adaptor", package="bitcoin"}
lightning = { version = "0.0.13-adaptor.0", path = "../lightning" }
libc = "0.2"

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winbase"] }

[dev-dependencies.bitcoin]
version = "0.26"
version = "0.26.0-adaptor.0"
git = "https://github.com/p2pderivatives/rust-bitcoin"
branch = "ecdsa-adaptor"
features = ["bitcoinconsensus"]

[dev-dependencies]
lightning = { version = "0.0.13", path = "../lightning", features = ["_test_utils"] }
lightning = { version = "0.0.13-adaptor.0", path = "../lightning", features = ["_test_utils"] }
8 changes: 5 additions & 3 deletions lightning/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "lightning"
version = "0.0.13"
version = "0.0.13-adaptor.0"
authors = ["Matt Corallo"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-bitcoin/rust-lightning/"
Expand All @@ -27,13 +27,15 @@ unsafe_revoked_tx_signing = []
unstable = []

[dependencies]
bitcoin = "0.26"
bitcoin = {version="0.26.0-adaptor.0", git = "https://github.com/p2pderivatives/rust-bitcoin", branch = "ecdsa-adaptor", package="bitcoin"}

hex = { version = "0.3", optional = true }
regex = { version = "0.1.80", optional = true }

[dev-dependencies.bitcoin]
version = "0.26"
version = "0.26.0-adaptor.0"
git = "https://github.com/p2pderivatives/rust-bitcoin"
branch = "ecdsa-adaptor"
features = ["bitcoinconsensus"]

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/ln/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub(crate) mod peer_channel_encryptor;

mod channel;
mod onion_utils;
mod wire;
pub mod wire;

// Older rustc (which we support) refuses to let us call the get_payment_preimage_hash!() macro
// without the node parameter being mut. This is incorrect, and thus newer rustcs will complain
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ pub(crate) mod chacha20poly1305rfc;
pub(crate) mod transaction_utils;
pub(crate) mod scid_utils;

/// Macros for serialization
#[macro_use]
pub(crate) mod ser_macros;
pub mod ser_macros;

/// Logging macro utilities.
#[macro_use]
Expand Down
110 changes: 106 additions & 4 deletions lightning/src/util/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use std::sync::Mutex;
use std::cmp;

use bitcoin::secp256k1::Signature;
use bitcoin::secp256k1::constants::{SCHNORRSIG_SIGNATURE_SIZE, SCHNORRSIG_PUBLIC_KEY_SIZE};
use bitcoin::secp256k1::key::{PublicKey, SecretKey};
use bitcoin::secp256k1::schnorrsig;
use bitcoin::blockdata::script::Script;
use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
use bitcoin::consensus;
Expand Down Expand Up @@ -84,7 +86,7 @@ impl Writer for VecWriter {

/// Writer that only tracks the amount of data written - useful if you need to calculate the length
/// of some data when serialized but don't yet need the full data.
pub(crate) struct LengthCalculatingWriter(pub usize);
pub struct LengthCalculatingWriter(pub usize);
impl Writer for LengthCalculatingWriter {
#[inline]
fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
Expand All @@ -97,20 +99,23 @@ impl Writer for LengthCalculatingWriter {

/// Essentially std::io::Take but a bit simpler and with a method to walk the underlying stream
/// forward to ensure we always consume exactly the fixed length specified.
pub(crate) struct FixedLengthReader<R: Read> {
pub struct FixedLengthReader<R: Read> {
read: R,
bytes_read: u64,
total_bytes: u64,
}
impl<R: Read> FixedLengthReader<R> {
/// Create a new FixedLengthReader.
pub fn new(read: R, total_bytes: u64) -> Self {
Self { read, bytes_read: 0, total_bytes }
}

/// Whether the reader has remaining bytes to read.
pub fn bytes_remain(&mut self) -> bool {
self.bytes_read != self.total_bytes
}

/// Eat the remaining of the reader.
pub fn eat_remaining(&mut self) -> Result<(), DecodeError> {
::std::io::copy(self, &mut ::std::io::sink()).unwrap();
if self.bytes_read != self.total_bytes {
Expand All @@ -120,6 +125,7 @@ impl<R: Read> FixedLengthReader<R> {
}
}
}

impl<R: Read> Read for FixedLengthReader<R> {
fn read(&mut self, dest: &mut [u8]) -> Result<usize, ::std::io::Error> {
if self.total_bytes == self.bytes_read {
Expand All @@ -139,16 +145,23 @@ impl<R: Read> Read for FixedLengthReader<R> {

/// A Read which tracks whether any bytes have been read at all. This allows us to distinguish
/// between "EOF reached before we started" and "EOF reached mid-read".
pub(crate) struct ReadTrackingReader<R: Read> {
pub struct ReadTrackingReader<R: Read> {
read: R,
/// Whether any bytes have been read or not.
pub have_read: bool,
}

/// Implementation for ReadTrackingReader.
impl<R: Read> ReadTrackingReader<R> {
/// Create a new ReadTrackingReader.
pub fn new(read: R) -> Self {
Self { read, have_read: false }
}
}

/// Implements the Read trait for ReadTrackingReader.
impl<R: Read> Read for ReadTrackingReader<R> {
/// Read into the given buffer.
fn read(&mut self, dest: &mut [u8]) -> Result<usize, ::std::io::Error> {
match self.read.read(dest) {
Ok(0) => Ok(0),
Expand Down Expand Up @@ -244,7 +257,7 @@ impl Readable for U48 {
/// encoded in several different ways, which we must check for at deserialization-time. Thus, if
/// you're looking for an example of a variable-length integer to use for your own project, move
/// along, this is a rather poor design.
pub(crate) struct BigSize(pub u64);
pub struct BigSize(pub u64);
impl Writeable for BigSize {
#[inline]
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
Expand Down Expand Up @@ -425,6 +438,8 @@ impl_array!(16); // for IPv6
impl_array!(32); // for channel id & hmac
impl_array!(33); // for PublicKey
impl_array!(64); // for Signature
impl_array!(65); // for AdaptorSignature
impl_array!(97); // for AdaptorProof
impl_array!(1300); // for OnionPacket.hop_data

// HashMap
Expand Down Expand Up @@ -477,6 +492,7 @@ impl Readable for Vec<u8> {
Ok(ret)
}
}

impl Writeable for Vec<Signature> {
#[inline]
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
Expand Down Expand Up @@ -504,6 +520,60 @@ impl Readable for Vec<Signature> {
}
}

impl Writeable for Vec<schnorrsig::Signature> {
#[inline]
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
(self.len() as u16).write(w)?;
for e in self.iter() {
e.write(w)?;
}
Ok(())
}
}

impl Readable for Vec<schnorrsig::Signature> {
#[inline]
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let len: u16 = Readable::read(r)?;
let byte_size = (len as usize)
.checked_mul(SCHNORRSIG_SIGNATURE_SIZE)
.ok_or(DecodeError::BadLengthDescriptor)?;
if byte_size > MAX_BUF_SIZE {
return Err(DecodeError::BadLengthDescriptor);
}
let mut ret = Vec::with_capacity(len as usize);
for _ in 0..len { ret.push(schnorrsig::Signature::read(r)?); }
Ok(ret)
}
}

impl Writeable for Vec<schnorrsig::PublicKey> {
#[inline]
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
(self.len() as u16).write(w)?;
for e in self.iter() {
e.write(w)?;
}
Ok(())
}
}

impl Readable for Vec<schnorrsig::PublicKey> {
#[inline]
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let len: u16 = Readable::read(r)?;
let byte_size = (len as usize)
.checked_mul(SCHNORRSIG_PUBLIC_KEY_SIZE)
.ok_or(DecodeError::BadLengthDescriptor)?;
if byte_size > MAX_BUF_SIZE {
return Err(DecodeError::BadLengthDescriptor);
}
let mut ret = Vec::with_capacity(len as usize);
for _ in 0..len { ret.push(schnorrsig::PublicKey::read(r)?); }
Ok(ret)
}
}

impl Writeable for Script {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
(self.len() as u16).write(w)?;
Expand Down Expand Up @@ -536,6 +606,22 @@ impl Readable for PublicKey {
}
}

impl Writeable for schnorrsig::PublicKey {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
self.serialize().write(w)
}
}

impl Readable for schnorrsig::PublicKey {
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let buf: [u8; 33] = Readable::read(r)?;
match schnorrsig::PublicKey::from_slice(&buf) {
Ok(key) => Ok(key),
Err(_) => return Err(DecodeError::InvalidValue),
}
}
}

impl Writeable for SecretKey {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
let mut ser = [0; 32];
Expand Down Expand Up @@ -585,6 +671,22 @@ impl Readable for Signature {
}
}

impl Writeable for schnorrsig::Signature {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
self.as_ref().write(w)
}
}

impl Readable for schnorrsig::Signature {
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let buf: [u8; 64] = Readable::read(r)?;
match schnorrsig::Signature::from_slice(&buf) {
Ok(sig) => Ok(sig),
Err(_) => return Err(DecodeError::InvalidValue),
}
}
}

impl Writeable for PaymentPreimage {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
self.0.write(w)
Expand Down
Loading