Skip to content
Snippets Groups Projects
Commit 37a21e56 authored by Éloïs's avatar Éloïs
Browse files

[fix] ed25519: pubkey from bytes: ensure bytes represent Edwards point

parent dca861c7
No related branches found
No related tags found
1 merge request!8Elois/private message
...@@ -18,6 +18,7 @@ arrayvec = { version = "0.5.1", features = ["array-sizes-33-128", "array-sizes-1 ...@@ -18,6 +18,7 @@ arrayvec = { version = "0.5.1", features = ["array-sizes-33-128", "array-sizes-1
base64 = "0.11.0" base64 = "0.11.0"
bs58 = "0.3.0" bs58 = "0.3.0"
byteorder = "1.3.2" byteorder = "1.3.2"
curve25519-dalek = "2.0.0"
ring = "0.16.9" ring = "0.16.9"
scrypt = { version = "0.2", default-features = false } scrypt = { version = "0.2", default-features = false }
serde = { version = "1.0.*", features = ["derive"], optional = true } serde = { version = "1.0.*", features = ["derive"], optional = true }
......
...@@ -27,6 +27,7 @@ use crate::bases::*; ...@@ -27,6 +27,7 @@ use crate::bases::*;
use crate::rand::UnspecifiedRandError; use crate::rand::UnspecifiedRandError;
use crate::seeds::Seed32; use crate::seeds::Seed32;
use base64; use base64;
use curve25519_dalek::edwards::CompressedEdwardsY;
use ring::signature::{Ed25519KeyPair as RingKeyPair, KeyPair, UnparsedPublicKey, ED25519}; use ring::signature::{Ed25519KeyPair as RingKeyPair, KeyPair, UnparsedPublicKey, ED25519};
#[cfg(feature = "ser")] #[cfg(feature = "ser")]
use serde::{ use serde::{
...@@ -73,6 +74,7 @@ impl Serialize for Signature { ...@@ -73,6 +74,7 @@ impl Serialize for Signature {
} }
#[cfg(feature = "ser")] #[cfg(feature = "ser")]
#[cfg_attr(tarpaulin, skip)]
impl<'de> Deserialize<'de> for Signature { impl<'de> Deserialize<'de> for Signature {
fn deserialize<D>(deserializer: D) -> Result<Signature, D::Error> fn deserialize<D>(deserializer: D) -> Result<Signature, D::Error>
where where
...@@ -187,12 +189,19 @@ impl TryFrom<&[u8]> for PublicKey { ...@@ -187,12 +189,19 @@ impl TryFrom<&[u8]> for PublicKey {
found: bytes.len(), found: bytes.len(),
}) })
} else { } else {
let mut u8_array = [0; PUBKEY_SIZE_IN_BYTES]; // Ensure that given bytes represents a valid point on the Edwards form of Curve25519.
u8_array[(PUBKEY_SIZE_IN_BYTES - bytes.len())..].copy_from_slice(&bytes); let compressed_edwards_y = CompressedEdwardsY::from_slice(bytes);
Ok(PublicKey { if compressed_edwards_y.decompress().is_some() {
datas: u8_array, let mut u8_array = [0; PUBKEY_SIZE_IN_BYTES];
count_leading_zero: 0, u8_array[(PUBKEY_SIZE_IN_BYTES - bytes.len())..].copy_from_slice(bytes);
})
Ok(PublicKey {
datas: u8_array,
count_leading_zero: 0,
})
} else {
Err(PubkeyFromBytesError::InvalidBytesContent)
}
} }
} }
} }
...@@ -684,6 +693,42 @@ Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 ...@@ -684,6 +693,42 @@ Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
assert!(keypair.verify(message.as_bytes(), &sig).is_ok()); assert!(keypair.verify(message.as_bytes(), &sig).is_ok());
} }
#[test]
fn invalid_pubkey() -> Result<(), ()> {
let invalid_bytes = [
206u8, 58, 67, 221, 20, 133, 0, 225, 86, 115, 26, 104, 142, 116, 140, 132, 119, 51,
175, 45, 82, 225, 14, 195, 7, 107, 43, 212, 8, 37, 234, 23,
];
if let Err(PubkeyFromBytesError::InvalidBytesContent) =
PublicKey::try_from(&invalid_bytes[..])
{
Ok(())
} else {
panic!("expected PubkeyFromBytesError::InvalidBytesContent");
}
}
#[test]
fn test_parse_expanded_base58_private_key() {
let bytes = bs58::decode(
"31uSnvigJtJEUgG4YDqJB99awp4hkYgYqb3Yzu8P1LP5ZPMHtwNoCohVhm6jKcG9HFHbagDWdcoPgYBgHhdg5Efo"
).into_vec().expect("fail to decode b58");
let mut seed = [0u8; 32];
seed.copy_from_slice(&bytes[..32]);
let mut pubkey_bytes = [0u8; 32];
pubkey_bytes.copy_from_slice(&bytes[32..64]);
let keypair = KeyPairFromSeed32Generator::generate(Seed32::new(seed));
assert_eq!(
"8hgzaeFnjkNCsemcaL4rmhB2999B79BydtE8xow4etB7",
&keypair.public_key().to_base58()
);
assert_eq!(
"8hgzaeFnjkNCsemcaL4rmhB2999B79BydtE8xow4etB7",
&bs58::encode(&pubkey_bytes).into_string(),
);
}
/*#[test] /*#[test]
fn test_tmp() { fn test_tmp() {
let message = "InnerHash: A9697A9954EA447BBDC88D1B22AA8B60B2D11986DE806319C1A5AAFEB348C213\nNonce: 10300000043648\n"; let message = "InnerHash: A9697A9954EA447BBDC88D1B22AA8B60B2D11986DE806319C1A5AAFEB348C213\nNonce: 10300000043648\n";
......
...@@ -251,6 +251,8 @@ pub enum PubkeyFromBytesError { ...@@ -251,6 +251,8 @@ pub enum PubkeyFromBytesError {
/// Found length /// Found length
found: usize, found: usize,
}, },
/// Invalid bytes content
InvalidBytesContent,
} }
impl PubKey { impl PubKey {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment