From 8fdbe5c05109a5fd78e094c15cdcfa505e62147c Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Sat, 12 Dec 2020 11:38:47 -0700 Subject: [PATCH] Girocco/HashUtil.pm: speed up by an order of magnitude The perl transliteration operator (tr/// aka y///) runs much, much, much more quickly than a global pattern substitution. Replace the various global substitution patterns with suitable transliteration operations to vastly speed up the computation of the result. Speed is roughly 10x faster with these changes. Signed-off-by: Kyle J. McKay --- Girocco/HashUtil.pm | 54 ++++++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/Girocco/HashUtil.pm b/Girocco/HashUtil.pm index b5deb0c..368b5ab 100644 --- a/Girocco/HashUtil.pm +++ b/Girocco/HashUtil.pm @@ -1,5 +1,5 @@ # Girocco::HashUtil.pm -- HMAC SHA-1 Utility Functions -# Copyright (c) 2013 Kyle J. McKay. All rights reserved. +# Copyright (C) 2013,2020 Kyle J. McKay. All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -50,44 +50,38 @@ BEGIN { . "must be available\n"; } -my %_b64convert; -BEGIN { - # A table that converts a standard base 64 encoding using this string: - # "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - # to the alternate crypt encoding using this string: - # "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - %_b64convert = ( - 'A'=>'.','B'=>'/','C'=>'0','D'=>'1','E'=>'2','F'=>'3','G'=>'4','H'=>'5', - 'I'=>'6','J'=>'7','K'=>'8','L'=>'9','M'=>'A','N'=>'B','O'=>'C','P'=>'D', - 'Q'=>'E','R'=>'F','S'=>'G','T'=>'H','U'=>'I','V'=>'J','W'=>'K','X'=>'L', - 'Y'=>'M','Z'=>'N','a'=>'O','b'=>'P','c'=>'Q','d'=>'R','e'=>'S','f'=>'T', - 'g'=>'U','h'=>'V','i'=>'W','j'=>'X','k'=>'Y','l'=>'Z','m'=>'a','n'=>'b', - 'o'=>'c','p'=>'d','q'=>'e','r'=>'f','s'=>'g','t'=>'h','u'=>'i','v'=>'j', - 'w'=>'k','x'=>'l','y'=>'m','z'=>'n','0'=>'o','1'=>'p','2'=>'q','3'=>'r', - '4'=>'s','5'=>'t','6'=>'u','7'=>'v','8'=>'w','9'=>'x','+'=>'y','/'=>'z' - ); -} - # Like MIME::Base64::encode except that the crypt Base64 string is used # instead and no \n or = characters are generated and each 4-character output # sequence is reversed. To make the input an even multiple of 3-character # sequences, the first 1 or 2 bytes of it may be repeated on the end. sub _encode_base64_alt { use bytes; - my $val = shift || ''; - $val .= substr($val.$val, 0, (3-(length($val)%3))) if length($val)%3; + my $val = defined($_[0]) ? $_[0] : ''; + my $l = length($val); + my $r; + $l == 1 and $val .= $val.$val; + $l > 1 and $r = $l % 3 and $val .= substr($val,0,3-$r); my $b64 = encode_base64($val, ''); - $b64 =~ s/=+//; - $b64 =~ s/(.)/$_b64convert{$1}/g; + # convert standard base 64 encoding to the alternate crypt encoding + $b64 =~ tr{ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/} + {./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz}; my $out = ''; - while (length($b64)) { - $out .= substr($b64,3,1).substr($b64,2,1). - substr($b64,1,1).substr($b64,0,1); - substr($b64,0,4) = ''; - } + $l = length($b64); + my $i = 0; + $out .= reverse(substr($b64,$i,4)), $i += 4 while $i < $l; return $out; } +sub _xor36 {use bytes; $_[0]=~tr +{\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff} +{\x36\x37\x34\x35\x32\x33\x30\x31\x3e\x3f\x3c\x3d\x3a\x3b\x38\x39\x26\x27\x24\x25\x22\x23\x20\x21\x2e\x2f\x2c\x2d\x2a\x2b\x28\x29\x16\x17\x14\x15\x12\x13\x10\x11\x1e\x1f\x1c\x1d\x1a\x1b\x18\x19\x06\x07\x04\x05\x02\x03\x00\x01\x0e\x0f\x0c\x0d\x0a\x0b\x08\x09\x76\x77\x74\x75\x72\x73\x70\x71\x7e\x7f\x7c\x7d\x7a\x7b\x78\x79\x66\x67\x64\x65\x62\x63\x60\x61\x6e\x6f\x6c\x6d\x6a\x6b\x68\x69\x56\x57\x54\x55\x52\x53\x50\x51\x5e\x5f\x5c\x5d\x5a\x5b\x58\x59\x46\x47\x44\x45\x42\x43\x40\x41\x4e\x4f\x4c\x4d\x4a\x4b\x48\x49\xb6\xb7\xb4\xb5\xb2\xb3\xb0\xb1\xbe\xbf\xbc\xbd\xba\xbb\xb8\xb9\xa6\xa7\xa4\xa5\xa2\xa3\xa0\xa1\xae\xaf\xac\xad\xaa\xab\xa8\xa9\x96\x97\x94\x95\x92\x93\x90\x91\x9e\x9f\x9c\x9d\x9a\x9b\x98\x99\x86\x87\x84\x85\x82\x83\x80\x81\x8e\x8f\x8c\x8d\x8a\x8b\x88\x89\xf6\xf7\xf4\xf5\xf2\xf3\xf0\xf1\xfe\xff\xfc\xfd\xfa\xfb\xf8\xf9\xe6\xe7\xe4\xe5\xe2\xe3\xe0\xe1\xee\xef\xec\xed\xea\xeb\xe8\xe9\xd6\xd7\xd4\xd5\xd2\xd3\xd0\xd1\xde\xdf\xdc\xdd\xda\xdb\xd8\xd9\xc6\xc7\xc4\xc5\xc2\xc3\xc0\xc1\xce\xcf\xcc\xcd\xca\xcb\xc8\xc9} +} + +sub _xor5C {use bytes; $_[0]=~tr +{\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff} +{\x5c\x5d\x5e\x5f\x58\x59\x5a\x5b\x54\x55\x56\x57\x50\x51\x52\x53\x4c\x4d\x4e\x4f\x48\x49\x4a\x4b\x44\x45\x46\x47\x40\x41\x42\x43\x7c\x7d\x7e\x7f\x78\x79\x7a\x7b\x74\x75\x76\x77\x70\x71\x72\x73\x6c\x6d\x6e\x6f\x68\x69\x6a\x6b\x64\x65\x66\x67\x60\x61\x62\x63\x1c\x1d\x1e\x1f\x18\x19\x1a\x1b\x14\x15\x16\x17\x10\x11\x12\x13\x0c\x0d\x0e\x0f\x08\x09\x0a\x0b\x04\x05\x06\x07\x00\x01\x02\x03\x3c\x3d\x3e\x3f\x38\x39\x3a\x3b\x34\x35\x36\x37\x30\x31\x32\x33\x2c\x2d\x2e\x2f\x28\x29\x2a\x2b\x24\x25\x26\x27\x20\x21\x22\x23\xdc\xdd\xde\xdf\xd8\xd9\xda\xdb\xd4\xd5\xd6\xd7\xd0\xd1\xd2\xd3\xcc\xcd\xce\xcf\xc8\xc9\xca\xcb\xc4\xc5\xc6\xc7\xc0\xc1\xc2\xc3\xfc\xfd\xfe\xff\xf8\xf9\xfa\xfb\xf4\xf5\xf6\xf7\xf0\xf1\xf2\xf3\xec\xed\xee\xef\xe8\xe9\xea\xeb\xe4\xe5\xe6\xe7\xe0\xe1\xe2\xe3\x9c\x9d\x9e\x9f\x98\x99\x9a\x9b\x94\x95\x96\x97\x90\x91\x92\x93\x8c\x8d\x8e\x8f\x88\x89\x8a\x8b\x84\x85\x86\x87\x80\x81\x82\x83\xbc\xbd\xbe\xbf\xb8\xb9\xba\xbb\xb4\xb5\xb6\xb7\xb0\xb1\xb2\xb3\xac\xad\xae\xaf\xa8\xa9\xaa\xab\xa4\xa5\xa6\xa7\xa0\xa1\xa2\xa3} +} + # As defined in RFC 2104 for H = SHA-1 sub hmac_sha1 { use bytes; @@ -105,7 +99,7 @@ sub hmac_sha1 { # (2) Create the step 4 data for the hash starting with $key XOR 0x36 my $data4 = $key; - $data4 =~ s/(.)/chr(ord($1)^0x36)/ge; + _xor36($data4); # (3) Append the text $data4 .= $text; @@ -115,7 +109,7 @@ sub hmac_sha1 { # (5) Create the step 5 data for the hash starting with $key XOR 0x5C my $data5 = $key; - $data5 =~ s/(.)/chr(ord($1)^0x5C)/ge; + _xor5C($data5); # (6) Append step 4 result to step 5 result $data5 .= $data4; -- 2.11.4.GIT