MCPcopy Create free account
hub / github.com/BitVM/BitVM / CompactWots

Interface CompactWots

bitvm/src/signatures/public.rs:219–321  ·  view source on GitHub ↗

High-level functionality for working with compact Winternitz signatures. Compact signatures contain the signature of each digit, but not the digit itself. ## See [`Wots`]

Source from the content-addressed store, hash-verified

217///
218/// [`Wots`]
219pub trait CompactWots: Wots {
220 type CompactSignature: AsRef<[[u8; 20]]> + TryFrom<Vec<[u8; 20]>, Error: std::fmt::Debug>;
221 const COMPACT_ALGORITHM: Winternitz<BruteforceVerifier, Self::Converter> = Winternitz::new();
222
223 /// Generates a compact signature for the given `secret_key` and `message`,
224 /// in form of a Bitcoin witness.
225 fn compact_sign_to_raw_witness(
226 secret_key: &WinternitzSecret,
227 message: &Self::Message,
228 ) -> bitcoin::Witness {
229 let witness = Self::COMPACT_ALGORITHM.sign(&Self::PARAMETERS, secret_key, message.as_ref());
230 debug_assert_eq!(witness.len(), Self::TOTAL_DIGIT_LEN as usize);
231 witness
232 }
233
234 /// Generates a compact signature for the given `secret_key` and `message`.
235 fn compact_sign(
236 secret_key: &WinternitzSecret,
237 message: &Self::Message,
238 ) -> Self::CompactSignature {
239 let witness = Self::compact_sign_to_raw_witness(secret_key, message);
240 Self::compact_raw_witness_to_signature(&witness)
241 }
242
243 /// Parses the given bitcoin `witness` as a Winternitz signature.
244 ///
245 /// The `witness` must be in the format that is returned by [`CompactWots::compact_sign`].
246 ///
247 /// ## Panics
248 ///
249 /// This method panics if the `witness` is ill-formatted.
250 fn compact_raw_witness_to_signature(witness: &bitcoin::Witness) -> Self::CompactSignature {
251 assert_eq!(witness.len(), Self::TOTAL_DIGIT_LEN as usize);
252 let mut digit_signatures: Vec<[u8; 20]> =
253 Vec::with_capacity(Self::TOTAL_DIGIT_LEN as usize);
254
255 for i in 0..witness.len() {
256 assert_eq!(
257 witness[i].len(),
258 20,
259 "the digit signature should be constant 20 bytes"
260 );
261
262 let digit_signature: [u8; 20] = witness[i].try_into().unwrap();
263 digit_signatures.push(digit_signature);
264 }
265
266 debug_assert_eq!(digit_signatures.len(), Self::TOTAL_DIGIT_LEN as usize);
267 match Self::CompactSignature::try_from(digit_signatures) {
268 Ok(signature) => signature,
269 _ => unreachable!(),
270 }
271 }
272
273 /// Encodes the given Winternitz `signature` as a bitcoin witness.
274 fn compact_signature_to_raw_witness(signature: &Self::CompactSignature) -> bitcoin::Witness {
275 let mut witness = bitcoin::Witness::new();
276

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected