Originally Posted by Khaled
If you come across an identifier that you think should be using a different default value, let me know. However, if the behavior has been in place for a long time, it normally cannot be changed since that would affect backward compatibility.

So I guess that, if something has been around the block long enough, the default can't change, and the only solutions are to leave it as-is, or make the alternate behavior available only from a switch, or change only if the behavior is considered a bug.

  • $totp TIMESTEP

    One example is something I mentioned previously, where the TIMESTEP parm in $totp does the same thing that $xor and many other identifiers do, and evaluate text the same as if zero were used, so $and(123,text) is same as $and(123,0).

    Much of the time, text in numeric parameters results either from a typo when putting the %variable name in, or by mis-counting the parameters and putting a valid parameter in the wrong spot, such as $totp(key,sha1)

    However the TIMESTEP parameter seems to be a case that, even if it's valid to see text as the number zero, that is still invalid input.

    The TIMESTEP is a floor divisor for the TIME value, so zero and negatives are invalid floor divisors for a result that is supposed to be an integer [0,2^64-1], so that should be an invalid parameter rather than silently changing the input into the default of 30.

    So this example shows that TEXT and $null are returning the same result as if 30 were used.

    //var %timestepvar 60 , %time 123456789 | echo -a $totp(key,%time,sha1,6,%timestepvar) vs $totp(key,%time,sha1,6,timestepvar) same as $totp(key,%time,sha1,6,30) same as $totp(key,%time,sha1,6,0) same as $totp(key,%time,sha1,6,-1) same as $totp(key,%time,sha1,6,$null)

    Another aspect of the default behavior of TIMESTEP seems to be the exception to the general behavior that if a parameter is present, where normally that parm being $null is considered an error or causes the return value to be $null. i.e. there are exceptions like $tip where a $null parameter can be followed by a not-null parameter, but generally when an optional parameter is present but is blank, the identifier returns blank or an error, like with $sha1(abc,$null)

    But if I want to change the timestep from 30 to 60 without changing any of the other defaults, it doesn't let me do $totp(key,,,,60), but makes me list the 3 defaults in order to change the timestep. But if I do $totp(key,$ctime,sha1,6,) it lets me do that and treats $null as the default 30.

    Summary: it seems that a timestep 'value' that evaluates to zero should either return $null or generate an 'invalid parameter' error, because a (TIME // zero) is not a legit value. i.e. the default is correct, but should be used only when the parameter is not used, not when the parameter is not within the valid range of positives.
  • Interpreting text as zero for the newer math identifiers

    Most of the time, having text in a parameter is a typo from forgetting the % of a variable name or some other kind of error, and returning a value as if zero were used is not going to be useful behavior, and can make it hard to track down an error.

    I kept getting results that shouldn't be possible, until finally figuring out that a typo was causing $gcd to see one of the 3 parameters as text, making it return the wrong answer as if the parameter were zero.

    //var %a 25 , %b 35 , %c 29 | echo -a $gcd(%a,%b,%c) and $lcm(%a,%b,%c) vs $gcd(%a,%b,c) and $lcm(%a,%b,c)

    result: 1 and 1575 vs 5 and 0

    Summary: it seems more helpful for the newbies if it's an error/blank return if a parameter is not numeric:


    depends if you think the other long-in-the-tooth math identifiers should also interpret text as zero


    Also, since these new identifiers are valid only for integers, the current behavior of stripping fractions to make floats be integer is fine, but should not be handling scifi notation by translating it into integer, because this notation by definition has a limited precision, and 1e99 in the input is not necessarily going to be exactly 1 followed by 99 zeroes, and same goes for 1.123457e99.

    //echo -a $powmod(3,1e3,65539) should be error not same as $powmod(3,1000,65539)

    If there is the intent to have the input interpreted as scifi when it's present, then those edge cases can simply use the behavior of $int to handle situations where the input should interpret the notation, $powmod(3,$int(1e99),65539)


Missing parameters related to encryption keys:

  • $hotp and $totp

    /help $totp says 'The key is required'
    /help $hotp says 'The key is required'

    But they have never required that.

    //echo -a $totp() same as $totp($null) same as $totp($null,$ctime)

    $hotp allows a missing key, but only when the COUNT parameter is present since it treats that as required, but doesn't require the key be present:

    //echo -a $hotp($null,123) same as $hotp(,123)


    The purpose of $hotp and $totp is to prove that you know the key without actually sending the key itself. By having the output be a 6-digit number, it boils the key strength down to $log2(10^6) = 20 bits, and there's no usefulness or use-case for allowing the 'required' key be null length
  • $hmac This is restatement of the feature suggested I made for $hmac hex/binary keys

    HMAC is the only case I can think of where it's legit to have a crypto key be null length, due to people using HMAC as a keyless hash substitute for $sha256 or $sha512 that can be vulnerable to the length-extension attack in certain situations. Plus, HMAC is defined so that short keys are padded to full length, so a null key just gets more padding than other not-so-short keys do.

    However, when HMAC does use a key, it's almost always shown as hex, and the RFC test vectors can't be matched without being able to have the key be non-UTF8. The existing handling of the key defaulting as text can't be changed without a switch that makes it be seen as hex.
  • Restatement of suggestion Blowfish 'k' switch for $encode/$decode hex keys

    Likewise for Blowfish, the official test vectors all use hex keys and IV's, with virtually all of them being binary strings other than UTF8 text. The existing default has been there too long to enable hex keys without an optional switch for the Parm3/Parm4 to be seen as hex

    The default behavior of allowing the Parm3 key to be $null is also not desirable for encryption ciphers. Even though $encode(message,mc,$null) changes the output each time due to mixing a random salt with no-key-used, it ends up being no more secure than if using ROT13.

    When the Parm3 key is $null, $encode is treating it as if the input were a hex key of all 0x00 null bytes, which isn't the same thing. The design for Blowfish states that the key input is repeated until it's 72 bytes. There's 2 ways of doing this.
    for (key72=$null ; length(key72) < 72 ;) { key72 = $left( key72 $+ input,72) }
    for (i = 0;i < 72;i++) { key72[i] = input[ i % length(input)] }
    However a null key is invalid in both scenarios, either an infinite loop trying to repeat length 0 until it reaches length 72, or a divide by zero error when trying to use the Nth byte of a zero length key.

    So, currently the user cannot depend on an error message to prevent the encryption being done with a missing key, and needs to explicitly add an extra check against the %key variable being blank, or halt the script like $$+(%key)