mirror of
https://github.com/crosstool-ng/crosstool-ng.git
synced 2025-01-02 02:56:40 +00:00
165 lines
5.6 KiB
Diff
165 lines
5.6 KiB
Diff
|
|
||
|
# HG changeset patch
|
||
|
# User Torbjorn Granlund <tege@gmplib.org>
|
||
|
# Date 1373624469 -7200
|
||
|
# Node ID a447c0c537891ed23edf180594a89616364ee633
|
||
|
# Parent 6540e0b2925ead29f7158bb182e4fabfb9441433
|
||
|
Partial rewrite.
|
||
|
|
||
|
diff -r 6540e0b2925e -r a447c0c53789 mpn/generic/sbpi1_div_sec.c
|
||
|
--- a/mpn/generic/sbpi1_div_sec.c Mon Jul 01 19:16:32 2013 +0200
|
||
|
+++ b/mpn/generic/sbpi1_div_sec.c Fri Jul 12 12:21:09 2013 +0200
|
||
|
@@ -8,7 +8,7 @@
|
||
|
SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
|
||
|
GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
|
||
|
|
||
|
-Copyright 2011, 2012 Free Software Foundation, Inc.
|
||
|
+Copyright 2011, 2012, 2013 Free Software Foundation, Inc.
|
||
|
|
||
|
This file is part of the GNU MP Library.
|
||
|
|
||
|
@@ -29,6 +29,28 @@
|
||
|
#include "gmp-impl.h"
|
||
|
#include "longlong.h"
|
||
|
|
||
|
+/* This side-channel silent division algorithm reduces the partial remainder by
|
||
|
+ GMP_NUMB_BITS/2 bits at a time, compared to GMP_NUMB_BITS for the main
|
||
|
+ division algorithm. We do not insists on reducing by exactly
|
||
|
+ GMP_NUMB_BITS/2, but may leave a partial remainder that is D*B^i to 3D*B^i
|
||
|
+ too large (B is the limb base, D is the divisor, and i is the induction
|
||
|
+ variable); the subsequent step will handle the extra partial remainder bits.
|
||
|
+
|
||
|
+ WIth that partial remainder reduction, each step generates a quotient "half
|
||
|
+ limb". The outer loop generates two quotient half limbs, an upper (q1h) and
|
||
|
+ a lower (q0h) which are stored sparsely in separate limb arrays. These
|
||
|
+ arrays are added at the end; using separate arrays avoids data-dependent
|
||
|
+ carry propagation which could else pose a side-channel leakage problem.
|
||
|
+
|
||
|
+ The quotient half limbs may be between -3 to 0 from the accurate value
|
||
|
+ ("accurate" being the one which corresponds to a reduction to a principal
|
||
|
+ partial remainder). Too small quotient half limbs correspond to too large
|
||
|
+ remainders, which we reduce later, as described above.
|
||
|
+
|
||
|
+ In order to keep quotients from getting too big, corresponding to a negative
|
||
|
+ partial remainder, we use an inverse which is sligtly smaller than usually.
|
||
|
+*/
|
||
|
+
|
||
|
#if OPERATION_sbpi1_div_qr_sec
|
||
|
/* Needs (dn + 1) + (nn - dn) + (nn - dn) = 2nn - dn + 1 limbs at tp. */
|
||
|
#define FNAME mpn_sbpi1_div_qr_sec
|
||
|
@@ -49,7 +71,7 @@
|
||
|
mp_limb_t dinv,
|
||
|
mp_ptr tp)
|
||
|
{
|
||
|
- mp_limb_t nh, cy, q1h, q0h, dummy, h;
|
||
|
+ mp_limb_t nh, cy, q1h, q0h, dummy, cnd;
|
||
|
mp_size_t i;
|
||
|
mp_ptr hp;
|
||
|
#if OPERATION_sbpi1_div_qr_sec
|
||
|
@@ -72,77 +94,69 @@
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
+ /* Decremenet inverse to keep quotient half limbs from being too large. */
|
||
|
+ dinv -= dinv != 0; /* FIXME: cmp-to-int */
|
||
|
+
|
||
|
/* Create a divisor copy shifted half a limb. */
|
||
|
hp = tp; /* (dn + 1) limbs */
|
||
|
- cy = mpn_lshift (hp, dp, dn, GMP_NUMB_BITS / 2);
|
||
|
- hp[dn] = dp[dn - 1] >> GMP_NUMB_BITS / 2;
|
||
|
+ hp[dn] = mpn_lshift (hp, dp, dn, GMP_NUMB_BITS / 2);
|
||
|
|
||
|
#if OPERATION_sbpi1_div_qr_sec
|
||
|
qlp = tp + (dn + 1); /* (nn - dn) limbs */
|
||
|
qhp = tp + (nn + 1); /* (nn - dn) limbs */
|
||
|
#endif
|
||
|
|
||
|
- np += nn;
|
||
|
+ np += nn - dn;
|
||
|
+ nh = 0;
|
||
|
|
||
|
- /* Main loop. Develop one full limb per iteration, but do it in two steps in
|
||
|
- order to avoid conditionals. Quotient bits will be either correct or
|
||
|
- underestimates. When a quotient is underestimated, the next quotient will
|
||
|
- compensate, since quotients are to be added at consecutive weight distance
|
||
|
- GMP_NUMB_BITS/2. We make two quotient arrays, each with GMP_NUMB_BITS/2+2
|
||
|
- bits per entry. The arrays are added late after the loop. Separate
|
||
|
- arrays avoid data-dependent carry propagation. */
|
||
|
- nh = 0;
|
||
|
for (i = nn - dn - 1; i >= 0; i--)
|
||
|
{
|
||
|
np--;
|
||
|
|
||
|
- nh = (nh << GMP_NUMB_BITS/2) + (np[0] >> GMP_NUMB_BITS/2);
|
||
|
+ nh = (nh << GMP_NUMB_BITS/2) + (np[dn] >> GMP_NUMB_BITS/2);
|
||
|
umul_ppmm (q1h, dummy, nh, dinv);
|
||
|
q1h += nh;
|
||
|
#if OPERATION_sbpi1_div_qr_sec
|
||
|
qhp[i] = q1h;
|
||
|
#endif
|
||
|
- cy = mpn_submul_1 (np - dn, hp, dn + 1, q1h);
|
||
|
+ mpn_submul_1 (np, hp, dn + 1, q1h);
|
||
|
|
||
|
- nh = np[0];
|
||
|
+ nh = np[dn];
|
||
|
umul_ppmm (q0h, dummy, nh, dinv);
|
||
|
q0h += nh;
|
||
|
#if OPERATION_sbpi1_div_qr_sec
|
||
|
qlp[i] = q0h;
|
||
|
#endif
|
||
|
- cy = mpn_submul_1 (np - dn, dp, dn, q0h);
|
||
|
-
|
||
|
- nh -= cy;
|
||
|
+ nh -= mpn_submul_1 (np, dp, dn, q0h);
|
||
|
}
|
||
|
|
||
|
- np[0] = nh;
|
||
|
-
|
||
|
- np -= dn;
|
||
|
-
|
||
|
/* 1st adjustment depends on extra high remainder limb. */
|
||
|
- h = np[dn];
|
||
|
+ cnd = nh != 0; /* FIXME: cmp-to-int */
|
||
|
#if OPERATION_sbpi1_div_qr_sec
|
||
|
- qlp[0] += h;
|
||
|
+ qlp[0] += cnd;
|
||
|
#endif
|
||
|
- h -= mpn_subcnd_n (np, np, dp, dn, h);
|
||
|
+ nh -= mpn_subcnd_n (np, np, dp, dn, cnd);
|
||
|
|
||
|
- /* 2nd adjustment depends on remainder/divisor comparision as well as whether
|
||
|
+ /* 2nd adjustment depends on remainder/divisor comparison as well as whether
|
||
|
extra remainder limb was nullified by previous subtract. */
|
||
|
cy = mpn_sub_n (np, np, dp, dn);
|
||
|
- cy = cy == h; /* FIXME: might leak on some archs */
|
||
|
+ cy = cy - nh;
|
||
|
#if OPERATION_sbpi1_div_qr_sec
|
||
|
- qlp[0] += cy;
|
||
|
+ qlp[0] += 1 - cy;
|
||
|
#endif
|
||
|
- mpn_addcnd_n (np, np, dp, dn, 1 - cy);
|
||
|
+ mpn_addcnd_n (np, np, dp, dn, cy);
|
||
|
|
||
|
+ /* 3rd adjustment depends on remainder/divisor comparison. */
|
||
|
+ cy = mpn_sub_n (np, np, dp, dn);
|
||
|
+#if OPERATION_sbpi1_div_qr_sec
|
||
|
+ qlp[0] += 1 - cy;
|
||
|
+#endif
|
||
|
+ mpn_addcnd_n (np, np, dp, dn, cy);
|
||
|
+
|
||
|
+#if OPERATION_sbpi1_div_qr_sec
|
||
|
/* Combine quotient halves into final quotient. */
|
||
|
-#if OPERATION_sbpi1_div_qr_sec
|
||
|
- qh = 0;
|
||
|
- if (nn - dn != 0)
|
||
|
- {
|
||
|
- qh = mpn_lshift (qhp, qhp, nn - dn, GMP_NUMB_BITS/2);
|
||
|
- qh += mpn_add_n (qp, qhp, qlp, nn - dn);
|
||
|
- }
|
||
|
+ qh = mpn_lshift (qhp, qhp, nn - dn, GMP_NUMB_BITS/2);
|
||
|
+ qh += mpn_add_n (qp, qhp, qlp, nn - dn);
|
||
|
|
||
|
return qh;
|
||
|
#else
|
||
|
|