Skip to content

Commit

Permalink
crypto: Rederive pubkey for encode/decode
Browse files Browse the repository at this point in the history
  • Loading branch information
joyqvq committed Dec 22, 2022
1 parent 9b024c3 commit d656b08
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 41 deletions.
39 changes: 17 additions & 22 deletions crates/sui-types/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,61 +136,56 @@ impl FromStr for SuiKeyPair {
}

impl EncodeDecodeBase64 for SuiKeyPair {
/// Encode a SuiKeyPair as `flag || pubkey || privkey` in Base64. The pubkey bytesare derived directly from privkey.
fn encode_base64(&self) -> String {
let mut bytes: Vec<u8> = Vec::new();
match self {
SuiKeyPair::Ed25519(kp) => {
let kp1 = kp.copy();
bytes.extend_from_slice(&[self.public().flag()]);
bytes.extend_from_slice(kp.public().as_ref());
bytes.extend_from_slice(kp1.private().as_ref());
bytes.extend_from_slice(Ed25519PublicKey::from(&kp.copy().private()).as_ref());
bytes.extend_from_slice(kp.copy().private().as_ref());
}
SuiKeyPair::Secp256k1(kp) => {
let kp1 = kp.copy();
bytes.extend_from_slice(&[self.public().flag()]);
bytes.extend_from_slice(kp.public().as_ref());
bytes.extend_from_slice(kp1.private().as_ref());
bytes.extend_from_slice(Secp256k1PublicKey::from(&kp.copy().private()).as_ref());
bytes.extend_from_slice(kp.copy().private().as_ref());
}
SuiKeyPair::Secp256r1(kp) => {
let kp1 = kp.copy();
bytes.extend_from_slice(&[self.public().flag()]);
bytes.extend_from_slice(kp.public().as_ref());
bytes.extend_from_slice(kp1.private().as_ref());
bytes.extend_from_slice(Secp256r1PublicKey::from(&kp.copy().private()).as_ref());
bytes.extend_from_slice(kp.copy().private().as_ref());
}
}
println!("ccbytes={:?}", bytes);
Base64::encode(&bytes[..])
}

/// Decode a SuiKeyPair from Base64 encoded `flag || pubkey || privkey` in Base64. Use the privkey bytes only to derive the pubkey and the full keypair.
fn decode_base64(value: &str) -> Result<Self, eyre::Report> {
let bytes = Base64::decode(value).map_err(|e| eyre::eyre!("{}", e.to_string()))?;
match bytes.first() {
Some(x) => {
if x == &Ed25519SuiSignature::SCHEME.flag() {
let priv_key_bytes = bytes
.get(1 + Ed25519PublicKey::LENGTH..)
.ok_or_else(|| eyre::eyre!("Invalid length"))?;
let sk = Ed25519PrivateKey::from_bytes(priv_key_bytes)?;
Ok(SuiKeyPair::Ed25519(<Ed25519KeyPair as From<
Ed25519PrivateKey,
>>::from(sk)))
let sk = Ed25519PrivateKey::from_bytes(
bytes
.get(1 + Ed25519PublicKey::LENGTH..)
.ok_or_else(|| eyre::eyre!("Invalid length"))?,
)?;
Ok(SuiKeyPair::Ed25519(sk.into()))
} else if x == &Secp256k1SuiSignature::SCHEME.flag() {
let sk = Secp256k1PrivateKey::from_bytes(
bytes
.get(1 + Secp256k1PublicKey::LENGTH..)
.ok_or_else(|| eyre::eyre!("Invalid length"))?,
)?;
Ok(SuiKeyPair::Secp256k1(<Secp256k1KeyPair as From<
Secp256k1PrivateKey,
>>::from(sk)))
Ok(SuiKeyPair::Secp256k1(sk.into()))
} else if x == &Secp256r1SuiSignature::SCHEME.flag() {
let sk = Secp256r1PrivateKey::from_bytes(
bytes
.get(1 + Secp256r1PublicKey::LENGTH..)
.ok_or_else(|| eyre::eyre!("Invalid length"))?,
)?;
Ok(SuiKeyPair::Secp256r1(<Secp256r1KeyPair as From<
Secp256r1PrivateKey,
>>::from(sk)))
Ok(SuiKeyPair::Secp256r1(sk.into()))
} else {
Err(eyre::eyre!("Invalid flag byte"))
}
Expand Down
4 changes: 2 additions & 2 deletions crates/sui-types/src/sui_serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::marker::PhantomData;

use anyhow::anyhow;
use fastcrypto::encoding::{Base64, Encoding};
use fastcrypto::traits::ToFromBytes;
use fastcrypto::traits::{EncodeDecodeBase64, ToFromBytes};
use move_core_types::account_address::AccountAddress;
use serde;
use serde::de::{Deserializer, Error};
Expand Down Expand Up @@ -201,7 +201,7 @@ impl SerializeAs<AuthoritySignature> for AuthSignature {
where
S: Serializer,
{
Base64::encode(value.as_ref()).serialize(serializer)
value.encode_base64().serialize(serializer)
}
}

Expand Down
3 changes: 2 additions & 1 deletion crates/sui-types/src/unit_tests/base_types_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use std::str::FromStr;

use fastcrypto::traits::EncodeDecodeBase64;
use move_binary_format::file_format;

use crate::crypto::bcs_signable_test::{Bar, Foo};
Expand Down Expand Up @@ -311,7 +312,7 @@ fn test_authority_signature_serde_human_readable() {
let sig = AuthoritySignature::new(&Foo("some data".to_string()), 0, &key);
let serialized = serde_json::to_string(&sig).unwrap();
assert_eq!(
format!(r#"{{"sig":"{}"}}"#, Base64::encode(sig.as_ref())),
format!(r#"{{"sig":"{}"}}"#, sig.encode_base64()),
serialized
);
let deserialized: AuthoritySignature = serde_json::from_str(&serialized).unwrap();
Expand Down
25 changes: 9 additions & 16 deletions crates/sui/src/keytool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,16 @@ use anyhow::anyhow;
use bip32::DerivationPath;
use clap::*;
use fastcrypto::encoding::{decode_bytes_hex, Base64, Encoding};
use fastcrypto::traits::{ToFromBytes, VerifyingKey};
use sui_keys::key_derive::generate_new_key;
use sui_types::intent::Intent;
use sui_types::messages::TransactionData;
use tracing::info;

use fastcrypto::ed25519::{Ed25519KeyPair, Ed25519PrivateKey, Ed25519PublicKey};
use sui_keys::keystore::{AccountKeystore, Keystore};
use sui_types::base_types::SuiAddress;
use sui_types::crypto::{
get_authority_key_pair, AuthorityKeyPair, Ed25519SuiSignature, EncodeDecodeBase64,
NetworkKeyPair, SignatureScheme, SuiKeyPair, SuiSignatureInner,
get_authority_key_pair, AuthorityKeyPair, EncodeDecodeBase64, NetworkKeyPair, SignatureScheme,
SuiKeyPair,
};
#[cfg(test)]
#[path = "unit_tests/keytool_tests.rs"]
Expand Down Expand Up @@ -93,7 +91,7 @@ impl KeyToolCommand {
let res: Result<SuiKeyPair, anyhow::Error> = read_keypair_from_file(&file);
match res {
Ok(keypair) => {
println!("Public Key: {}", Base64::encode(keypair.public()));
println!("Public Key: {}", keypair.public().encode_base64());
println!("Flag: {}", keypair.public().flag());
}
Err(e) => {
Expand All @@ -115,7 +113,7 @@ impl KeyToolCommand {
println!(
" {0: ^42} | {1: ^45} | {2: ^6}",
Into::<SuiAddress>::into(&pub_key),
Base64::encode(&pub_key),
pub_key.encode_base64(),
pub_key.scheme().to_string()
);
}
Expand Down Expand Up @@ -229,15 +227,10 @@ pub fn read_network_keypair_from_file<P: AsRef<std::path::Path>>(
path: P,
) -> anyhow::Result<NetworkKeyPair> {
let value = std::fs::read_to_string(path)?;
let bytes = Base64::decode(value.as_str()).map_err(|e| anyhow::anyhow!(e))?;
if let Some(flag) = bytes.first() {
if flag == &Ed25519SuiSignature::SCHEME.flag() {
let priv_key_bytes = bytes
.get(1 + Ed25519PublicKey::LENGTH..)
.ok_or_else(|| anyhow!("Invalid length"))?;
let sk = Ed25519PrivateKey::from_bytes(priv_key_bytes)?;
return Ok(<Ed25519KeyPair as From<Ed25519PrivateKey>>::from(sk));
}
let kp = SuiKeyPair::decode_base64(value.as_str()).map_err(|e| anyhow!(e))?;
if let SuiKeyPair::Ed25519(kp) = kp {
Ok(kp)
} else {
Err(anyhow!("Invalid scheme for network keypair"))
}
Err(anyhow!("Invalid bytes"))
}

0 comments on commit d656b08

Please sign in to comment.