diff options
author | Dmitry Belyavskiy <beldmit@gmail.com> | 2018-03-15 11:03:36 +0300 |
---|---|---|
committer | Dmitry Belyavskiy <beldmit@gmail.com> | 2018-03-15 11:03:36 +0300 |
commit | 835e0d788bfec1f51545b038cef135b02456b27b (patch) | |
tree | 68385e6234e82915681e6e45b9060bc0ba64e1ba /gosthash2012.c | |
parent | 75df5b70a4122bac2d731acb479bba2104dbfb25 (diff) | |
download | gost-engine-835e0d788bfec1f51545b038cef135b02456b27b.zip gost-engine-835e0d788bfec1f51545b038cef135b02456b27b.tar.gz gost-engine-835e0d788bfec1f51545b038cef135b02456b27b.tar.bz2 |
Bugfix - carry bit overflow
Diffstat (limited to 'gosthash2012.c')
-rw-r--r-- | gosthash2012.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/gosthash2012.c b/gosthash2012.c index f9b8f23..ee534c2 100644 --- a/gosthash2012.c +++ b/gosthash2012.c @@ -60,18 +60,33 @@ static INLINE void add512(const union uint512_u *x, { #ifndef __GOST3411_BIG_ENDIAN__ unsigned int CF, OF; + unsigned long long tmp; unsigned int i; CF = 0; - for (i = 0; i < 8; i++) { - r->QWORD[i] = x->QWORD[i] + y->QWORD[i]; - if (r->QWORD[i] < y->QWORD[i] || r->QWORD[i] < x->QWORD[i]) + for (i = 0; i < 8; i++) + { + /* Detecting integer overflow condition for three numbers + * in a portable way is tricky a little. */ + + /* Step 1: numbers cause overflow */ + tmp = x->QWORD[i] + y->QWORD[i]; + + /* Compare with any of two summands, no need to check both */ + if (tmp < x->QWORD[i]) OF = 1; else OF = 0; - r->QWORD[i] += CF; + /* Step 2: carry bit causes overflow */ + tmp += CF; + + if (CF > 0 && tmp == 0) + OF = 1; + CF = OF; + + r->QWORD[i] = tmp; } #else const unsigned char *xp, *yp; |