refactor: implement some optimisations

When possible, the original header is used instead of allocating a new header.

The generated hash is no longer encoded into hex for comparisons.
This commit is contained in:
Anna 2023-08-31 00:22:30 -04:00
parent fae04ba3b8
commit fae02b3423
Signed by: anna
GPG Key ID: D0943384CD9F87D1
1 changed files with 67 additions and 5 deletions

View File

@ -254,6 +254,24 @@ fn unlock_key_file(path: &str, check_secrets: bool, return_password: bool) -> Re
}
const PW_SERVICE: &str = "lgbt.anna.git-vain";
const NIBBLES: [[u8; 16]; 16] = [
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31],
[32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47],
[48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63],
[64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95],
[96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111],
[112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127],
[128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143],
[144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159],
[160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175],
[176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191],
[192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207],
[208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223],
[224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239],
[240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255],
];
fn main() -> Result<()> {
let args = Cli::parse();
@ -311,6 +329,30 @@ fn main() -> Result<()> {
let prefix = args.prefix
.expect("clap should handle this")
.to_lowercase();
if !prefix.chars().all(|c| c.is_ascii_hexdigit()) {
anyhow::bail!("prefix must be hexadecimal");
}
let (byte_prefix, nibble_values) = if prefix.len() % 2 == 0 {
// even
let bytes = data_encoding::HEXLOWER.decode(prefix.as_bytes())
.context("could not decode prefix as hex")?;
(bytes, None)
} else {
// odd
let bytes = data_encoding::HEXLOWER.decode(prefix[..prefix.len() - 1].as_bytes())
.context("could not decode prefix as hex")?;
let last = prefix.as_bytes()[prefix.len() - 1];
let idx = match last {
48..=57 => last - 48,
97..=102 => last - 97,
_ => unreachable!(),
};
let nibble = NIBBLES[idx as usize];
(bytes, Some(nibble))
};
let threads = match args.threads.or_else(|| config.as_ref().and_then(|c| c.threads)) {
None | Some(0) => num_cpus::get(),
Some(x) => x,
@ -382,6 +424,8 @@ fn main() -> Result<()> {
}
}
let stripped_header = header_lines.join("\n");
let message = commit.message_raw()
.context("commit had an invalid message")?
.to_string();
@ -427,10 +471,12 @@ fn main() -> Result<()> {
let found = Arc::clone(&found);
let timestamp = Arc::clone(&timestamp);
let message = message.clone();
let prefix = prefix.clone();
let byte_prefix = byte_prefix.clone();
let nibble_values = nibble_values.clone();
let mut author_parts = author_parts.clone();
let mut committer_parts = committer_parts.clone();
let mut header_lines = header_lines.clone();
let stripped_header = stripped_header.clone();
let method = args.method
.or_else(|| config.as_ref().and_then(|c| c.method))
.unwrap_or(Method::Counter);
@ -503,11 +549,17 @@ fn main() -> Result<()> {
line.push_str(buffer.format(count));
}
let mut header = header_lines.join("\n");
let mut header = match method {
// counter and random don't mutate the header, so don't
// allocate for it
Method::Counter | Method::Random => Cow::from(&stripped_header),
_ => Cow::from(header_lines.join("\n")),
};
// NOTE: don't need to handle append here, since we'll never be
// both appending *and* signing
if let Some(ctx) = &mut gpg {
let header = header.to_mut();
let to_sign = format!("{header}\n{message}");
let mut output = Vec::new();
ctx.sign(SignMode::Detached, to_sign, &mut output)
@ -524,6 +576,7 @@ fn main() -> Result<()> {
header.push('\n');
}
} else if let Some(key) = &mut seq_key {
let header = header.to_mut();
let to_sign = format!("{header}\n{message}");
let sig = SignatureBuilder::new(SignatureType::Binary)
.sign_message(key, to_sign)
@ -564,7 +617,7 @@ fn main() -> Result<()> {
sha1.update("commit ");
sha1.update(buffer.format(header.len() + message_len + 1));
sha1.update([0]);
sha1.update(&header);
sha1.update(header.as_bytes());
sha1.update("\n");
match &append {
Some(a) => {
@ -577,10 +630,18 @@ fn main() -> Result<()> {
}
let hash = sha1.finalize_reset();
let hash = data_encoding::HEXLOWER.encode(&hash);
// let hash = data_encoding::HEXLOWER.encode(&hash);
bar.inc(1);
if hash.starts_with(&prefix) {
// if hash.starts_with(&prefix) {
if hash[0..byte_prefix.len()] == byte_prefix {
// check the nibble
if let Some(values) = nibble_values {
if !values.contains(&hash[byte_prefix.len()]) {
continue;
}
}
found.store(true, Ordering::SeqCst);
let message = match append {
Some(append) => Cow::from(format!("{message}\n{append}\n")),
@ -588,6 +649,7 @@ fn main() -> Result<()> {
};
let total = format!("{header}\n{message}");
let raw_commit = format!("commit {}\0", total.len());
let hash = data_encoding::HEXLOWER.encode(&hash);
commit_tx.send((hash, format!("{raw_commit}{total}"))).unwrap();
break;
}