From 7023e378bbbd68a0576fe89d1fe478ddaf584230 Mon Sep 17 00:00:00 2001 From: Piotr Macek <4007944+piotrm50@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:46:59 +0200 Subject: [PATCH 1/3] Add .idea/ to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 96ef6c0..408b8a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target Cargo.lock +.idea \ No newline at end of file From f980d5b7d6875b683f52082104070e6492178b6c Mon Sep 17 00:00:00 2001 From: Piotr Macek <4007944+piotrm50@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:47:12 +0200 Subject: [PATCH 2/3] Remove legacy MultiSig --- .../src/types/crypto/multisig.rs | 240 +----------------- 1 file changed, 8 insertions(+), 232 deletions(-) diff --git a/crates/iota-rust-sdk/src/types/crypto/multisig.rs b/crates/iota-rust-sdk/src/types/crypto/multisig.rs index 90086a9..d99be4c 100644 --- a/crates/iota-rust-sdk/src/types/crypto/multisig.rs +++ b/crates/iota-rust-sdk/src/types/crypto/multisig.rs @@ -8,8 +8,6 @@ pub type WeightUnit = u8; pub type ThresholdUnit = u16; pub type BitmapUnit = u16; -#[cfg(feature = "serde")] -const MAX_COMMITTEE_SIZE: usize = 10; // TODO validate sigs // const MAX_BITMAP_VALUE: BitmapUnit = 0b1111111111; @@ -86,17 +84,6 @@ pub struct MultisigAggregatedSignature { /// A bitmap that indicates the position of which public key the signature /// should be authenticated with. bitmap: BitmapUnit, - /// Legacy encoding for the bitmap. - // TODO implement a strategy for legacy bitmap - #[cfg_attr( - feature = "schemars", - schemars( - skip_serializing_if = "Option::is_none", - with = "Option", - ) - )] - #[cfg_attr(test, strategy(proptest::strategy::Just(None)))] - legacy_bitmap: Option, /// The public key encoded with each public key with its signature scheme /// used along with the corresponding weight. committee: MultisigCommittee, @@ -111,10 +98,6 @@ impl MultisigAggregatedSignature { self.bitmap } - pub fn legacy_bitmap(&self) -> Option<&roaring::RoaringBitmap> { - self.legacy_bitmap.as_ref() - } - pub fn committee(&self) -> &MultisigCommittee { &self.committee } @@ -122,8 +105,6 @@ impl MultisigAggregatedSignature { impl PartialEq for MultisigAggregatedSignature { fn eq(&self, other: &Self) -> bool { - // Skip comparing the legacy bitmap since we always convert to the new bitmap - // form self.bitmap == other.bitmap && self.signatures == other.signatures && self.committee == other.committee @@ -132,19 +113,6 @@ impl PartialEq for MultisigAggregatedSignature { impl Eq for MultisigAggregatedSignature {} -/// Convert a roaring bitmap to plain bitmap. -#[cfg(feature = "serde")] -fn roaring_bitmap_to_u16(roaring: &roaring::RoaringBitmap) -> Result { - let mut val = 0; - for i in roaring.iter() { - if i >= MAX_COMMITTEE_SIZE as u32 { - return Err("invalid bitmap"); - } - val |= 1 << i as u8; - } - Ok(val) -} - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(test, derive(test_strategy::Arbitrary))] #[allow(clippy::large_enum_variant)] @@ -160,135 +128,11 @@ pub enum MultisigMemberSignature { mod serialization { use std::borrow::Cow; - use base64ct::{Base64, Encoding}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; - use serde_with::{Bytes, DeserializeAs, SerializeAs}; + use serde_with::{Bytes, DeserializeAs}; use super::*; - use crate::types::{ - Ed25519PublicKey, Secp256k1PublicKey, Secp256r1PublicKey, SignatureScheme, - crypto::{Base64Array33, Base64Array34}, - }; - - pub struct Base64MultisigMemberPublicKey; - - impl SerializeAs for Base64MultisigMemberPublicKey { - fn serialize_as( - source: &MultisigMemberPublicKey, - serializer: S, - ) -> Result - where - S: Serializer, - { - match source { - MultisigMemberPublicKey::Ed25519(public_key) => { - let mut buf = [0; 1 + Ed25519PublicKey::LENGTH]; - buf[0] = SignatureScheme::Ed25519 as u8; - buf[1..].copy_from_slice(public_key.as_ref()); - Base64Array33::serialize_as(&buf, serializer) - } - MultisigMemberPublicKey::Secp256k1(public_key) => { - let mut buf = [0; 1 + Secp256k1PublicKey::LENGTH]; - buf[0] = SignatureScheme::Secp256k1 as u8; - buf[1..].copy_from_slice(public_key.as_ref()); - Base64Array34::serialize_as(&buf, serializer) - } - MultisigMemberPublicKey::Secp256r1(public_key) => { - let mut buf = [0; 1 + Secp256r1PublicKey::LENGTH]; - buf[0] = SignatureScheme::Secp256r1 as u8; - buf[1..].copy_from_slice(public_key.as_ref()); - Base64Array34::serialize_as(&buf, serializer) - } - MultisigMemberPublicKey::ZkLogin(_) => Err(serde::ser::Error::custom( - "zklogin not supported in legacy multisig", - )), - } - } - } - - impl<'de> DeserializeAs<'de, MultisigMemberPublicKey> for Base64MultisigMemberPublicKey { - fn deserialize_as(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let b64: Cow<'de, str> = Deserialize::deserialize(deserializer)?; - let bytes = Base64::decode_vec(&b64).map_err(serde::de::Error::custom)?; - let flag = SignatureScheme::from_byte( - *bytes - .first() - .ok_or_else(|| serde::de::Error::custom("missing signature scheme flag"))?, - ) - .map_err(serde::de::Error::custom)?; - let public_key_bytes = &bytes[1..]; - match flag { - SignatureScheme::Ed25519 => { - let public_key = Ed25519PublicKey::from_bytes(public_key_bytes) - .map_err(serde::de::Error::custom)?; - Ok(MultisigMemberPublicKey::Ed25519(public_key)) - } - SignatureScheme::Secp256k1 => { - let public_key = Secp256k1PublicKey::from_bytes(public_key_bytes) - .map_err(serde::de::Error::custom)?; - Ok(MultisigMemberPublicKey::Secp256k1(public_key)) - } - SignatureScheme::Secp256r1 => { - let public_key = Secp256r1PublicKey::from_bytes(public_key_bytes) - .map_err(serde::de::Error::custom)?; - Ok(MultisigMemberPublicKey::Secp256r1(public_key)) - } - SignatureScheme::Multisig - | SignatureScheme::Bls12381 - | SignatureScheme::ZkLogin - | SignatureScheme::Passkey => { - Err(serde::de::Error::custom("invalid public key type")) - } - } - } - } - - pub struct LegacyMultisigMember; - - impl SerializeAs for LegacyMultisigMember { - fn serialize_as(source: &MultisigMember, serializer: S) -> Result - where - S: Serializer, - { - #[derive(serde_derive::Serialize)] - struct LegacyMember<'a> { - #[serde(with = "::serde_with::As::")] - public_key: &'a MultisigMemberPublicKey, - weight: WeightUnit, - } - - let legacy = LegacyMember { - public_key: &source.public_key, - weight: source.weight, - }; - - legacy.serialize(serializer) - } - } - - impl<'de> DeserializeAs<'de, MultisigMember> for LegacyMultisigMember { - fn deserialize_as(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(serde_derive::Deserialize)] - struct LegacyMember { - #[serde(with = "::serde_with::As::")] - public_key: MultisigMemberPublicKey, - weight: WeightUnit, - } - - let legacy = LegacyMember::deserialize(deserializer)?; - - Ok(MultisigMember { - public_key: legacy.public_key, - weight: legacy.weight, - }) - } - } + use crate::types::{Ed25519PublicKey, Secp256k1PublicKey, Secp256r1PublicKey, SignatureScheme}; #[derive(serde_derive::Deserialize)] pub struct Multisig { @@ -304,43 +148,10 @@ mod serialization { committee: &'a MultisigCommittee, } - #[derive(serde_derive::Deserialize)] - pub struct LegacyMultisig { - signatures: Vec, - #[serde(with = "::serde_with::As::")] - bitmap: roaring::RoaringBitmap, - committee: LegacyMultisigCommittee, - } - - #[derive(serde_derive::Serialize)] - pub struct LegacyMultisigRef<'a> { - signatures: &'a [MultisigMemberSignature], - #[serde(with = "::serde_with::As::")] - bitmap: &'a roaring::RoaringBitmap, - committee: LegacyMultisigCommitteeRef<'a>, - } - - #[derive(serde_derive::Deserialize)] - struct LegacyMultisigCommittee { - #[serde(with = "::serde_with::As::>")] - members: Vec, - threshold: ThresholdUnit, - } - - #[derive(serde_derive::Serialize)] - struct LegacyMultisigCommitteeRef<'a> { - #[serde(with = "::serde_with::As::<&[LegacyMultisigMember]>")] - members: &'a [MultisigMember], - threshold: ThresholdUnit, - } - #[derive(serde_derive::Deserialize)] struct ReadableMultisigAggregatedSignature { signatures: Vec, bitmap: BitmapUnit, - #[serde(default)] - #[serde(with = "::serde_with::As::>")] - legacy_bitmap: Option, committee: MultisigCommittee, } @@ -348,9 +159,6 @@ mod serialization { struct ReadableMultisigAggregatedSignatureRef<'a> { signatures: &'a [MultisigMemberSignature], bitmap: BitmapUnit, - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(with = "::serde_with::As::>")] - legacy_bitmap: &'a Option, committee: &'a MultisigCommittee, } @@ -363,7 +171,6 @@ mod serialization { let readable = ReadableMultisigAggregatedSignatureRef { signatures: &self.signatures, bitmap: self.bitmap, - legacy_bitmap: &self.legacy_bitmap, committee: &self.committee, }; readable.serialize(serializer) @@ -371,25 +178,12 @@ mod serialization { let mut buf = Vec::new(); buf.push(SignatureScheme::Multisig as u8); - if let Some(bitmap) = &self.legacy_bitmap { - let legacy = LegacyMultisigRef { - signatures: &self.signatures, - bitmap, - committee: LegacyMultisigCommitteeRef { - members: &self.committee.members, - threshold: self.committee.threshold, - }, - }; - - bcs::serialize_into(&mut buf, &legacy).expect("serialization cannot fail"); - } else { - let multisig = MultisigRef { - signatures: &self.signatures, - bitmap: self.bitmap, - committee: &self.committee, - }; - bcs::serialize_into(&mut buf, &multisig).expect("serialization cannot fail"); - } + let multisig = MultisigRef { + signatures: &self.signatures, + bitmap: self.bitmap, + committee: &self.committee, + }; + bcs::serialize_into(&mut buf, &multisig).expect("serialization cannot fail"); serializer.serialize_bytes(&buf) } } @@ -405,7 +199,6 @@ mod serialization { Ok(Self { signatures: readable.signatures, bitmap: readable.bitmap, - legacy_bitmap: readable.legacy_bitmap, committee: readable.committee, }) } else { @@ -431,29 +224,12 @@ mod serialization { } let bcs_bytes = &bytes[1..]; - // Unfortunately we have no information in the serialized form of a Multisig to - // be able to determine if its a Legacy format or the new standard - // format so we just need to try each. - // - // We'll start with the newer format as that should be more prevalent. if let Ok(multisig) = bcs::from_bytes::(bcs_bytes) { Ok(Self { signatures: multisig.signatures, bitmap: multisig.bitmap, - legacy_bitmap: None, committee: multisig.committee, }) - } else if let Ok(legacy) = bcs::from_bytes::(bcs_bytes) { - Ok(Self { - signatures: legacy.signatures, - bitmap: roaring_bitmap_to_u16(&legacy.bitmap) - .map_err(serde::de::Error::custom)?, - legacy_bitmap: Some(legacy.bitmap), - committee: MultisigCommittee { - members: legacy.committee.members, - threshold: legacy.committee.threshold, - }, - }) } else { Err(serde::de::Error::custom("invalid multisig")) } From d98a71347592b39a77fc524fde53f64638f3143d Mon Sep 17 00:00:00 2001 From: Piotr Macek <4007944+piotrm50@users.noreply.github.com> Date: Tue, 22 Oct 2024 07:50:43 +0200 Subject: [PATCH 3/3] Remove test of legacy fixture --- .../src/types/crypto/signature.rs | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/crates/iota-rust-sdk/src/types/crypto/signature.rs b/crates/iota-rust-sdk/src/types/crypto/signature.rs index a2b3b45..dced092 100644 --- a/crates/iota-rust-sdk/src/types/crypto/signature.rs +++ b/crates/iota-rust-sdk/src/types/crypto/signature.rs @@ -580,26 +580,6 @@ mod serialization { } } - #[test] - fn legacy_multisig_fixtures() { - const FIXTURE1: &str = "rgIDAgAnwUSyrALP8m0eEPZE6aPggBELk72n1u3LU+i4nx5kqzhahcICbskEYzHJrbarvFr/RQITgDMoorqpDhN8dgsKATyrN3CD8g37D60dYiGW6sOBqIcf3E1mdMsKvX2pbOZsYQv8VNL+2Jz3vnMXcwEZF32PplKjcnmyUGRhV11M7n4UOjAAAAEAAAAAAAEAEAAAAAAAAQADLEFBMTlxeldNamEycVR2b0FTYWRiQjBObFZiRUtOb0ladTJnUGNGY1RTZGQxATBBUUlPRjgxWk9lUnJHV1pCbG96WFdaRUxvbGQrSi9wei9lT0hiYm0reGJ6ckt3PT0BMEFnTkgrNjhqOERpcnhNTUlvbkVSZWlwTS82N2R2Ri80SEhVWHZHeDBwKzIwTUE9PQECAA=="; - - const FIXTURE2: &str = "8QIDAwDYAAra4KQGp2Oq1TCOgWfH8IxC4UA5wJB/NqOcNmMh54Y5d5pnVQfTlqgq4J17a8+W+y3+jk9h4YMB9LzPDYcLAaJJBH+WLPfPaQ7T3Cv8nqpZ1TbPrT8E61FrSgeIbN4OTJeijjguv1pd3ImvTeo4AMYZczf5OH6+5yBaur7R6YACiooT5J36agjUk0TpVcTKMGwykIwD7NBkZ0gbinHxuVJwdi1tSbqhMpqvNgP+CFO6F7FSTe+xiHh0MDOKyYQItxY6MAAAAQAAAAAAAgAQAAAAAAABAAIAAyxBQTE5cXpXTWphMnFUdm9BU2FkYkIwTmxWYkVLTm9JWnUyZ1BjRmNUU2RkMQEwQVFJT0Y4MVpPZVJyR1daQmxvelhXWkVMb2xkK0ovcHovZU9IYmJtK3hienJLdz09ATBBZ05IKzY4ajhEaXJ4TU1Jb25FUmVpcE0vNjdkdkYvNEhIVVh2R3gwcCsyME1BPT0BAgA="; - - for fixture in [FIXTURE1, FIXTURE2] { - let bcs = Base64::decode_vec(fixture).unwrap(); - - let sig: UserSignature = bcs::from_bytes(&bcs).unwrap(); - assert_eq!(SignatureScheme::Multisig, sig.scheme()); - let bytes = bcs::to_bytes(&sig).unwrap(); - assert_eq!(bcs, bytes); - - let json = serde_json::to_string_pretty(&sig).unwrap(); - println!("{json}"); - assert_eq!(sig, serde_json::from_str(&json).unwrap()); - } - } - #[test] fn multisig_fixtures() { const FIXTURE1: &str = "sgIDAwCTLgVngjC4yeuvpAGKVkgcvIKVFUJnL1r6oFZScQVE5DNIz6kfxAGDRcVUczE9CUb7/sN/EuFJ8ot86Sdb8pAFASoQ91stRHXdW5dLy0BQ6v+7XWptawy2ItMyPk508p+PHdtZcm2aKl3lZGIvXe6MPY73E+1Hakv/xJbTYsw5SPMC5dx3gBwxds2GV12c7VUSqkyXamliSF1W/QBMufqrlmdIOZ1ox9gbsvIPtXYahfvKm8ozA7rsZWwRv8atsnyfYgcAAwANfas1jI2tqk76AEmnWwdDZVWxCjaCGbtoD3BXE0nXdQEBAg4XzVk55GsZZkGWjNdZkQuiV34n+nP944dtub7FvOsrAQIDR/uvI/A4q8TDCKJxEXoqTP+u3bxf+Bx1F7xsdKfttDABAgA=";