-
Notifications
You must be signed in to change notification settings - Fork 11.3k
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
crypto: Add multisig to sui #7110
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 4 Ignored Deployments
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's have a design doc for this first as there are many functionality decisions (ie weighted multisig)
#7187 linked design doc in this issue |
00d8556
to
4ff57d7
Compare
4c14cbd
to
e8ca0e3
Compare
We should also consider supporting secp256r1 signature verification in the move library. |
|
67d4a17
to
8cbb4a2
Compare
crates/sui-types/src/base_types.rs
Outdated
@@ -258,6 +259,25 @@ impl From<&PublicKey> for SuiAddress { | |||
} | |||
} | |||
|
|||
/// A Multisig address is the first 20 bytes of `threshold || pk_1 || weight_1 || ... || pk_n || weight_n` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... is the first 20 bytes of the hash of flag || threshold || pk_1
....
crates/sui-types/src/crypto.rs
Outdated
// Unwrap below is safe because the bytes are directly read from the signature bytes from [enum Signature]. | ||
match self.scheme() { | ||
SignatureScheme::ED25519 => Ok(CompressedSignature::Ed25519( | ||
Ed25519Signature::from_bytes(bytes).unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are these unwrap always successful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah i added a line above at 697, bc here we always use the signature_bytes()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
edit: unwrap removed
|| pks.len() != weights.len() | ||
|| pks.len() > MAX_SIGNER_IN_MULTISIG | ||
{ | ||
return Err(SuiError::InvalidSignature { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we do these checks even when deserializing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point. added to from_bytes to validate the multisig itself and its pk
threshold: ThresholdUnit, | ||
) -> Result<Self, SuiError> { | ||
if pks.is_empty() | ||
|| weights.is_empty() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we should even disallow any zero weights, no multisig key should carry any weight = 0 pk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, added tests
crates/sui-types/src/multisig.rs
Outdated
|
||
/// The struct that contains the public key used for authenticating a multisig. | ||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] | ||
pub struct MultiPublicKey { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, and obviously very subjective - I view "MultiSig" as the scheme name, like ECDSA or EdDSA, and so MultiSigPublicKey sounds clearer to me here.
crates/sui-types/src/multisig.rs
Outdated
/// This way multisig (and future Authenticators) can implement its own `verify`. | ||
#[enum_dispatch(AuthenticatorTrait)] | ||
#[derive(Debug, Clone, PartialEq, Eq, JsonSchema, Hash)] | ||
pub enum GenericSignature { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, and also very subjective - maybe enum Signature { MultiSig, SingleSig }
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed on both naming. renaming Signature -> SingleSig is quite invasive, will do this in a later PR.
let mut weight_sum = 0; | ||
let message = bcs::to_bytes(&value).expect("Message serialization should not fail"); | ||
|
||
for (sig, i) in self.sigs.iter().zip(&self.bitmap) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it assume here that the sigs are sorted according to their public keys?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, we depend here on bitmap to check that we don't have 2 signatures for the same public key, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah sigs are assumed sorted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah roaring bitmap prevents inserting the same value twice.
however, it is technically possible if the multisig pubkey itself is constructed with two same pks (with different different index in bitmap ). i dont know if there is a good reason someone would do that but didnt check to fail for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah as the user controls their multisig pubKey, there is no good incentive to have a double pubKey. Maybe an edge case is if a user wanted to double their max weight for some peculiar auth structure, but it's fine to omit that check.
8036589
to
44c51ba
Compare
@kchalkias @benr-ml addressed most of the comments PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job Joy!
let mut weight_sum = 0; | ||
let message = bcs::to_bytes(&value).expect("Message serialization should not fail"); | ||
|
||
for (sig, i) in self.sigs.iter().zip(&self.bitmap) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah as the user controls their multisig pubKey, there is no good incentive to have a double pubKey. Maybe an edge case is if a user wanted to double their max weight for some peculiar auth structure, but it's fine to omit that check.
crates/sui-types/src/multisig.rs
Outdated
error: "Invalid address".to_string(), | ||
}); | ||
} | ||
let mut weight_sum = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd specifically add the type here (u16) just for readability. I understand we have weights being u8 atm and we aggregate them into a u16, but in any case I'd also add a test where all keys have max weight (just to capture any future update where for some reason we allow 256+ pubKeys)
Multisig support in Sui: Now sui accepts Multisig signatures. [enum GenericSignature] now replaced all [enum Signature] for user signature verification logics.
Keytool command now supports 1) Generate multisig address 2) Combine single signatures to a multisig.
Design: #7187
PR: #7110
Step by step testing in localnet: https://gist.github.com/joyqvq/5febd8deb5cacc6f47afa1253224b7da
Main changes are in
multisig.rs
,signature.rs
crypto.rs
Next step: