Skip to content

Commit

Permalink
crypto: introduce zklogin verifier support
Browse files Browse the repository at this point in the history
  • Loading branch information
bmwill committed Sep 25, 2024
1 parent 646aee1 commit cc2c6bc
Show file tree
Hide file tree
Showing 16 changed files with 14,610 additions and 74 deletions.
30 changes: 29 additions & 1 deletion crates/sui-sdk-crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ default = []
ed25519 = ["dep:ed25519-dalek", "dep:rand_core", "sui-sdk/hash", "sui-sdk/serde"]
secp256r1 = ["dep:p256", "dep:rand_core", "sui-sdk/hash", "sui-sdk/serde"]
secp256k1 = ["dep:k256", "dep:rand_core", "signature/std", "sui-sdk/hash", "sui-sdk/serde"]
zklogin = [
"dep:ark-bn254",
"dep:ark-ff",
"dep:ark-groth16",
"dep:ark-snark",
"dep:ark-std",
"dep:base64ct",
"dep:bnum",
"dep:itertools",
"dep:serde",
"dep:serde_derive",
"dep:serde_json",
"signature/std",
"sui-sdk/hash",
"sui-sdk/serde",
]

[dependencies]
signature = "2.2"
Expand All @@ -41,8 +57,20 @@ p256 = { version = "0.13.2", default-features = false, features = ["ecdsa", "std
# secp256k1 support
k256 = { version = "0.13.4", default-features = false, features = ["ecdsa"], optional = true }

# zklogin verification support
ark-bn254 = { version = "0.4.0", optional = true }
ark-ff = { version = "0.4.1", features = ["asm"], optional = true }
ark-groth16 = { version = "0.4.0", default-features = false, optional = true }
ark-snark = { version = "0.4.0", optional = true }
ark-std = { version = "0.4.0", optional = true }
base64ct = { version = "1.6.0", features = ["alloc"], optional = true }
bnum = { version = "0.11.0", optional = true }
itertools = { version = "0.10.5", optional = true }
serde = { version = "1.0.190", optional = true }
serde_derive = { version = "1.0.190", optional = true }
serde_json = { version = "1.0.114", optional = true }

[dev-dependencies]
base64ct = { version = "1.6.0", features = ["alloc"] }
bcs = { version = "0.1.6" }
hex = "0.4.3"
serde_json = { version = "1.0.114" }
Expand Down
2 changes: 1 addition & 1 deletion crates/sui-sdk-crypto/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ test:

.PHONY: wasm
wasm:
CC=clang wasm-pack test --node --all-features
CC=clang wasm-pack test -r --node --all-features

%:
$(MAKE) -C ../.. $@
51 changes: 38 additions & 13 deletions crates/sui-sdk-crypto/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,23 @@ impl Signer<Ed25519Signature> for Ed25519PrivateKey {
}
}

impl Signer<UserSignature> for Ed25519PrivateKey {
fn try_sign(&self, msg: &[u8]) -> Result<UserSignature, SignatureError> {
impl Signer<SimpleSignature> for Ed25519PrivateKey {
fn try_sign(&self, msg: &[u8]) -> Result<SimpleSignature, SignatureError> {
<Self as Signer<Ed25519Signature>>::try_sign(self, msg).map(|signature| {
let signature = SimpleSignature::Ed25519 {
SimpleSignature::Ed25519 {
signature,
public_key: self.public_key(),
};
UserSignature::Simple(signature)
}
})
}
}

impl Signer<UserSignature> for Ed25519PrivateKey {
fn try_sign(&self, msg: &[u8]) -> Result<UserSignature, SignatureError> {
<Self as Signer<SimpleSignature>>::try_sign(self, msg).map(UserSignature::Simple)
}
}

impl SuiSigner for Ed25519PrivateKey {
fn sign_transaction(&self, transaction: &Transaction) -> Result<UserSignature, SignatureError> {
let msg = transaction.signing_digest();
Expand Down Expand Up @@ -114,12 +119,12 @@ impl Verifier<Ed25519Signature> for Ed25519VerifyingKey {
}
}

impl Verifier<UserSignature> for Ed25519VerifyingKey {
fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
let UserSignature::Simple(SimpleSignature::Ed25519 {
impl Verifier<SimpleSignature> for Ed25519VerifyingKey {
fn verify(&self, message: &[u8], signature: &SimpleSignature) -> Result<(), SignatureError> {
let SimpleSignature::Ed25519 {
signature,
public_key,
}) = signature
} = signature
else {
return Err(SignatureError::from_source("not an ed25519 signature"));
};
Expand All @@ -134,6 +139,16 @@ impl Verifier<UserSignature> for Ed25519VerifyingKey {
}
}

impl Verifier<UserSignature> for Ed25519VerifyingKey {
fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
let UserSignature::Simple(signature) = signature else {
return Err(SignatureError::from_source("not an ed25519 signature"));
};

<Self as Verifier<SimpleSignature>>::verify(self, message, signature)
}
}

impl SuiVerifier for Ed25519VerifyingKey {
fn verify_transaction(
&self,
Expand Down Expand Up @@ -163,12 +178,12 @@ impl Ed25519Verifier {
}
}

impl Verifier<UserSignature> for Ed25519Verifier {
fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
let UserSignature::Simple(SimpleSignature::Ed25519 {
impl Verifier<SimpleSignature> for Ed25519Verifier {
fn verify(&self, message: &[u8], signature: &SimpleSignature) -> Result<(), SignatureError> {
let SimpleSignature::Ed25519 {
signature,
public_key,
}) = signature
} = signature
else {
return Err(SignatureError::from_source("not an ed25519 signature"));
};
Expand All @@ -179,6 +194,16 @@ impl Verifier<UserSignature> for Ed25519Verifier {
}
}

impl Verifier<UserSignature> for Ed25519Verifier {
fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
let UserSignature::Simple(signature) = signature else {
return Err(SignatureError::from_source("not an ed25519 signature"));
};

<Self as Verifier<SimpleSignature>>::verify(self, message, signature)
}
}

impl SuiVerifier for Ed25519Verifier {
fn verify_transaction(
&self,
Expand Down
21 changes: 21 additions & 0 deletions crates/sui-sdk-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ pub mod secp256k1;
#[cfg_attr(doc_cfg, doc(cfg(feature = "secp256r1")))]
pub mod secp256r1;

#[cfg(feature = "zklogin")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "zklogin")))]
pub mod zklogin;

#[cfg(any(
feature = "ed25519",
feature = "secp256r1",
feature = "secp256k1",
feature = "zklogin"
))]
#[cfg_attr(
doc_cfg,
doc(cfg(any(
feature = "ed25519",
feature = "secp256r1",
feature = "secp256k1",
feature = "zklogin"
)))
)]
pub mod simple;

pub trait SuiSigner {
fn sign_transaction(&self, transaction: &Transaction) -> Result<UserSignature, SignatureError>;
fn sign_personal_message(
Expand Down
67 changes: 54 additions & 13 deletions crates/sui-sdk-crypto/src/secp256k1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,23 @@ impl Signer<Secp256k1Signature> for Secp256k1PrivateKey {
}
}

impl Signer<UserSignature> for Secp256k1PrivateKey {
fn try_sign(&self, msg: &[u8]) -> Result<UserSignature, SignatureError> {
impl Signer<SimpleSignature> for Secp256k1PrivateKey {
fn try_sign(&self, msg: &[u8]) -> Result<SimpleSignature, SignatureError> {
<Self as Signer<Secp256k1Signature>>::try_sign(self, msg).map(|signature| {
let signature = SimpleSignature::Secp256k1 {
SimpleSignature::Secp256k1 {
signature,
public_key: self.public_key(),
};
UserSignature::Simple(signature)
}
})
}
}

impl Signer<UserSignature> for Secp256k1PrivateKey {
fn try_sign(&self, msg: &[u8]) -> Result<UserSignature, SignatureError> {
<Self as Signer<SimpleSignature>>::try_sign(self, msg).map(UserSignature::Simple)
}
}

impl SuiSigner for Secp256k1PrivateKey {
fn sign_transaction(&self, transaction: &Transaction) -> Result<UserSignature, SignatureError> {
let msg = transaction.signing_digest();
Expand Down Expand Up @@ -116,12 +121,12 @@ impl Verifier<Secp256k1Signature> for Secp256k1VerifyingKey {
}
}

impl Verifier<UserSignature> for Secp256k1VerifyingKey {
fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
let UserSignature::Simple(SimpleSignature::Secp256k1 {
impl Verifier<SimpleSignature> for Secp256k1VerifyingKey {
fn verify(&self, message: &[u8], signature: &SimpleSignature) -> Result<(), SignatureError> {
let SimpleSignature::Secp256k1 {
signature,
public_key,
}) = signature
} = signature
else {
return Err(SignatureError::from_source("not a secp256k1 signature"));
};
Expand All @@ -136,6 +141,16 @@ impl Verifier<UserSignature> for Secp256k1VerifyingKey {
}
}

impl Verifier<UserSignature> for Secp256k1VerifyingKey {
fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
let UserSignature::Simple(signature) = signature else {
return Err(SignatureError::from_source("not a secp256k1 signature"));
};

<Self as Verifier<SimpleSignature>>::verify(self, message, signature)
}
}

impl SuiVerifier for Secp256k1VerifyingKey {
fn verify_transaction(
&self,
Expand Down Expand Up @@ -165,12 +180,12 @@ impl Secp256k1Verifier {
}
}

impl Verifier<UserSignature> for Secp256k1Verifier {
fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
let UserSignature::Simple(SimpleSignature::Secp256k1 {
impl Verifier<SimpleSignature> for Secp256k1Verifier {
fn verify(&self, message: &[u8], signature: &SimpleSignature) -> Result<(), SignatureError> {
let SimpleSignature::Secp256k1 {
signature,
public_key,
}) = signature
} = signature
else {
return Err(SignatureError::from_source("not a secp256k1 signature"));
};
Expand All @@ -181,6 +196,16 @@ impl Verifier<UserSignature> for Secp256k1Verifier {
}
}

impl Verifier<UserSignature> for Secp256k1Verifier {
fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
let UserSignature::Simple(signature) = signature else {
return Err(SignatureError::from_source("not a secp256k1 signature"));
};

<Self as Verifier<SimpleSignature>>::verify(self, message, signature)
}
}

impl SuiVerifier for Secp256k1Verifier {
fn verify_transaction(
&self,
Expand Down Expand Up @@ -233,4 +258,20 @@ mod test {
.verify_personal_message(&message, &signature)
.unwrap();
}

#[test]
fn personal_message_signing_fixture() {
let key = [
172, 12, 96, 180, 207, 143, 111, 151, 81, 57, 242, 89, 74, 5, 150, 51, 56, 111, 245,
150, 182, 30, 149, 178, 29, 255, 188, 27, 48, 241, 151, 193,
];

let signer = Secp256k1PrivateKey::new(key).unwrap();

let message = PersonalMessage(b"hello".into());
let sig = signer.sign_personal_message(&message).unwrap();
let external_sig = "AVFAWGjuD8+xUoc6jMC0lKqMtT+4ukln7vz+8Nuv+EbYKl47jwzOWn39maDsqu81kezLPgLzz6o/AfSE0M9+jVwClcrtiuyUggEt/6CEZi8+JQ+NS9TmOhPBZV2X1KjhGCw=";
let b64 = sig.to_base64();
assert_eq!(external_sig, b64);
}
}
Loading

0 comments on commit cc2c6bc

Please sign in to comment.