From 9791e5df3e5a12c2a765e8eea55a585e1314cbd5 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 14 Dec 2023 20:26:15 +0100 Subject: [PATCH] dbc: refactor validation workflow --- consensus/src/script.rs | 2 +- dbc/src/anchor.rs | 18 ++++++----- dbc/src/opret/mod.rs | 56 ++++++++++++++-------------------- dbc/src/opret/spk.rs | 58 ++++++++++++++++++++++++++++++++++++ dbc/src/opret/tx.rs | 56 ++++++++++++++++++++++++++++++++++ dbc/src/opret/txout.rs | 46 ++++++++++++++++++++++++++++ dbc/src/tapret/mod.rs | 17 +++++------ dbc/src/tapret/spk.rs | 6 ++-- dbc/src/tapret/tapscript.rs | 4 +-- dbc/src/tapret/tx.rs | 6 ++-- dbc/src/tapret/txout.rs | 6 ++-- dbc/src/tapret/xonlypk.rs | 12 ++++---- seals/src/txout/blind.rs | 4 +-- src/stl.rs | 2 +- stl/BPCore@0.1.0.sta | 50 +++++++++++++++---------------- stl/BPCore@0.1.0.stl | Bin 3687 -> 3691 bytes stl/BPCore@0.1.0.sty | 10 +++---- 17 files changed, 251 insertions(+), 102 deletions(-) create mode 100644 dbc/src/opret/spk.rs create mode 100644 dbc/src/opret/tx.rs create mode 100644 dbc/src/opret/txout.rs diff --git a/consensus/src/script.rs b/consensus/src/script.rs index 2764bf77..72f797b8 100644 --- a/consensus/src/script.rs +++ b/consensus/src/script.rs @@ -229,7 +229,7 @@ impl ScriptPubkey { } #[inline] - pub fn is_op_return(&self) -> bool { self[0] == OpCode::Return as u8 } + pub fn is_op_return(&self) -> bool { !self.is_empty() && self[0] == OpCode::Return as u8 } /// Adds a single opcode to the script. #[inline] diff --git a/dbc/src/anchor.rs b/dbc/src/anchor.rs index 07262dd2..8855c2c8 100644 --- a/dbc/src/anchor.rs +++ b/dbc/src/anchor.rs @@ -119,16 +119,16 @@ impl PartialOrd for Anchor { #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Display, Error, From)] #[display(doc_comments)] pub enum MergeError { - /// Error merging two LNPBP-4 proofs, which are unrelated. + /// Error merging two MPC proofs, which are unrelated. #[display(inner)] #[from] - Lnpbp4Mismatch(mpc::MergeError), + MpcMismatch(mpc::MergeError), /// anchors can't be merged since they have different witness transactions TxidMismatch, - /// anchors can't be merged since they have different proofs - ProofMismatch, + /// anchors can't be merged since they have different DBC proofs + DbcMismatch, } impl Anchor { @@ -178,10 +178,12 @@ impl Anchor { protocol_id: impl Into, message: Message, tx: &Tx, - ) -> Result<(), VerifyError> { + ) -> Result> { + let mpc_commitment = self.convolve(protocol_id, message)?; self.dbc_proof - .verify(&self.mpc_proof.convolve(protocol_id.into(), message)?, tx) - .map_err(VerifyError::Dbc) + .verify(&mpc_commitment, tx) + .map_err(VerifyError::Dbc)?; + Ok(mpc_commitment) } /// Verifies that the anchor commits to the given message under the given @@ -233,7 +235,7 @@ impl Anchor { return Err(MergeError::TxidMismatch); } if self.dbc_proof != other.dbc_proof { - return Err(MergeError::ProofMismatch); + return Err(MergeError::DbcMismatch); } self.mpc_proof.merge_reveal(other.mpc_proof)?; Ok(self) diff --git a/dbc/src/opret/mod.rs b/dbc/src/opret/mod.rs index 8939c8f9..2b533d0b 100644 --- a/dbc/src/opret/mod.rs +++ b/dbc/src/opret/mod.rs @@ -21,12 +21,23 @@ //! ScriptPubkey-based OP_RETURN commitments. -use bc::{ScriptPubkey, Tx, Txid}; +mod tx; +mod txout; +mod spk; + +use bc::Tx; use commit_verify::mpc::Commitment; +use commit_verify::{CommitmentProtocol, EmbedCommitVerify, EmbedVerifyError}; use crate::{Proof, LIB_NAME_BPCORE}; -/// Errors covering failed anchor validation. +/// Marker non-instantiable enum defining LNPBP-12 taproot OP_RETURN (`tapret`) +/// protocol. +pub enum Opret {} + +impl CommitmentProtocol for Opret {} + +/// Errors during tapret commitment. #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] #[cfg_attr( feature = "serde", @@ -34,21 +45,13 @@ use crate::{Proof, LIB_NAME_BPCORE}; serde(crate = "serde_crate", rename_all = "camelCase") )] #[display(doc_comments)] -pub enum OpretVerifyError { - /// witness transaction {txid} contains invalid OP_RETURN commitment - /// {present:x} instead of {expected:x}. - OpretMismatch { - /// Transaction id - txid: Txid, - /// Commitment from the first OP_RETURN transaction output - present: ScriptPubkey, - /// Expected commitment absent in the first OP_RETURN transaction output - expected: ScriptPubkey, - }, +pub enum OpretError { + /// transaction doesn't contain OP_RETURN output. + NoOpretOutput, - /// witness transaction {0} does not contain any OP_RETURN commitment - /// required by the seal definition. - OpretAbsent(Txid), + /// first OP_RETURN output inside the transaction already contains some + /// data. + InvalidOpretScript, } /// Empty type for use inside [`crate::Anchor`] for opret commitment scheme. @@ -65,24 +68,9 @@ pub enum OpretVerifyError { pub struct OpretProof(()); impl Proof for OpretProof { - type Error = OpretVerifyError; + type Error = EmbedVerifyError; - fn verify(&self, msg: &Commitment, tx: &Tx) -> Result<(), OpretVerifyError> { - // TODO: Use embed-commit-verify - for txout in &tx.outputs { - if txout.script_pubkey.is_op_return() { - let expected = ScriptPubkey::op_return(msg.as_slice()); - if txout.script_pubkey == expected { - return Ok(()); - } else { - return Err(OpretVerifyError::OpretMismatch { - txid: tx.txid(), - present: txout.script_pubkey.clone(), - expected, - }); - } - } - } - Err(OpretVerifyError::OpretAbsent(tx.txid())) + fn verify(&self, msg: &Commitment, tx: &Tx) -> Result<(), EmbedVerifyError> { + tx.verify(msg, self) } } diff --git a/dbc/src/opret/spk.rs b/dbc/src/opret/spk.rs new file mode 100644 index 00000000..f66fadc4 --- /dev/null +++ b/dbc/src/opret/spk.rs @@ -0,0 +1,58 @@ +// Deterministic bitcoin commitments library. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Written in 2019-2023 by +// Dr Maxim Orlovsky +// +// Copyright (C) 2019-2023 LNP/BP Standards Association. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use bc::opcodes::OP_RETURN; +use bc::ScriptPubkey; +use commit_verify::mpc::Commitment; +use commit_verify::{EmbedCommitProof, EmbedCommitVerify, EmbedVerifyError}; + +use crate::opret::{Opret, OpretError, OpretProof}; + +impl EmbedCommitProof for OpretProof { + fn restore_original_container( + &self, + commit_container: &ScriptPubkey, + ) -> Result> { + if !commit_container.is_op_return() { + return Err(OpretError::NoOpretOutput.into()); + } + if commit_container.len() != 34 { + return Err(OpretError::InvalidOpretScript.into()); + } + Ok(ScriptPubkey::from_unsafe(vec![OP_RETURN])) + } +} + +impl EmbedCommitVerify for ScriptPubkey { + type Proof = OpretProof; + type CommitError = OpretError; + + fn embed_commit(&mut self, msg: &Commitment) -> Result { + if !self.is_op_return() { + return Err(OpretError::NoOpretOutput); + } + if self.len() != 1 { + return Err(OpretError::InvalidOpretScript); + } + *self = ScriptPubkey::op_return(msg.as_slice()); + Ok(OpretProof::default()) + } +} diff --git a/dbc/src/opret/tx.rs b/dbc/src/opret/tx.rs new file mode 100644 index 00000000..95d6c5a2 --- /dev/null +++ b/dbc/src/opret/tx.rs @@ -0,0 +1,56 @@ +// Deterministic bitcoin commitments library. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Written in 2019-2023 by +// Dr Maxim Orlovsky +// +// Copyright (C) 2019-2023 LNP/BP Standards Association. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use bc::Tx; +use commit_verify::mpc::Commitment; +use commit_verify::{EmbedCommitProof, EmbedCommitVerify, EmbedVerifyError}; + +use super::{Opret, OpretError, OpretProof}; + +impl EmbedCommitProof for OpretProof { + fn restore_original_container( + &self, + commit_container: &Tx, + ) -> Result> { + let mut tx = commit_container.clone(); + for txout in &mut tx.outputs { + if txout.script_pubkey.is_op_return() { + *txout = self.restore_original_container(txout)?; + return Ok(tx); + } + } + Err(OpretError::NoOpretOutput.into()) + } +} + +impl EmbedCommitVerify for Tx { + type Proof = OpretProof; + type CommitError = OpretError; + + fn embed_commit(&mut self, msg: &Commitment) -> Result { + for txout in &mut self.outputs { + if txout.script_pubkey.is_op_return() { + return txout.script_pubkey.embed_commit(msg); + } + } + Err(OpretError::NoOpretOutput) + } +} diff --git a/dbc/src/opret/txout.rs b/dbc/src/opret/txout.rs new file mode 100644 index 00000000..40d61dd4 --- /dev/null +++ b/dbc/src/opret/txout.rs @@ -0,0 +1,46 @@ +// Deterministic bitcoin commitments library. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Written in 2019-2023 by +// Dr Maxim Orlovsky +// +// Copyright (C) 2019-2023 LNP/BP Standards Association. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use bc::TxOut; +use commit_verify::mpc::Commitment; +use commit_verify::{EmbedCommitProof, EmbedCommitVerify, EmbedVerifyError}; + +use crate::opret::{Opret, OpretError, OpretProof}; + +impl EmbedCommitProof for OpretProof { + fn restore_original_container( + &self, + commit_container: &TxOut, + ) -> Result> { + let mut txout = commit_container.clone(); + txout.script_pubkey = self.restore_original_container(&txout.script_pubkey)?; + Ok(txout) + } +} + +impl EmbedCommitVerify for TxOut { + type Proof = OpretProof; + type CommitError = OpretError; + + fn embed_commit(&mut self, msg: &Commitment) -> Result { + self.script_pubkey.embed_commit(msg) + } +} diff --git a/dbc/src/tapret/mod.rs b/dbc/src/tapret/mod.rs index 0453ff99..a2e57b35 100644 --- a/dbc/src/tapret/mod.rs +++ b/dbc/src/tapret/mod.rs @@ -67,22 +67,21 @@ mod txout; mod spk; mod xonlypk; -pub use tapscript::{TapretCommitment, TAPRET_SCRIPT_COMMITMENT_PREFIX}; -pub use tx::TapretError; -pub use xonlypk::TapretKeyError; - -/// Marker non-instantiable enum defining LNPBP-12 taproot OP_RETURN (`tapret`) -/// protocol. -pub enum Lnpbp12 {} - use bc::{InternalPk, IntoTapHash, LeafScript, ScriptPubkey, TapBranchHash, TapNodeHash, Tx}; use commit_verify::mpc::Commitment; use commit_verify::{CommitmentProtocol, ConvolveCommitProof, ConvolveVerifyError}; use strict_encoding::{StrictDeserialize, StrictSerialize}; +pub use tapscript::{TapretCommitment, TAPRET_SCRIPT_COMMITMENT_PREFIX}; +pub use tx::TapretError; +pub use xonlypk::TapretKeyError; use crate::{Proof, LIB_NAME_BPCORE}; -impl CommitmentProtocol for Lnpbp12 {} +/// Marker non-instantiable enum defining LNPBP-12 taproot OP_RETURN (`tapret`) +/// protocol. +pub enum Tapret {} + +impl CommitmentProtocol for Tapret {} /// Errors in constructing tapret path proof [`TapretPathProof`]. #[derive(Clone, Eq, PartialEq, Hash, Debug, Display, Error)] diff --git a/dbc/src/tapret/spk.rs b/dbc/src/tapret/spk.rs index 668a5ec9..c18aa10e 100644 --- a/dbc/src/tapret/spk.rs +++ b/dbc/src/tapret/spk.rs @@ -22,9 +22,9 @@ use bc::ScriptPubkey; use commit_verify::{mpc, ConvolveCommit, ConvolveCommitProof}; -use super::{Lnpbp12, TapretKeyError, TapretProof}; +use super::{Tapret, TapretKeyError, TapretProof}; -impl ConvolveCommitProof for TapretProof { +impl ConvolveCommitProof for TapretProof { type Suppl = Self; fn restore_original(&self, _: &ScriptPubkey) -> ScriptPubkey { self.original_pubkey_script() } @@ -32,7 +32,7 @@ impl ConvolveCommitProof for TapretProof fn extract_supplement(&self) -> &Self::Suppl { self } } -impl ConvolveCommit for ScriptPubkey { +impl ConvolveCommit for ScriptPubkey { type Commitment = ScriptPubkey; type CommitError = TapretKeyError; diff --git a/dbc/src/tapret/tapscript.rs b/dbc/src/tapret/tapscript.rs index 00d68836..aa6ba3ba 100644 --- a/dbc/src/tapret/tapscript.rs +++ b/dbc/src/tapret/tapscript.rs @@ -28,7 +28,7 @@ use bc::{TapCode, TapScript}; use commit_verify::{mpc, CommitEncode, CommitVerify}; use strict_encoding::{DecodeError, DeserializeError, StrictDeserialize, StrictSerialize}; -use super::Lnpbp12; +use super::Tapret; use crate::LIB_NAME_BPCORE; /// Hardcoded tapret script prefix consisting of 29 `OP_RESERVED` pushes, @@ -99,7 +99,7 @@ impl TapretCommitment { pub fn with(mpc: mpc::Commitment, nonce: u8) -> Self { Self { mpc, nonce } } } -impl CommitVerify for TapScript { +impl CommitVerify for TapScript { /// Tapret script consists of 29 `OP_RESERVED` pushes, followed by /// `OP_RETURN`, `OP_PUSHBYTES_33` and serialized commitment data (MPC /// commitment + nonce as a single slice). diff --git a/dbc/src/tapret/tx.rs b/dbc/src/tapret/tx.rs index 07295e23..ac12d772 100644 --- a/dbc/src/tapret/tx.rs +++ b/dbc/src/tapret/tx.rs @@ -22,7 +22,7 @@ use bc::Tx; use commit_verify::{mpc, ConvolveCommit, ConvolveCommitProof}; -use super::{Lnpbp12, TapretKeyError, TapretProof}; +use super::{Tapret, TapretKeyError, TapretProof}; /// Errors during tapret commitment. #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] @@ -42,7 +42,7 @@ pub enum TapretError { NoTaprootOutput, } -impl ConvolveCommitProof for TapretProof { +impl ConvolveCommitProof for TapretProof { type Suppl = Self; fn restore_original(&self, commitment: &Tx) -> Tx { @@ -59,7 +59,7 @@ impl ConvolveCommitProof for TapretProof { fn extract_supplement(&self) -> &Self::Suppl { self } } -impl ConvolveCommit for Tx { +impl ConvolveCommit for Tx { type Commitment = Tx; type CommitError = TapretError; diff --git a/dbc/src/tapret/txout.rs b/dbc/src/tapret/txout.rs index 24fe7f7e..cdbc77e0 100644 --- a/dbc/src/tapret/txout.rs +++ b/dbc/src/tapret/txout.rs @@ -22,9 +22,9 @@ use bc::{ScriptPubkey, TxOut}; use commit_verify::{mpc, ConvolveCommit, ConvolveCommitProof}; -use super::{Lnpbp12, TapretKeyError, TapretProof}; +use super::{Tapret, TapretKeyError, TapretProof}; -impl ConvolveCommitProof for TapretProof { +impl ConvolveCommitProof for TapretProof { type Suppl = Self; fn restore_original(&self, commitment: &TxOut) -> TxOut { @@ -37,7 +37,7 @@ impl ConvolveCommitProof for TapretProof { fn extract_supplement(&self) -> &Self::Suppl { self } } -impl ConvolveCommit for TxOut { +impl ConvolveCommit for TxOut { type Commitment = TxOut; type CommitError = TapretKeyError; diff --git a/dbc/src/tapret/xonlypk.rs b/dbc/src/tapret/xonlypk.rs index cfcfd482..5e6792cf 100644 --- a/dbc/src/tapret/xonlypk.rs +++ b/dbc/src/tapret/xonlypk.rs @@ -22,7 +22,7 @@ use bc::{InternalPk, OutputPk, TapBranchHash, TapLeafHash, TapNodeHash, TapScript}; use commit_verify::{mpc, CommitVerify, ConvolveCommit, ConvolveCommitProof}; -use super::{Lnpbp12, TapretNodePartner, TapretPathProof, TapretProof}; +use super::{Tapret, TapretNodePartner, TapretPathProof, TapretProof}; use crate::tapret::tapscript::TapretCommitment; /// Errors during tapret commitment embedding into x-only public key. @@ -42,7 +42,7 @@ pub enum TapretKeyError { IncorrectOrdering(TapretNodePartner, TapLeafHash), } -impl ConvolveCommitProof for TapretProof { +impl ConvolveCommitProof for TapretProof { type Suppl = TapretPathProof; fn restore_original(&self, _: &OutputPk) -> InternalPk { self.internal_pk } @@ -50,7 +50,7 @@ impl ConvolveCommitProof for TapretProof { fn extract_supplement(&self) -> &Self::Suppl { &self.path_proof } } -impl ConvolveCommit for InternalPk { +impl ConvolveCommit for InternalPk { type Commitment = OutputPk; type CommitError = TapretKeyError; @@ -125,7 +125,7 @@ mod test { internal_pk }); - ConvolveCommitProof::::verify(&proof, &msg, &outer_key) + ConvolveCommitProof::::verify(&proof, &msg, &outer_key) .unwrap(); } @@ -149,7 +149,7 @@ mod test { internal_pk }); - ConvolveCommitProof::::verify(&proof, &msg, &outer_key) + ConvolveCommitProof::::verify(&proof, &msg, &outer_key) .unwrap(); } @@ -174,7 +174,7 @@ mod test { internal_pk }); - ConvolveCommitProof::::verify(&proof, &msg, &outer_key) + ConvolveCommitProof::::verify(&proof, &msg, &outer_key) .unwrap(); } } diff --git a/seals/src/txout/blind.rs b/seals/src/txout/blind.rs index 4dbdcb7c..0aa4db3a 100644 --- a/seals/src/txout/blind.rs +++ b/seals/src/txout/blind.rs @@ -29,7 +29,7 @@ use amplify::{hex, Bytes32, Wrapper}; use baid58::{Baid58ParseError, Chunking, FromBaid58, ToBaid58, CHUNKING_32CHECKSUM}; use bc::{Outpoint, Txid, Vout}; use commit_verify::{CommitVerify, Conceal}; -use dbc::tapret::Lnpbp12; +use dbc::tapret::Tapret; use rand::{thread_rng, RngCore}; use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; @@ -389,7 +389,7 @@ impl From for SecretSeal { fn from(outpoint: Outpoint) -> Self { BlindSeal::::from(outpoint).conceal() } } -impl CommitVerify, Lnpbp12> for SecretSeal { +impl CommitVerify, Tapret> for SecretSeal { fn commit(reveal: &BlindSeal) -> Self { Bytes32::commit(reveal).into() } } diff --git a/src/stl.rs b/src/stl.rs index fb3dad9f..f7b6144d 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -32,7 +32,7 @@ use strict_types::{CompileError, LibBuilder, TypeLib}; /// Strict types id for the library providing data types from [`dbc`] and /// [`seals`] crates. pub const LIB_ID_BPCORE: &str = - "urn:ubideco:stl:5UnRmQChaU5Czu3AQHxDHPzW9JKARBWoMcVYamwoCLPP#siren-stone-soda"; + "urn:ubideco:stl:2LXdci4De5v59LqENhJkhcVi8RiHX5rq6nTwxRnFwgir#lucky-proxy-orchid"; fn _bp_core_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_BPCORE), tiny_bset! { diff --git a/stl/BPCore@0.1.0.sta b/stl/BPCore@0.1.0.sta index 7a454656..a5aff5c2 100644 --- a/stl/BPCore@0.1.0.sta +++ b/stl/BPCore@0.1.0.sta @@ -1,5 +1,5 @@ -----BEGIN STRICT TYPE LIB----- -Id: urn:ubideco:stl:5UnRmQChaU5Czu3AQHxDHPzW9JKARBWoMcVYamwoCLPP +Id: urn:ubideco:stl:2LXdci4De5v59LqENhJkhcVi8RiHX5rq6nTwxRnFwgir Name: BPCore Dependencies: urn:ubideco:stl:ZtHaBzu9ojbDahaGKEXe5v9DfSDxLERbLkEB23R6Q6V, @@ -59,30 +59,30 @@ KCXsG4EroYfdnZhJi0qNFvpu1UMEdHhpZAL1bBNiI/Y5p0oJk9xHRsn5iqu4g1hd tdkWPxh+xCgaCqOCQvPL19HQoRLajeFgL1bU+G8OxMR2xcBoWUxLBGVWBHZvdXQC 9WwTYiP2OadKCZPcR0bJ+YqruINYXbXZFj8YfsQoGgoh4z5Dxapc8iknU6M4wWft O2OcTdnOvamPNGkXuslDdQhibGluZGluZwAACAtDbG9zZU1ldGhvZAMCCm9wcmV0 -Rmlyc3QAC3RhcHJldEZpcnN0AQxFeHBsaWNpdFNlYWwGAwZtZXRob2QB0lIwfH1x -kDX3MH7oKCXsG4EroYfdnZhJi0qNFvpu1UMEdHhpZAL1bBNiI/Y5p0oJk9xHRsn5 -iqu4g1hdtdkWPxh+xCgaCqOCQvPL19HQoRLajeFgL1bU+G8OxMR2xcBoWUxLBGVW -BHZvdXQC9WwTYiP2OadKCZPcR0bJ+YqruINYXbXZFj8YfsQoGgoh4z5Dxapc8ikn -U6M4wWftO2OcTdnOvamPNGkXuslDdRFFeHBsaWNpdFNlYWxUeFB0cgYDBm1ldGhv -ZAHSUjB8fXGQNfcwfugoJewbgSuhh92dmEmLSo0W+m7VQwR0eGlkAbHlODkUCji+ -8G8az74cYKVv4eH0fXgIKHm/0frTECHdBHZvdXQC9WwTYiP2OadKCZPcR0bJ+Yqr -uINYXbXZFj8YfsQoGgoh4z5Dxapc8iknU6M4wWftO2OcTdnOvamPNGkXuslDdQpP -cHJldFByb29mBQEAAAAKU2VjcmV0U2VhbAUBAAcAAEAgABFUYXByZXROb2RlUGFy -dG5lcgQDAAhsZWZ0Tm9kZQAFAQL1bBNiI/Y5p0oJk9xHRsn5iqu4g1hdtdkWPxh+ -xCgaCjG7ruiEiXfFsAcxcjHNkvYwtiktzYl/3LrexbrE6X/ZAQlyaWdodExlYWYA -BQEC9WwTYiP2OadKCZPcR0bJ+YqruINYXbXZFj8YfsQoGgpfrNlt5T9OxRTZsY1n -gNoKq+stJgv9Ny2jwHqkXTmfTQILcmlnaHRCcmFuY2gABQEBOD9iLnFT0sghkTzL -dx2fPWTfdvIoVVkt+EZDlBZNbQUPVGFwcmV0UGF0aFByb29mBgILcGFydG5lck5v -ZGUABAIABG5vbmUAAAABBHNvbWUABQEBAXwHXQBASxaVmBsXw2Etxrjqrg1/cFli -khZ1WuUZkxEFbm9uY2UAAAELVGFwcmV0UHJvb2YGAglwYXRoUHJvb2YBE8RTUmYn -u0QljDtn9MzCfv785Ce3z14P/YGPL3572HwKaW50ZXJuYWxQawL1bBNiI/Y5p0oJ -k9xHRsn5iqu4g1hdtdkWPxh+xCgaCqmFhHdTnmj7sL/ux5ohxFdDwVT4+r0/mODT -kT3ntzd4EVRhcHJldFJpZ2h0QnJhbmNoBgIMbGVmdE5vZGVIYXNoAvVsE2Ij9jmn -SgmT3EdGyfmKq7iDWF212RY/GH7EKBoKMbuu6ISJd8WwBzFyMc2S9jC2KS3NiX/c -ut7FusTpf9kNcmlnaHROb2RlSGFzaAL1bBNiI/Y5p0oJk9xHRsn5iqu4g1hdtdkW -Pxh+xCgaCjG7ruiEiXfFsAcxcjHNkvYwtiktzYl/3LrexbrE6X/ZBVR4UHRyBAIA -CXdpdG5lc3NUeAAAAAEEdHhpZAAFAQL1bBNiI/Y5p0oJk9xHRsn5iqu4g1hdtdkW -Pxh+xCgaCqOCQvPL19HQoRLajeFgL1bU+G8OxMR2xcBoWUxLBGVW +Rmlyc3QAC3RhcHJldEZpcnN0ARFFeHBsaWNpdFNlYWxUeFB0cgYDBm1ldGhvZAHS +UjB8fXGQNfcwfugoJewbgSuhh92dmEmLSo0W+m7VQwR0eGlkAbHlODkUCji+8G8a +z74cYKVv4eH0fXgIKHm/0frTECHdBHZvdXQC9WwTYiP2OadKCZPcR0bJ+YqruINY +XbXZFj8YfsQoGgoh4z5Dxapc8iknU6M4wWftO2OcTdnOvamPNGkXuslDdRBFeHBs +aWNpdFNlYWxUeGlkBgMGbWV0aG9kAdJSMHx9cZA19zB+6Cgl7BuBK6GH3Z2YSYtK +jRb6btVDBHR4aWQC9WwTYiP2OadKCZPcR0bJ+YqruINYXbXZFj8YfsQoGgqjgkLz +y9fR0KES2o3hYC9W1PhvDsTEdsXAaFlMSwRlVgR2b3V0AvVsE2Ij9jmnSgmT3EdG +yfmKq7iDWF212RY/GH7EKBoKIeM+Q8WqXPIpJ1OjOMFn7TtjnE3Zzr2pjzRpF7rJ +Q3UKT3ByZXRQcm9vZgUBAAAAClNlY3JldFNlYWwFAQAHAABAIAARVGFwcmV0Tm9k +ZVBhcnRuZXIEAwAIbGVmdE5vZGUABQEC9WwTYiP2OadKCZPcR0bJ+YqruINYXbXZ +Fj8YfsQoGgoxu67ohIl3xbAHMXIxzZL2MLYpLc2Jf9y63sW6xOl/2QEJcmlnaHRM +ZWFmAAUBAvVsE2Ij9jmnSgmT3EdGyfmKq7iDWF212RY/GH7EKBoKX6zZbeU/TsUU +2bGNZ4DaCqvrLSYL/Tcto8B6pF05n00CC3JpZ2h0QnJhbmNoAAUBATg/Yi5xU9LI +IZE8y3cdnz1k33byKFVZLfhGQ5QWTW0FD1RhcHJldFBhdGhQcm9vZgYCC3BhcnRu +ZXJOb2RlAAQCAARub25lAAAAAQRzb21lAAUBAQF8B10AQEsWlZgbF8NhLca46q4N +f3BZYpIWdVrlGZMRBW5vbmNlAAABC1RhcHJldFByb29mBgIJcGF0aFByb29mARPE +U1JmJ7tEJYw7Z/TMwn7+/OQnt89eD/2Bjy9+e9h8CmludGVybmFsUGsC9WwTYiP2 +OadKCZPcR0bJ+YqruINYXbXZFj8YfsQoGgqphYR3U55o+7C/7seaIcRXQ8FU+Pq9 +P5jg05E957c3eBFUYXByZXRSaWdodEJyYW5jaAYCDGxlZnROb2RlSGFzaAL1bBNi +I/Y5p0oJk9xHRsn5iqu4g1hdtdkWPxh+xCgaCjG7ruiEiXfFsAcxcjHNkvYwtikt +zYl/3LrexbrE6X/ZDXJpZ2h0Tm9kZUhhc2gC9WwTYiP2OadKCZPcR0bJ+YqruINY +XbXZFj8YfsQoGgoxu67ohIl3xbAHMXIxzZL2MLYpLc2Jf9y63sW6xOl/2QVUeFB0 +cgQCAAl3aXRuZXNzVHgAAAABBHR4aWQABQEC9WwTYiP2OadKCZPcR0bJ+YqruINY +XbXZFj8YfsQoGgqjgkLzy9fR0KES2o3hYC9W1PhvDsTEdsXAaFlMSwRlVg== -----END STRICT TYPE LIB----- diff --git a/stl/BPCore@0.1.0.stl b/stl/BPCore@0.1.0.stl index b467fab544429bfbda11f4ed157be2ae3da5f892..027413a57f7e0f8876285502681be94da865b4ad 100644 GIT binary patch delta 38 ucmaDZ^IB#DGuPx}Tq^_xTq_E4GLth)f>RT7LMk#-CJS(F+nmS!lL-JNHxAwa delta 34 qcmaDY^IT>FGZ!z9Yehj$W^!gpaB5=C