Add to_hex converter and add tests for hex conversion

This commit is contained in:
Elichai Turkel 2021-06-28 16:48:38 +03:00 committed by Dr Maxim Orlovsky
parent 24a9c9c765
commit 635a6ae441
No known key found for this signature in database
GPG Key ID: FFC0250947E5C6F7
1 changed files with 50 additions and 3 deletions

View File

@ -137,7 +137,6 @@ pub use secp256k1_sys as ffi;
#[cfg(all(test, target_arch = "wasm32"))] extern crate wasm_bindgen_test; #[cfg(all(test, target_arch = "wasm32"))] extern crate wasm_bindgen_test;
#[cfg(feature = "alloc")] extern crate alloc; #[cfg(feature = "alloc")] extern crate alloc;
use core::{fmt, ptr, str};
#[macro_use] #[macro_use]
mod macros; mod macros;
@ -156,7 +155,7 @@ pub use key::PublicKey;
pub use context::*; pub use context::*;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::ops::Deref; use core::ops::Deref;
use core::mem; use core::{mem, fmt, ptr, str};
use ffi::{CPtr, types::AlignedType}; use ffi::{CPtr, types::AlignedType};
#[cfg(feature = "global-context-less-secure")] #[cfg(feature = "global-context-less-secure")]
@ -851,6 +850,28 @@ fn from_hex(hex: &str, target: &mut [u8]) -> Result<usize, ()> {
Ok(idx / 2) Ok(idx / 2)
} }
/// Utility function used to encode hex into a target u8 buffer. Returns
/// a reference to the target buffer as an str.
// it returns an error if the target buffer isn't big enough
#[inline]
fn to_hex<'a>(src: &[u8], target: &'a mut [u8]) -> Result<&'a str, ()> {
let hex_len = src.len() * 2;
if target.len() < hex_len {
return Err(());
}
const HEX_TABLE: [u8; 16] = *b"0123456789abcdef";
let mut i = 0;
for &b in src {
target[i] = HEX_TABLE[usize::from(b >> 4)];
target[i+1] = HEX_TABLE[usize::from(b & 0b00001111)];
i +=2 ;
}
let result = &target[..hex_len];
debug_assert!(str::from_utf8(result).is_ok());
return unsafe { Ok(str::from_utf8_unchecked(result)) };
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
@ -859,7 +880,7 @@ mod tests {
use std::marker::PhantomData; use std::marker::PhantomData;
use key::{SecretKey, PublicKey}; use key::{SecretKey, PublicKey};
use super::from_hex; use super::{from_hex, to_hex};
use super::constants; use super::constants;
use super::{Secp256k1, Signature, Message}; use super::{Secp256k1, Signature, Message};
use super::Error::{InvalidMessage, IncorrectSignature, InvalidSignature}; use super::Error::{InvalidMessage, IncorrectSignature, InvalidSignature};
@ -1186,6 +1207,32 @@ mod tests {
assert!(Message::from_slice(&[1; constants::MESSAGE_SIZE]).is_ok()); assert!(Message::from_slice(&[1; constants::MESSAGE_SIZE]).is_ok());
} }
#[test]
fn test_hex() {
let mut rng = thread_rng();
const AMOUNT: usize = 1024;
for i in 0..AMOUNT {
// 255 isn't a valid utf8 character.
let mut hex_buf = [255u8; AMOUNT*2];
let mut src_buf = [0u8; AMOUNT];
let mut result_buf = [0u8; AMOUNT];
let src = &mut src_buf[0..i];
rng.fill_bytes(src);
let hex = to_hex(src, &mut hex_buf).unwrap();
assert_eq!(from_hex(hex, &mut result_buf).unwrap(), i);
assert_eq!(src, &result_buf[..i]);
}
assert!(to_hex(&[1;2], &mut [0u8; 3]).is_err());
assert!(to_hex(&[1;2], &mut [0u8; 4]).is_ok());
assert!(from_hex("deadbeaf", &mut [0u8; 3]).is_err());
assert!(from_hex("deadbeaf", &mut [0u8; 4]).is_ok());
assert!(from_hex("a", &mut [0u8; 4]).is_err());
assert!(from_hex("ag", &mut [0u8; 4]).is_err());
}
#[test] #[test]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
fn test_low_s() { fn test_low_s() {