From 9ee45d4e343420e0198594118f02c0abfc339171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Tue, 14 Mar 2017 00:32:32 +0100 Subject: [PATCH] Fix sign bug in special cases in mpi_{add,sub}_abs(). We failed to clear the negative flag when handling trivial cases, so if one of the terms was 0 and the other was negative, the result would be an exact copy of the non-zero term instead of its absolute value. --- lib/mpi/cryb_mpi_add_abs.c | 21 ++++++++++--- lib/mpi/cryb_mpi_sub_abs.c | 16 +++++++--- t/t_mpi_addsub.c | 62 ++++++++++++++++++++++++++++++-------- 3 files changed, 77 insertions(+), 22 deletions(-) diff --git a/lib/mpi/cryb_mpi_add_abs.c b/lib/mpi/cryb_mpi_add_abs.c index eb5739b..5562264 100644 --- a/lib/mpi/cryb_mpi_add_abs.c +++ b/lib/mpi/cryb_mpi_add_abs.c @@ -52,12 +52,23 @@ mpi_add_abs(cryb_mpi *X, cryb_mpi *A, cryb_mpi *B) if (A == B || mpi_eq_abs(A, B)) { if (X != A && X != B && mpi_copy(X, A) != 0) return (-1); - return (mpi_lshift(X, 1)); + if (mpi_lshift(X, 1) != 0) + return (-1); + X->neg = 0; + return (0); + } + if (A->msb == 0) { + if (X != B && mpi_copy(X, B) != 0) + return (-1); + X->neg = 0; + return (0); + } + if (B->msb == 0) { + if (X != A && mpi_copy(X, A) != 0) + return (-1); + X->neg = 0; + return (0); } - if (A->msb == 0) - return (X == B ? 0 : mpi_copy(X, B)); - if (B->msb == 0) - return (X == A ? 0 : mpi_copy(X, A)); /* * Normalize our operands: if X is identical to either A or B, we diff --git a/lib/mpi/cryb_mpi_sub_abs.c b/lib/mpi/cryb_mpi_sub_abs.c index 58696e0..32d950f 100644 --- a/lib/mpi/cryb_mpi_sub_abs.c +++ b/lib/mpi/cryb_mpi_sub_abs.c @@ -54,10 +54,18 @@ mpi_sub_abs(cryb_mpi *X, cryb_mpi *A, cryb_mpi *B) mpi_zero(X); return (0); } - if (A->msb == 0) - return (X == B ? 0 : mpi_copy(X, B)); - if (B->msb == 0) - return (X == A ? 0 : mpi_copy(X, A)); + if (A->msb == 0) { + if (X != B && mpi_copy(X, B) != 0) + return (-1); + X->neg = 0; + return (0); + } + if (B->msb == 0) { + if (X != A && mpi_copy(X, A) != 0) + return (-1); + X->neg = 0; + return (0); + } /* we want to subtract the smaller number from the larger */ if (mpi_cmp_abs(A, B) < 0) diff --git a/t/t_mpi_addsub.c b/t/t_mpi_addsub.c index 690723f..5fb78c5 100644 --- a/t/t_mpi_addsub.c +++ b/t/t_mpi_addsub.c @@ -60,28 +60,46 @@ static struct t_add_case { int eneg:1; } t_add_cases[] = { { - "0 + 0 == 0", + "|0| + |0| == 0", { }, 0, 0, { }, 0, 0, { }, 0, 0, }, { - "0 + 1 == 1", + "|0| + |1| == 1", { }, 0, 0, { 0x01, }, 1, 0, { 0x01, }, 1, 0, }, { - "1 + 0 == 1", + "|1| + |0| == 1", { 0x01, }, 1, 0, { }, 0, 0, { 0x01, }, 1, 0, }, { - "2 + 2 == 4", + "|1| + |1| == 2", + { 0x01, }, 1, 0, + { 0x01 }, 1, 0, { 0x02, }, 2, 0, + }, + { + "|0| + |-1| == 1", + { }, 0, 0, + { 0x01, }, 1, 1, + { 0x01, }, 1, 0, + }, + { + "|-1| + |0| == 1", + { 0x01, }, 1, 1, + { }, 0, 0, + { 0x01, }, 1, 0, + }, + { + "|-1| + |-1| == 2", + { 0x01, }, 1, 1, + { 0x01 }, 1, 1, { 0x02, }, 2, 0, - { 0x04, }, 3, 0, }, { "|0x20140901| + |0x19700101| == 0x39840a02", @@ -109,14 +127,14 @@ static struct t_add_case { }, { "simple carry, " - "0xffffffff + 0x01 == 0x0100000000", + "|0xffffffff| + |0x01| == 0x0100000000", { 0xff, 0xff, 0xff, 0xff, }, 32, 0, { 0x01, }, 1, 0, { 0x01, 0x00, 0x00, 0x00, 0x00, }, 33, 0, }, { "complex carry, " - "0x0100000000ffffffff + 0x01 == 0x010000000100000000", + "|0x0100000000ffffffff| + |0x01| == 0x010000000100000000", { 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, }, 64, 0, { 0x01, }, 1, 0, { 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, }, 64, 0, @@ -478,37 +496,55 @@ static struct t_sub_case { int eneg:1; } t_sub_cases[] = { { - "0 - 0 == 0", + "| |0| - |0| | == 0", { }, 0, 0, { }, 0, 0, { }, 0, 0, }, { - "0 - 1 == 1", + "| |0| - |1| | == 1", { }, 0, 0, { 0x01, }, 1, 0, { 0x01, }, 1, 0, }, { - "1 - 0 == 1", + "| |1| - |0| | == 1", { 0x01, }, 1, 0, { }, 0, 0, { 0x01, }, 1, 0, }, { - "1 - 1 == 0", + "| |1| - |1| | == 0", { 0x01, }, 1, 0, + { 0x01 }, 1, 0, + { 0x02, }, 0, 0, + }, + { + "| |0| - |-1| | == 1", + { }, 0, 0, + { 0x01, }, 1, 1, { 0x01, }, 1, 0, + }, + { + "| |-1| - |0| | == 1", + { 0x01, }, 1, 1, + { }, 0, 0, + { 0x01, }, 1, 0, + }, + { + "| |-1| - |-1| | == 0", + { 0x01, }, 1, 1, + { 0x01 }, 1, 1, { }, 0, 0, }, { - "4 - 2 == 2", + "| |4| - |2| | == 2", { 0x04, }, 3, 0, { 0x02, }, 2, 0, { 0x02, }, 2, 0, }, { - "2 - 4 == 2", + "| |2| - |4| | == 2", { 0x02, }, 2, 0, { 0x04, }, 3, 0, { 0x02, }, 2, 0,