Annotation of embedaddon/strongswan/src/libstrongswan/plugins/newhope/newhope_reconciliation.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2016 Andreas Steffen
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * Based on public domain code by Erdem Alkim, Léo Ducas, Thomas Pöppelmann,
6: * and Peter Schwabe.
7: *
8: * This program is free software; you can redistribute it and/or modify it
9: * under the terms of the GNU General Public License as published by the
10: * Free Software Foundation; either version 2 of the License, or (at your
11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12: *
13: * This program 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 General Public License
16: * for more details.
17: *
18: */
19:
20: #include "newhope_reconciliation.h"
21:
22: typedef struct private_newhope_reconciliation_t private_newhope_reconciliation_t;
23:
24: /**
25: * Private data of an newhope_reconciliation_t object.
26: */
27: struct private_newhope_reconciliation_t {
28:
29: /**
30: * Public newhope_reconciliation_t interface.
31: */
32: newhope_reconciliation_t public;
33:
34: /**
35: * Array sizes
36: */
37: int n, n4;
38:
39: /**
40: * Multiples of modulus q
41: */
42: int32_t q, q2, q4, q8, q16;
43: };
44:
45:
46: static inline int32_t rec_abs(int32_t v)
47: {
48: int32_t mask = v >> 31;
49:
50: return (v ^ mask) - mask;
51: }
52:
53: /**
54: * Auxiliary function used by help_reconcile() method
55: */
56: static int32_t rec_f(private_newhope_reconciliation_t *this,
57: int32_t v, uint8_t r, int32_t *v0, int32_t *v1)
58: {
59: int32_t x, xit, t, b;
60:
61: x = 8 * v + 2 * r;
62:
63: /* compute t = x/q */
64: b = x * 2730;
65: t = b >> 25;
66: b = x - t * this->q;
67: b = this->q - 1 - b;
68: b >>= 31;
69: t -= b;
70:
71: r = t & 0x01;
72: xit = (t >> 1);
73: *v0 = xit + r ; /* v0 = round(x/(2q)) */
74:
75: t -= 1;
76: r = t & 0x01;
77: *v1 = ( t>> 1) + r;
78:
79: return rec_abs(x - (*v0) * this->q2);
80: }
81:
82: /**
83: * Auxiliary function used by reconcile() method
84: */
85: static int32_t rec_g(private_newhope_reconciliation_t *this, int32_t x)
86: {
87: int32_t t, r, b;
88:
89: /* t = x/(4*q) */
90: b = x * 2730;
91: t = b >> 27;
92: b = x - t * this->q4;
93: b = this->q4 - 1 - b;
94: b >>= 31;
95: t -= b;
96:
97: r = t & 0x01;
98: t = (t >> 1) + r; /* t = round(x/(8q)) */
99: t *= this->q8;
100:
101: return abs(t - x);
102: }
103:
104: METHOD(newhope_reconciliation_t, help_reconcile, uint8_t*,
105: private_newhope_reconciliation_t *this, uint32_t *v, uint8_t *rbits)
106: {
107: int32_t v0[4], v1[4], v_tmp[4], k;
108: int i, i0, i1, i2, i3, j;
109: uint8_t *r, rbit;
110:
111: /* allocate output vector */
112: r = (uint8_t*)malloc(this->n);
113:
114: for (i = 0; i < this->n4/8; i++)
115: {
116: for (j = 0; j < 8; j++)
117: {
118: i0 = 8*i + j;
119: i1 = i0 + this->n4;
120: i2 = i1 + this->n4;
121: i3 = i2 + this->n4;
122:
123: /* iterate through all 256 random bits */
124: rbit = (rbits[i] >> j) & 0x01;
125:
126: k = rec_f(this, v[i0], rbit, &v0[0], &v1[0]);
127: k += rec_f(this, v[i1], rbit, &v0[1], &v1[1]);
128: k += rec_f(this, v[i2], rbit, &v0[2], &v1[2]);
129: k += rec_f(this, v[i3], rbit, &v0[3], &v1[3]);
130:
131: k = (this->q2 - 1 - k) >> 31;
132:
133: v_tmp[0] = ((~k) & v0[0]) ^ (k & v1[0]);
134: v_tmp[1] = ((~k) & v0[1]) ^ (k & v1[1]);
135: v_tmp[2] = ((~k) & v0[2]) ^ (k & v1[2]);
136: v_tmp[3] = ((~k) & v0[3]) ^ (k & v1[3]);
137:
138: r[i0] = (v_tmp[0] - v_tmp[3]) & 0x03;
139: r[i1] = (v_tmp[1] - v_tmp[3]) & 0x03;
140: r[i2] = (v_tmp[2] - v_tmp[3]) & 0x03;
141: r[i3] = (v_tmp[3] - k + v_tmp[3]) & 0x03;
142: }
143: }
144:
145: return r;
146: }
147:
148: METHOD(newhope_reconciliation_t, reconcile, chunk_t,
149: private_newhope_reconciliation_t *this, uint32_t *v, uint8_t *r)
150: {
151: size_t key_len;
152: uint8_t *key;
153: int32_t tmp[4], t;
154: int i, i0, i1, i2, i3, j;
155:
156: key_len = this->n4 / 8;
157: key = (uint8_t*)malloc(key_len);
158: memset(key, 0x00, key_len);
159:
160: for (i = 0; i < key_len; i++)
161: {
162: for (j = 0; j < 8; j++)
163: {
164: i0 = 8*i + j;
165: i1 = i0 + this->n4;
166: i2 = i1 + this->n4;
167: i3 = i2 + this->n4;
168:
169: tmp[0] = this->q16 + 8 * (int32_t)v[i0] -
170: this->q * (2*r[i0] + r[i3]);
171: tmp[1] = this->q16 + 8 * (int32_t)v[i1] -
172: this->q * (2*r[i1] + r[i3]);
173: tmp[2] = this->q16 + 8 * (int32_t)v[i2] -
174: this->q * (2*r[i2] + r[i3]);
175: tmp[3] = this->q16 + 8 * (int32_t)v[i3] -
176: this->q * ( r[i3]);
177:
178: t = rec_g(this, tmp[0]) + rec_g(this, tmp[1]) +
179: rec_g(this, tmp[2]) + rec_g(this, tmp[3]) - this->q8;
180:
181: key[i] |= ((t >> 31) & 0x01) << j;
182: }
183: }
184:
185: return chunk_create(key, key_len);
186: }
187:
188: METHOD(newhope_reconciliation_t, destroy, void,
189: private_newhope_reconciliation_t *this)
190: {
191: free(this);
192: }
193:
194: /*
195: * Described in header.
196: */
197: newhope_reconciliation_t *newhope_reconciliation_create(int n, int32_t q)
198: {
199: private_newhope_reconciliation_t *this;
200:
201: INIT(this,
202: .public = {
203: .help_reconcile = _help_reconcile,
204: .reconcile = _reconcile,
205: .destroy = _destroy,
206: },
207: .n = n,
208: .n4 = n / 4,
209: .q = q,
210: .q2 = 2 * q,
211: .q4 = 4 * q,
212: .q8 = 8 * q,
213: .q16 = 16 * q,
214: );
215:
216: return &this->public;
217: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>