1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/**
* @file p448/f_generic.c
* @author Mike Hamburg
*
* @copyright
* Copyright (c) 2015-2016 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
*
* @brief Generic arithmetic which has to be compiled per field.
*
* @warning This file was automatically generated in Python.
* Please do not edit it.
*/
#include "field.h"
static const gf MODULUS = {FIELD_LITERAL(
0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff, 0xfffffffffffffe, 0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff
)};
#if P_MOD_8 == 5
const gf SQRT_MINUS_ONE = {FIELD_LITERAL(
/* NOPE */
)};
#endif
/** Serialize to wire format. */
void cryptonite_gf_serialize (uint8_t serial[SER_BYTES], const gf x, int with_hibit) {
gf red;
cryptonite_gf_copy(red, x);
cryptonite_gf_strong_reduce(red);
if (!with_hibit) { assert(cryptonite_gf_hibit(red) == 0); }
unsigned int j=0, fill=0;
dword_t buffer = 0;
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));
j++;
}
serial[i] = buffer;
fill -= 8;
buffer >>= 8;
}
}
/** Return high bit of x = low bit of 2x mod p */
mask_t cryptonite_gf_hibit(const gf x) {
gf y;
cryptonite_gf_add(y,x,x);
cryptonite_gf_strong_reduce(y);
return -(y->limb[0]&1);
}
/** Deserialize from wire format; return -1 on success and 0 on failure. */
mask_t cryptonite_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 < (with_hibit ? X_SER_BYTES : SER_BYTES)) {
buffer |= ((dword_t)serial[j]) << fill;
fill += 8;
j++;
}
x->limb[LIMBPERM(i)] = (i<NLIMBS-1) ? buffer & LIMB_MASK(LIMBPERM(i)) : buffer;
fill -= LIMB_PLACE_VALUE(LIMBPERM(i));
buffer >>= LIMB_PLACE_VALUE(LIMBPERM(i));
scarry = (scarry + x->limb[LIMBPERM(i)] - MODULUS->limb[LIMBPERM(i)]) >> (8*sizeof(word_t));
}
mask_t succ = with_hibit ? -(mask_t)1 : ~cryptonite_gf_hibit(x);
return succ & word_is_zero(buffer) & ~word_is_zero(scarry);
}
/** Reduce to canonical form. */
void cryptonite_gf_strong_reduce (gf a) {
/* first, clear high */
cryptonite_gf_weak_reduce(a); /* Determined to have negligible perf impact. */
/* now the total is less than 2p */
/* compute total_value - p. No need to reduce mod p. */
dsword_t scarry = 0;
for (unsigned int i=0; i<NLIMBS; i++) {
scarry = scarry + a->limb[LIMBPERM(i)] - MODULUS->limb[LIMBPERM(i)];
a->limb[LIMBPERM(i)] = scarry & LIMB_MASK(LIMBPERM(i));
scarry >>= LIMB_PLACE_VALUE(LIMBPERM(i));
}
/* uncommon case: it was >= p, so now scarry = 0 and this = x
* common case: it was < p, so now scarry = -1 and this = x - p + 2^255
* so let's add back in p. will carry back off the top for 2^255.
*/
assert(word_is_zero(scarry) | word_is_zero(scarry+1));
word_t scarry_0 = scarry;
dword_t carry = 0;
/* add it back */
for (unsigned int i=0; i<NLIMBS; i++) {
carry = carry + a->limb[LIMBPERM(i)] + (scarry_0 & MODULUS->limb[LIMBPERM(i)]);
a->limb[LIMBPERM(i)] = carry & LIMB_MASK(LIMBPERM(i));
carry >>= LIMB_PLACE_VALUE(LIMBPERM(i));
}
assert(word_is_zero(carry + scarry_0));
}
/** Subtract two gf elements d=a-b */
void cryptonite_gf_sub (gf d, const gf a, const gf b) {
cryptonite_gf_sub_RAW ( d, a, b );
cryptonite_gf_bias( d, 2 );
cryptonite_gf_weak_reduce ( d );
}
/** Add two field elements d = a+b */
void cryptonite_gf_add (gf d, const gf a, const gf b) {
cryptonite_gf_add_RAW ( d, a, b );
cryptonite_gf_weak_reduce ( d );
}
/** Compare a==b */
mask_t cryptonite_gf_eq(const gf a, const gf b) {
gf c;
cryptonite_gf_sub(c,a,b);
cryptonite_gf_strong_reduce(c);
mask_t ret=0;
for (unsigned int i=0; i<NLIMBS; i++) {
ret |= c->limb[LIMBPERM(i)];
}
return word_is_zero(ret);
}
|