Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / nettle / umac-poly128.c
blob0c0f0a73c1495ba24486d06abe2d7e83bec2ee2d
1 /* umac-poly128.c
2 */
4 /* nettle, low-level cryptographics library
6 * Copyright (C) 2013 Niels Möller
8 * The nettle library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or (at your
11 * option) any later version.
13 * The nettle library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 * License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with the nettle library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02111-1301, USA.
24 #if HAVE_CONFIG_H
25 # include "config.h"
26 #endif
28 #include <assert.h>
30 #include "umac.h"
32 #define HI(x) (x >> 32)
33 #define LO(x) (x & 0xffffffffUL)
35 static void
36 poly128_mul (const uint32_t *k, uint64_t *y)
38 uint64_t y0,y1,y2,y3,p0,p1,p2,p3,m0,m1,m2;
39 y0 = LO (y[1]);
40 y1 = HI (y[1]);
41 y2 = LO (y[0]);
42 y3 = HI (y[0]);
44 p0 = y0 * k[3];
45 m0 = y0 * k[2] + y1 * k[3];
46 p1 = y0 * k[1] + y1 * k[2] + y2 * k[3];
47 m1 = y0 * k[0] + y1 * k[1] + y2 * k[2] + y3 * k[3];
48 p2 = y1 * k[0] + y2 * k[1] + y3 * k[2];
49 m2 = y2 * k[0] + y3 * k[1];
50 p3 = y3 * k[0];
52 /* Collaps to 4 64-bit words,
53 +---+---+---+---+
54 | p3| p2| p1| p0|
55 +-+-+-+-+-+-+-+-+
56 + | m2| m1| m0|
57 -+-+-+-+-+-+-+-+-+
59 /* But it's convenient to reduce (p3,p2,p1,p0) and (m2,m1,m0) mod p first.*/
60 m1 += UMAC_P128_OFFSET * HI(p3);
61 p1 += UMAC_P128_OFFSET * (LO(p3) + HI(m2));
62 m0 += UMAC_P128_OFFSET * (HI(p2) + LO(m2));
63 p0 += UMAC_P128_OFFSET * (LO(p2) + HI(m1));
65 /* Left to add
66 +---+---+
67 | p1| p0|
68 +-+-+-+-+
69 m1| m0|
70 +-+---+
72 /* First add high parts, with no possibilities for carries */
73 p1 += m0 >> 32;
75 m0 <<= 32;
76 m1 <<= 32;
78 /* Remains:
79 +---+---+
80 | p1| p0|
81 +-+-+---+
82 +| m1| m0|
83 -+---+---+
85 p0 += m0;
86 p1 += (p0 < m0);
87 p1 += m1;
88 if (p1 < m1)
90 p0 += UMAC_P128_OFFSET;
91 p1 += (p0 < UMAC_P128_OFFSET);
94 y[0] = p1;
95 y[1] = p0;
98 void
99 _umac_poly128 (const uint32_t *k, uint64_t *y, uint64_t mh, uint64_t ml)
101 uint64_t yh, yl, cy;
103 if ( (mh >> 32) == 0xffffffff)
105 poly128_mul (k, y);
106 if (y[1] > 0)
107 y[1]--;
108 else if (y[0] > 0)
110 y[0]--;
111 y[1] = UMAC_P128_HI;
113 else
115 y[0] = UMAC_P128_HI;
116 y[1] = UMAC_P128_LO-1;
119 mh -= (ml < UMAC_P128_OFFSET);
120 ml -= UMAC_P128_OFFSET;
122 assert (mh < UMAC_P128_HI || ml < UMAC_P128_LO);
124 poly128_mul (k, y);
125 yl = y[1] + ml;
126 cy = (yl < ml);
127 yh = y[0] + cy;
128 cy = (yh < cy);
129 yh += mh;
130 cy += (yh < mh);
131 assert (cy <= 1);
132 if (cy)
134 yl += UMAC_P128_OFFSET;
135 yh += yl < UMAC_P128_OFFSET;
138 y[0] = yh;
139 y[1] = yl;