forgot to append the data as usual. Now appended.
Note: "Experimental" is the ADC based code, "Safe / New" is poncho's code.

Am 07.11.2015 um 21:07 schrieb Jean-Pierre Münch:
> Am 05.11.2015 um 21:57 schrieb Jean-Pierre Münch:
>> Am 05.11.2015 um 04:13 schrieb Jeffrey Walton:
>>>
>>>>     On Wednesday, November 4, 2015 at 12:56:12 PM UTC-5,
>>>>     jean-pierre.muench wrote:
>>>>
>>>>         Interesting idea, although I fear that a timing side
>>>>         channel may remain (two dozen carries may take longer than
>>>>         no carry) and thereby not fixing the problem (if I'm
>>>>         reading things right).
>>>>
>>>>
>>>>     Forgot to mention... An ADC will work nicely here
>>>>     (http://www.fermimn.gov.it/linux/quarta/x86/adc.htm). There
>>>>     might even be an intrinsic for it.
>>>     Are you proposing something like the following?
>>>
>>>     |void IncrementCounterByOne(byte *in,byte *out, unsigned int
>>>     size) { byte cf = _addcarry_u8(0,1,in[size-1],&in[size-1]); //
>>>     make the initial addition for(int i=size-2;i>=0;--i) { cf = 
>>> |||_addcarry_u8(cf,0,in[i],&in[i]); // carry it over until the
>>>     very end| } memmove(out,in,size); } |
>>>
>>>     |This should run in constant time, assuming _addcarry_u8 runs in
>>>     constant time. I've tested this and it produces correct results.|
>>>
>>> Yeah, something like that should be fine. In that particular
>>> overload, I *think* `in` is a `const byte*`, so you probably cannot
>>> write to it. But I'd need to check. 
>> Yes, indeed I got the header wrong. My (new) proposals are below. As
>> for the speed, we just have to accept O(log(n)) run-time as it looks
>> if we want to provide constant time implementations, as we have to
>> compute no matter if there's a carry or not. Our current
>> implementation is basically o(1). I'll compare our options again in
>> the next few (2-3) days. The proposals use ADC on x86/x64 (still not
>> sure how to do this), use poncho's code for anything without ADC and
>> allow for our old code on override. Furthermore the two argument
>> function is now a special case of the three argument function. BR JPM 
> I finally got the promised data. It tells me that using the ADC
> instruction is *slower* than using poncho's approach in most cases
> (data's attached). So I'd propose the below set of functions as
> mitigation for this issue. However I think we need some sort of
> consensus on the strategy for this, which can be summarized as
> follows: We found the issue that non-constant time increments can
> provide a timing side channel that potentially allows for severe
> attacks on GCM. For the sake of speed our current code is non-constant
> time and thereby depends on the actual values of the bytes. We have a
> piece of code that fixes this issue and runs in constant time, the
> problem is that its run-time grows linearly with the length of the
> buffer to increment and its execution time usually is significantly
> longer than the old one. However the actual execution time of each
> call is still very short as it's a simple function, taking ~26.1
> cycles for 8 bytes on an i7 930 and ~2922 cycles for 1024 bytes on the
> same processor. The old code takes about 8.72 cycles for every
> size[1]. The question is now about the API, should we:
>
>  1. Not mitigate and just keep our old code.
>  2. Mitigate and allow for both codes (constant + non-constant time),
>     default to "use non-constant time code"
>  3. Mitigate and allow for both codes (constant + non-constant time),
>     default to "use constant time code"
>  4. Mitigate and only allow for constant time code
>
> My stand-point should be clear. The code for 3 and 4 can be found
> below, with a simple true/false exchange at the correct places.
>
> BR
>
> JPM
>
> [1]: The results were averaged from 2^33 function calls, the actual
> cycles may be a bit higher as TurboBoost frequency wasn't incorporated
> into the calculation.
>> inline void IncrementCounterByOne(byte *output, const byte *input, unsigned 
>> int s,bool UseUnsafeIncrement)
>> {
>>      if(UseUnsafeIncrement)
>>      {
>>              int i, carry;
>>              for (i=s-1, carry=1; i>=0 && carry; i--)
>>                      carry = ((output[i] = input[i]+1) == 0);
>>              memmove_s(output, s, input, i+1);
>>              return;
>>      }
>> |||for (int i=int(size-1), carry=1; i>=0; i--) { int t = input[i] +
>> carry; output[i] = t & 0xff; carry = t >> 8; }| ||}
>>
>> inline void IncrementCounterByOne(byte *output, const byte *input, unsigned 
>> int s)
>> {
>>      IncrementCounterByOne(output,input,s,false);
>> }
>>
>> inline void IncrementCounterByOne(byte *inout, unsigned int s)
>> {
>>      IncrementCounterByOne(inout,inout,s,false);
>> }
>>
>> inline void IncrementCounterByOne(byte *inout, unsigned int s,bool 
>> UseUnsafeIncrement)
>> {
>>      if(UseUnsafeIncrement)
>>      {
>>              for (int i=s-1, carry=1; i>=0 && carry; i--)
>>                      carry = !++inout[i];
>>              return;
>>      }
>>      IncrementCounterByOne(inout,inout,s,false); // use the safe code
>> }
>>
>>
>>> Jeff 
> -- -- You received this message because you are subscribed to the
> "Crypto++ Users" Google Group. To unsubscribe, send an email to
> cryptopp-users-unsubscr...@googlegroups.com. More information about
> Crypto++ and this group is available at http://www.cryptopp.com. ---
> You received this message because you are subscribed to the Google
> Groups "Crypto++ Users" group. To unsubscribe from this group and stop
> receiving emails from it, send an email to
> cryptopp-users+unsubscr...@googlegroups.com
> <mailto:cryptopp-users+unsubscr...@googlegroups.com>. For more
> options, visit https://groups.google.com/d/optout. 

-- 
-- 
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to cryptopp-users-unsubscr...@googlegroups.com.
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.
--- 
You received this message because you are subscribed to the Google Groups 
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to cryptopp-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Current buffer size: 1 bytes.
Old method time: 17818494µs.
Safe method time: 16435418µs.
Test method time: 17469064µs.
Overhead by new method: -7.76203%

Overhead by experimental method: -1.96105%

Current buffer size: 2 bytes.
Old method time: 26753134µs.
Safe method time: 48109188µs.
Test method time: 20938651µs.
Overhead by new method: 79.8264%

Overhead by experimental method: -21.7338%

Current buffer size: 4 bytes.
Old method time: 26445330µs.
Safe method time: 40338735µs.
Test method time: 49429638µs.
Overhead by new method: 52.5363%

Overhead by experimental method: 86.9125%

Current buffer size: 8 bytes.
Old method time: 26490806µs.
Safe method time: 80018675µs.
Test method time: 95708675µs.
Overhead by new method: 202.062%

Overhead by experimental method: 261.29%

Current buffer size: 16 bytes.
Old method time: 26618494µs.
Safe method time: 159927735µs.
Test method time: 188630680µs.
Overhead by new method: 500.814%

Overhead by experimental method: 608.645%

Current buffer size: 32 bytes.
Old method time: 26373319µs.
Safe method time: 299822817µs.
Test method time: 381609562µs.
Overhead by new method: 1036.84%

Overhead by experimental method: 1346.95%

Current buffer size: 64 bytes.
Old method time: 26369753µs.
Safe method time: 591267432µs.
Test method time: 762786294µs.
Overhead by new method: 2142.22%

Overhead by experimental method: 2792.66%

Current buffer size: 128 bytes.
Old method time: 26379620µs.
Safe method time: 1176066488µs.
Test method time: 1545594497µs.
Overhead by new method: 4358.24%

Overhead by experimental method: 5759.05%

Current buffer size: 256 bytes.
Old method time: 26398974µs.
Safe method time: 2294413860µs.
Test method time: 3035768316µs.
Overhead by new method: 8591.3%

Overhead by experimental method: 11399.6%

Current buffer size: 512 bytes.
Old method time: 26365764µs.
Safe method time: 4516061779µs.
Test method time: 5997060977µs.
Overhead by new method: 17028.5%

Overhead by experimental method: 22645.6%

Current buffer size: 1024 bytes.
Old method time: 26372286µs.
Safe method time: 8964378849µs.
Test method time: 11937839065µs.
Overhead by new method: 33891.7%

Overhead by experimental method: 45166.6%

Reply via email to