Re-license bitcoin-serai to MIT

It's pretty basic code, yet would still be quite pleasant to the larger
community.

Also adds documentation.
This commit is contained in:
Luke Parker
2023-01-31 09:28:03 -05:00
parent 86ad947261
commit df75782e54
5 changed files with 52 additions and 20 deletions

View File

@@ -14,17 +14,19 @@ use bitcoin::XOnlyPublicKey;
use frost::{algorithm::Hram, curve::Secp256k1};
/// Get the x coordinate of a non-infinity, even point.
/// Get the x coordinate of a non-infinity, even point. Panics on invalid input.
pub fn x(key: &ProjectivePoint) -> [u8; 32] {
let encoded = key.to_encoded_point(true);
assert_eq!(encoded.tag(), Tag::CompressedEvenY);
(*encoded.x().expect("point at infinity")).into()
}
/// Convert a non-infinite even point to a XOnlyPublicKey. Panics on invalid input.
pub fn x_only(key: &ProjectivePoint) -> XOnlyPublicKey {
XOnlyPublicKey::from_slice(&x(key)).unwrap()
}
/// Make a point even, returning the even version and the offset required for it to be even.
pub fn make_even(mut key: ProjectivePoint) -> (ProjectivePoint, u64) {
let mut c = 0;
while key.to_encoded_point(true).tag() == Tag::CompressedOddY {
@@ -34,7 +36,8 @@ pub fn make_even(mut key: ProjectivePoint) -> (ProjectivePoint, u64) {
(key, c)
}
#[derive(Clone)]
/// A BIP-340 compatible HRAm for use with the modular-frost Schnorr Algorithm.
#[derive(Clone, Copy, Debug)]
pub struct BitcoinHram {}
lazy_static! {

View File

@@ -1,5 +1,8 @@
/// Cryptographic helpers.
pub mod crypto;
/// Wallet functionality to create transactions.
pub mod wallet;
/// A minimal async RPC.
pub mod rpc;
#[cfg(test)]

View File

@@ -1,5 +1,5 @@
use std::{
io::{self, Read},
io::{self, Read, Write},
collections::HashMap,
};
@@ -17,25 +17,32 @@ use frost::{
use bitcoin::{
hashes::Hash,
consensus::encode::{Encodable, Decodable, serialize},
consensus::encode::{Decodable, serialize},
util::sighash::{SchnorrSighashType, SighashCache, Prevouts},
OutPoint, Script, Sequence, Witness, TxIn, TxOut, PackedLockTime, Transaction, Address,
};
use crate::crypto::{BitcoinHram, make_even};
/// A spendable output.
#[derive(Clone, Debug)]
pub struct SpendableOutput {
/// The scalar offset to obtain the key usable to spend this output.
/// Enables HDKD systems.
pub offset: Scalar,
/// The output to spend.
pub output: TxOut,
/// The TX ID and vout of the output to spend.
pub outpoint: OutPoint,
}
impl SpendableOutput {
/// Obtain a unique ID for this output.
pub fn id(&self) -> [u8; 36] {
serialize(&self.outpoint).try_into().unwrap()
}
/// Read a SpendableOutput from a generic satisfying Read.
pub fn read<R: Read>(r: &mut R) -> io::Result<SpendableOutput> {
Ok(SpendableOutput {
offset: Secp256k1::read_F(r)?,
@@ -46,14 +53,22 @@ impl SpendableOutput {
})
}
/// Write a SpendableOutput to a generic satisfying Write.
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
w.write_all(&self.offset.to_bytes())?;
w.write_all(&serialize(&self.output))?;
w.write_all(&serialize(&self.outpoint))
}
/// Serialize a SpendableOutput to a Vec<u8>.
pub fn serialize(&self) -> Vec<u8> {
let mut res = self.offset.to_bytes().to_vec();
self.output.consensus_encode(&mut res).unwrap();
self.outpoint.consensus_encode(&mut res).unwrap();
let mut res = vec![];
self.write(&mut res).unwrap();
res
}
}
/// A signable transaction, clone-able across attempts.
#[derive(Clone, Debug)]
pub struct SignableTransaction(Transaction, Vec<Scalar>, Vec<TxOut>);
@@ -82,6 +97,7 @@ impl SignableTransaction {
u64::try_from(tx.weight()).unwrap()
}
/// Create a new signable-transaction.
pub fn new(
mut inputs: Vec<SpendableOutput>,
payments: &[(Address, u64)],
@@ -130,6 +146,7 @@ impl SignableTransaction {
))
}
/// Create a multisig machine for this transaction.
pub async fn multisig(
self,
keys: ThresholdKeys<Secp256k1>,
@@ -165,6 +182,7 @@ impl SignableTransaction {
}
}
/// A FROST signing machine to produce a Bitcoin transaction.
pub struct TransactionMachine {
tx: SignableTransaction,
transcript: RecommendedTranscript,