version 1.5, 2021/01/08 02:33:13 |
version 1.6, 2023/01/11 02:13:52 |
|
|
Time still varies depending on m; user must ensure that m is constant. |
Time still varies depending on m; user must ensure that m is constant. |
Time also varies on CPUs where multiplication is variable-time. |
Time also varies on CPUs where multiplication is variable-time. |
There could be more CPU issues. |
There could be more CPU issues. |
There could also be compiler issues. |
There could also be compiler issues. |
*/ |
*/ |
|
|
static void uint32_divmod_uint14(uint32 *q,uint16 *r,uint32 x,uint16 m) |
static void uint32_divmod_uint14(uint32 *q,uint16 *r,uint32 x,uint16 m) |
|
|
#ifndef LPR |
#ifndef LPR |
|
|
static Fq Fq_recip(Fq a1) |
static Fq Fq_recip(Fq a1) |
{ |
{ |
int i = 1; |
int i = 1; |
Fq ai = a1; |
Fq ai = a1; |
|
|
|
|
i += 1; |
i += 1; |
} |
} |
return ai; |
return ai; |
} |
} |
|
|
#endif |
#endif |
|
|
|
|
|
|
/* returns 0 if recip succeeded; else -1 */ |
/* returns 0 if recip succeeded; else -1 */ |
static int R3_recip(small *out,const small *in) |
static int R3_recip(small *out,const small *in) |
{ |
{ |
small f[p+1],g[p+1],v[p+1],r[p+1]; |
small f[p+1],g[p+1],v[p+1],r[p+1]; |
int i,loop,delta; |
int i,loop,delta; |
int sign,swap,t; |
int sign,swap,t; |
|
|
for (i = 0;i < p+1;++i) v[i] = 0; |
for (i = 0;i < p+1;++i) v[i] = 0; |
for (i = 0;i < p+1;++i) r[i] = 0; |
for (i = 0;i < p+1;++i) r[i] = 0; |
r[0] = 1; |
r[0] = 1; |
|
|
f[0] = 1; f[p-1] = f[p] = -1; |
f[0] = 1; f[p-1] = f[p] = -1; |
for (i = 0;i < p;++i) g[p-1-i] = in[i]; |
for (i = 0;i < p;++i) g[p-1-i] = in[i]; |
g[p] = 0; |
g[p] = 0; |
|
|
delta = 1; |
|
|
|
|
delta = 1; |
|
|
for (loop = 0;loop < 2*p-1;++loop) { |
for (loop = 0;loop < 2*p-1;++loop) { |
for (i = p;i > 0;--i) v[i] = v[i-1]; |
for (i = p;i > 0;--i) v[i] = v[i-1]; |
v[0] = 0; |
v[0] = 0; |
|
|
sign = -g[0]*f[0]; |
sign = -g[0]*f[0]; |
swap = int16_negative_mask(-delta) & int16_nonzero_mask(g[0]); |
swap = int16_negative_mask(-delta) & int16_nonzero_mask(g[0]); |
delta ^= swap&(delta^-delta); |
delta ^= swap&(delta^-delta); |
delta += 1; |
delta += 1; |
|
|
for (i = 0;i < p+1;++i) { |
for (i = 0;i < p+1;++i) { |
t = swap&(f[i]^g[i]); f[i] ^= t; g[i] ^= t; |
t = swap&(f[i]^g[i]); f[i] ^= t; g[i] ^= t; |
t = swap&(v[i]^r[i]); v[i] ^= t; r[i] ^= t; |
t = swap&(v[i]^r[i]); v[i] ^= t; r[i] ^= t; |
} |
} |
|
|
for (i = 0;i < p+1;++i) g[i] = F3_freeze(g[i]+sign*f[i]); |
for (i = 0;i < p+1;++i) g[i] = F3_freeze(g[i]+sign*f[i]); |
for (i = 0;i < p+1;++i) r[i] = F3_freeze(r[i]+sign*v[i]); |
for (i = 0;i < p+1;++i) r[i] = F3_freeze(r[i]+sign*v[i]); |
|
|
for (i = 0;i < p;++i) g[i] = g[i+1]; |
for (i = 0;i < p;++i) g[i] = g[i+1]; |
g[p] = 0; |
g[p] = 0; |
} |
} |
|
|
sign = f[0]; |
sign = f[0]; |
for (i = 0;i < p;++i) out[i] = sign*v[p-1-i]; |
for (i = 0;i < p;++i) out[i] = sign*v[p-1-i]; |
|
|
return int16_nonzero_mask(delta); |
return int16_nonzero_mask(delta); |
} |
} |
|
|
#endif |
#endif |
|
|
|
|
static void Rq_mult3(Fq *h,const Fq *f) |
static void Rq_mult3(Fq *h,const Fq *f) |
{ |
{ |
int i; |
int i; |
|
|
for (i = 0;i < p;++i) h[i] = Fq_freeze(3*f[i]); |
for (i = 0;i < p;++i) h[i] = Fq_freeze(3*f[i]); |
} |
} |
|
|
/* out = 1/(3*in) in Rq */ |
/* out = 1/(3*in) in Rq */ |
/* returns 0 if recip succeeded; else -1 */ |
/* returns 0 if recip succeeded; else -1 */ |
static int Rq_recip3(Fq *out,const small *in) |
static int Rq_recip3(Fq *out,const small *in) |
{ |
{ |
Fq f[p+1],g[p+1],v[p+1],r[p+1]; |
Fq f[p+1],g[p+1],v[p+1],r[p+1]; |
int i,loop,delta; |
int i,loop,delta; |
int swap,t; |
int swap,t; |
|
|
{ |
{ |
small g[p]; |
small g[p]; |
Fq finv[p]; |
Fq finv[p]; |
|
|
for (;;) { |
for (;;) { |
Small_random(g); |
Small_random(g); |
if (R3_recip(ginv,g) == 0) break; |
if (R3_recip(ginv,g) == 0) break; |
|
|
for (i = 0;i < w;++i) r[i] = ((ev[i]^1)&~mask)^1; |
for (i = 0;i < w;++i) r[i] = ((ev[i]^1)&~mask)^1; |
for (i = w;i < p;++i) r[i] = ev[i]&~mask; |
for (i = w;i < p;++i) r[i] = ev[i]&~mask; |
} |
} |
|
|
#endif |
#endif |
|
|
/* ----- NTRU LPRime Core */ |
/* ----- NTRU LPRime Core */ |
|
|
for (i = 0;i < I;++i) |
for (i = 0;i < I;++i) |
r[i] = -int16_negative_mask(Fq_freeze(Right(T[i])-aB[i]+4*w+1)); |
r[i] = -int16_negative_mask(Fq_freeze(Right(T[i])-aB[i]+4*w+1)); |
} |
} |
|
|
#endif |
#endif |
|
|
/* ----- encoding I-bit inputs */ |
/* ----- encoding I-bit inputs */ |
|
|
} |
} |
|
|
#endif |
#endif |
|
|
/* ----- NTRU LPRime Expand */ |
/* ----- NTRU LPRime Expand */ |
|
|
#ifdef LPR |
#ifdef LPR |
|
|
{ |
{ |
uint16 R[p],M[p]; |
uint16 R[p],M[p]; |
int i; |
int i; |
|
|
for (i = 0;i < p;++i) R[i] = r[i]+q12; |
for (i = 0;i < p;++i) R[i] = r[i]+q12; |
for (i = 0;i < p;++i) M[i] = q; |
for (i = 0;i < p;++i) M[i] = q; |
Encode(s,R,M,p); |
Encode(s,R,M,p); |
|
|
Decode(R,s,M,p); |
Decode(R,s,M,p); |
for (i = 0;i < p;++i) r[i] = ((Fq)R[i])-q12; |
for (i = 0;i < p;++i) r[i] = ((Fq)R[i])-q12; |
} |
} |
|
|
#endif |
#endif |
|
|
/* ----- encoding rounded polynomials */ |
/* ----- encoding rounded polynomials */ |