2 * Copyright (C) 2016 Andreas Steffen
4 * Based on public domain code by Erdem Alkim, Léo Ducas, Thomas Pöppelmann,
7 * Copyright (C) secunet Security Networks AG
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 #include "newhope_reconciliation.h"
23 typedef struct private_newhope_reconciliation_t private_newhope_reconciliation_t
;
26 * Private data of an newhope_reconciliation_t object.
28 struct private_newhope_reconciliation_t
{
31 * Public newhope_reconciliation_t interface.
33 newhope_reconciliation_t
public;
41 * Multiples of modulus q
43 int32_t q
, q2
, q4
, q8
, q16
;
47 static inline int32_t rec_abs(int32_t v
)
49 int32_t mask
= v
>> 31;
51 return (v
^ mask
) - mask
;
55 * Auxiliary function used by help_reconcile() method
57 static int32_t rec_f(private_newhope_reconciliation_t
*this,
58 int32_t v
, uint8_t r
, int32_t *v0
, int32_t *v1
)
74 *v0
= xit
+ r
; /* v0 = round(x/(2q)) */
80 return rec_abs(x
- (*v0
) * this->q2
);
84 * Auxiliary function used by reconcile() method
86 static int32_t rec_g(private_newhope_reconciliation_t
*this, int32_t x
)
99 t
= (t
>> 1) + r
; /* t = round(x/(8q)) */
105 METHOD(newhope_reconciliation_t
, help_reconcile
, uint8_t*,
106 private_newhope_reconciliation_t
*this, uint32_t *v
, uint8_t *rbits
)
108 int32_t v0
[4], v1
[4], v_tmp
[4], k
;
109 int i
, i0
, i1
, i2
, i3
, j
;
112 /* allocate output vector */
113 r
= (uint8_t*)malloc(this->n
);
115 for (i
= 0; i
< this->n4
/8; i
++)
117 for (j
= 0; j
< 8; j
++)
124 /* iterate through all 256 random bits */
125 rbit
= (rbits
[i
] >> j
) & 0x01;
127 k
= rec_f(this, v
[i0
], rbit
, &v0
[0], &v1
[0]);
128 k
+= rec_f(this, v
[i1
], rbit
, &v0
[1], &v1
[1]);
129 k
+= rec_f(this, v
[i2
], rbit
, &v0
[2], &v1
[2]);
130 k
+= rec_f(this, v
[i3
], rbit
, &v0
[3], &v1
[3]);
132 k
= (this->q2
- 1 - k
) >> 31;
134 v_tmp
[0] = ((~k
) & v0
[0]) ^ (k
& v1
[0]);
135 v_tmp
[1] = ((~k
) & v0
[1]) ^ (k
& v1
[1]);
136 v_tmp
[2] = ((~k
) & v0
[2]) ^ (k
& v1
[2]);
137 v_tmp
[3] = ((~k
) & v0
[3]) ^ (k
& v1
[3]);
139 r
[i0
] = (v_tmp
[0] - v_tmp
[3]) & 0x03;
140 r
[i1
] = (v_tmp
[1] - v_tmp
[3]) & 0x03;
141 r
[i2
] = (v_tmp
[2] - v_tmp
[3]) & 0x03;
142 r
[i3
] = (v_tmp
[3] - k
+ v_tmp
[3]) & 0x03;
149 METHOD(newhope_reconciliation_t
, reconcile
, chunk_t
,
150 private_newhope_reconciliation_t
*this, uint32_t *v
, uint8_t *r
)
155 int i
, i0
, i1
, i2
, i3
, j
;
157 key_len
= this->n4
/ 8;
158 key
= (uint8_t*)malloc(key_len
);
159 memset(key
, 0x00, key_len
);
161 for (i
= 0; i
< key_len
; i
++)
163 for (j
= 0; j
< 8; j
++)
170 tmp
[0] = this->q16
+ 8 * (int32_t)v
[i0
] -
171 this->q
* (2*r
[i0
] + r
[i3
]);
172 tmp
[1] = this->q16
+ 8 * (int32_t)v
[i1
] -
173 this->q
* (2*r
[i1
] + r
[i3
]);
174 tmp
[2] = this->q16
+ 8 * (int32_t)v
[i2
] -
175 this->q
* (2*r
[i2
] + r
[i3
]);
176 tmp
[3] = this->q16
+ 8 * (int32_t)v
[i3
] -
179 t
= rec_g(this, tmp
[0]) + rec_g(this, tmp
[1]) +
180 rec_g(this, tmp
[2]) + rec_g(this, tmp
[3]) - this->q8
;
182 key
[i
] |= ((t
>> 31) & 0x01) << j
;
186 return chunk_create(key
, key_len
);
189 METHOD(newhope_reconciliation_t
, destroy
, void,
190 private_newhope_reconciliation_t
*this)
196 * Described in header.
198 newhope_reconciliation_t
*newhope_reconciliation_create(int n
, int32_t q
)
200 private_newhope_reconciliation_t
*this;
204 .help_reconcile
= _help_reconcile
,
205 .reconcile
= _reconcile
,
217 return &this->public;