Commit 55766b76 authored by Michael Hamburg's avatar Michael Hamburg

homogenize invsqrt code

parent 08bbb567
......@@ -156,8 +156,8 @@ $$(BUILD_OBJ)/$(1)/%.o: src/$(1)/%.c $$(HEADERS_OF_$(1))
$$(BUILD_OBJ)/$(1)/%.o: src/$(1)/$$(ARCH_FOR_$(1))/%.c $$(HEADERS_OF_$(1))
$$(CC) $$(CFLAGS) -I src/$(1) -I src/$(1)/$$(ARCH_FOR_$(1)) -I $(BUILD_H)/$(1) \
-I $(BUILD_H)/$(1)/$$(ARCH_FOR_$(1)) -I src/include/$$(ARCH_FOR_$(1)) \
-c -o $$@ $$<
-I $(BUILD_H)/$(1)/$$(ARCH_FOR_$(1)) -I src/include/$$(ARCH_FOR_$(1)) \
-c -o $$@ $$<
endef
################################################################
......
......@@ -84,7 +84,6 @@ def ceil_log2(x):
out += 1
return out
# TODO: reduce this because we can now have expressions.
for field,data in field_data.iteritems():
if "modulus" not in data:
data["modulus"] = eval(data["gf_desc"].replace("^","**"))
......
......@@ -12,21 +12,40 @@
#include "constant_time.h"
/* Guarantee: a^2 x = 0 if x = 0; else a^2 x = 1 or SQRT_MINUS_ONE; */
void gf_isr (gf a, const gf x) {
gf st[3], tmp1, tmp2;
const struct { unsigned char sh, idx; } ops[] = {
{1,2},{1,2},{3,1},{6,0},{1,2},{12,1},{25,1},{25,1},{50,0},{125,0},{2,2},{1,2}
};
st[0][0] = st[1][0] = st[2][0] = x[0];
unsigned int i;
for (i=0; i<sizeof(ops)/sizeof(ops[0]); i++) {
gf_sqrn(tmp1, st[1^(i&1)], ops[i].sh);
gf_mul(tmp2, tmp1, st[ops[i].idx]);
st[i&1][0] = tmp2[0];
}
mask_t gf_isr (gf a, const gf x) {
gf L0, L1, L2, L3;
mask_t mask = gf_eq(st[1],ONE) | gf_eq(st[1],SQRT_MINUS_ONE);
gf_sqr (L0, x);
gf_mul (L1, L0, x);
gf_sqr (L0, L1);
gf_mul (L1, L0, x);
gf_sqrn(L0, L1, 3);
gf_mul (L2, L0, L1);
gf_sqrn(L0, L2, 6);
gf_mul (L1, L2, L0);
gf_sqr (L2, L1);
gf_mul (L0, L2, x);
gf_sqrn(L2, L0, 12);
gf_mul (L0, L2, L1);
gf_sqrn(L2, L0, 25);
gf_mul (L3, L2, L0);
gf_sqrn(L2, L3, 25);
gf_mul (L1, L2, L0);
gf_sqrn(L2, L1, 50);
gf_mul (L0, L2, L3);
gf_sqrn(L2, L0, 125);
gf_mul (L3, L2, L0);
gf_sqrn(L2, L3, 2);
gf_mul (L0, L2, x);
gf_sqr (L2, L0);
gf_mul (L3, L2, x);
gf_add(L1,L3,ONE);
mask_t one = gf_eq(L3,ONE);
mask_t succ = one | gf_eq(L1,ZERO);
mask_t qr = one | gf_eq(L3,SQRT_MINUS_ONE);
constant_time_select(tmp1, SQRT_MINUS_ONE, ONE, sizeof(tmp1), mask, 0);
gf_mul(a,tmp1,st[0]);
constant_time_select(L2, SQRT_MINUS_ONE, ONE, sizeof(L2), qr, 0);
gf_mul (a,L2,L0);
return succ;
}
......@@ -10,8 +10,7 @@
#include "field.h"
void
gf_isr (
mask_t gf_isr (
gf a,
const gf x
) {
......@@ -39,5 +38,9 @@ gf_isr (
gf_sqr (L0, L2 );
gf_mul (L1, x, L0 );
gf_sqrn (L0, L1, 223 );
gf_mul ( a, L2, L0 );
gf_mul (L1, L2, L0 );
gf_sqr (L2, L1);
gf_mul (L0, L2, x);
gf_copy(a,L1);
return gf_eq(L0,ONE);
}
This diff is collapsed.
......@@ -26,12 +26,12 @@ void API_NS(precompute_wnafs) (
const API_NS(point_t) base
);
static void field_print(const gf f) { /* UNIFY */
unsigned char ser[SER_BYTES];
gf_serialize(ser,f);
unsigned char ser[X_SER_BYTES];
gf_serialize(ser,f,1);
int b=0, i, comma=0;
unsigned long long limb = 0;
printf("{FIELD_LITERAL(");
for (i=0; i<SER_BYTES; i++) {
for (i=0; i<X_SER_BYTES; i++) {
limb |= ((uint64_t)ser[i])<<b;
b += 8;
if (b >= GF_LIT_LIMB_BITS || i == SER_BYTES-1) {
......
......@@ -8,7 +8,8 @@
#define __DECAF_$(gf_shortname)_GF_DEFINED__ 1
#define NLIMBS ($(gf_impl_bits/8)/sizeof(word_t))
#define SER_BYTES $(((gf_bits-1)//8 + 1)) /* MAGIC: depends on if high bit known to be clear (eg p521) */
#define X_SER_BYTES $(((gf_bits-1)/8 + 1))
#define SER_BYTES $(((gf_bits-2)/8 + 1))
typedef struct gf_$(gf_shortname)_s {
word_t limb[NLIMBS];
} __attribute__((aligned(32))) gf_$(gf_shortname)_s, gf_$(gf_shortname)_t[1];
......@@ -21,6 +22,7 @@ typedef struct gf_$(gf_shortname)_s {
#define gf gf_$(gf_shortname)_t
#define gf_s gf_$(gf_shortname)_s
#define gf_eq gf_$(gf_shortname)_eq
#define gf_hibit gf_$(gf_shortname)_hibit
#define gf_copy gf_$(gf_shortname)_copy
#define gf_add gf_$(gf_shortname)_add
#define gf_sub gf_$(gf_shortname)_sub
......@@ -37,7 +39,7 @@ typedef struct gf_$(gf_shortname)_s {
#define gf_deserialize gf_$(gf_shortname)_deserialize
/* RFC 7748 support */
#define X_PUBLIC_BYTES $((gf_bits-1)/8 + 1)
#define X_PUBLIC_BYTES X_SER_BYTES
#define X_PRIVATE_BYTES X_PUBLIC_BYTES
#define X_PRIVATE_BITS $(gf_bits)
......@@ -62,10 +64,12 @@ void gf_sub (gf out, const gf a, const gf b);
void gf_mul (gf_s *__restrict__ out, const gf a, const gf b);
void gf_mulw (gf_s *__restrict__ out, const gf a, uint32_t b);
void gf_sqr (gf_s *__restrict__ out, const gf a);
void gf_serialize (uint8_t *serial, const gf x);
void gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0 */
mask_t gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0. Return true if successful */
mask_t gf_eq (const gf x, const gf y);
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES]);
mask_t gf_hibit (const gf x);
void gf_serialize (uint8_t *serial, const gf x,int with_highbit);
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES],int with_highbit);
#ifdef __cplusplus
......
......@@ -15,14 +15,15 @@ static const gf MODULUS = {FIELD_LITERAL(
)};
/** Serialize to wire format. */
void gf_serialize (uint8_t serial[SER_BYTES], const gf x) {
void gf_serialize (uint8_t serial[SER_BYTES], const gf x, int with_hibit) {
gf red;
gf_copy(red, x);
gf_strong_reduce(red);
if (!with_hibit) { assert(gf_hibit(red) == 0); }
unsigned int j=0, fill=0;
dword_t buffer = 0;
UNROLL for (unsigned int i=0; i<SER_BYTES; i++) {
UNROLL for (unsigned int i=0; i<(with_hibit ? X_SER_BYTES : SER_BYTES); i++) {
if (fill < 8 && j < NLIMBS) {
buffer |= ((dword_t)red->limb[LIMBPERM(j)]) << fill;
fill += LIMB_PLACE_VALUE(LIMBPERM(j));
......@@ -34,13 +35,21 @@ void gf_serialize (uint8_t serial[SER_BYTES], const gf x) {
}
}
/** Return high bit of x = low bit of 2x mod p */
mask_t gf_hibit(const gf x) {
gf y;
gf_add(y,x,x);
gf_strong_reduce(y);
return -(y->limb[0]&1);
}
/** Deserialize from wire format; return -1 on success and 0 on failure. */
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES]) {
mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES], int with_hibit) {
unsigned int j=0, fill=0;
dword_t buffer = 0;
dsword_t scarry = 0;
UNROLL for (unsigned int i=0; i<NLIMBS; i++) {
UNROLL while (fill < LIMB_PLACE_VALUE(LIMBPERM(i)) && j < SER_BYTES) {
UNROLL while (fill < LIMB_PLACE_VALUE(LIMBPERM(i)) && j < (with_hibit ? X_SER_BYTES : SER_BYTES)) {
buffer |= ((dword_t)serial[j]) << fill;
fill += 8;
j++;
......@@ -50,7 +59,8 @@ mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES]) {
buffer >>= LIMB_PLACE_VALUE(LIMBPERM(i));
scarry = (scarry + x->limb[LIMBPERM(i)] - MODULUS->limb[LIMBPERM(i)]) >> (8*sizeof(word_t));
}
return word_is_zero(buffer) & ~word_is_zero(scarry);
mask_t succ = with_hibit ? -1 : ~gf_hibit(x);
return succ & word_is_zero(buffer) & ~word_is_zero(scarry);
}
/** Reduce to canonical form. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment