/* bug-3229.c A crash in code generation for stm8 in the modular inversion of the NTRU reference implementation. */ #include #include #include #define NTRU_N 67 // Smallest prime for which the bug could be reproduced. typedef struct{ uint16_t coeffs[NTRU_N]; } poly; static inline uint8_t mod3(uint8_t a) /* a between 0 and 9 */ { int16_t t, c; a = (a >> 2) + (a & 3); /* between 0 and 4 */ t = a - 3; c = t >> 5; return (uint8_t) (t^(c&(a^t))); } /* return -1 if x<0 and y<0; otherwise return 0 */ static inline int16_t both_negative_mask(int16_t x,int16_t y) { return (x & y) >> 15; } #if !defined(__SDCC_mcs51) && !defined(__SDCC_sm83) && !defined(__SDCC_pdk13) && !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) && !defined(__SDCC_pdk16) // Lack of memory void poly_S3_inv(poly *r, const poly *a) { poly f, g, v, w; size_t i,loop; int16_t delta,sign,swap,t; for (i = 0;i < NTRU_N;++i) v.coeffs[i] = 0; for (i = 0;i < NTRU_N;++i) w.coeffs[i] = 0; w.coeffs[0] = 1; for (i = 0;i < NTRU_N;++i) f.coeffs[i] = 1; for (i = 0;i < NTRU_N-1;++i) g.coeffs[NTRU_N-2-i] = mod3((a->coeffs[i] & 3) + 2*(a->coeffs[NTRU_N-1] & 3)); g.coeffs[NTRU_N-1] = 0; delta = 1; for (loop = 0;loop < 2*(NTRU_N-1)-1;++loop) { for (i = NTRU_N-1;i > 0;--i) v.coeffs[i] = v.coeffs[i-1]; v.coeffs[0] = 0; sign = mod3((uint8_t) (2 * g.coeffs[0] * f.coeffs[0])); swap = both_negative_mask(-delta,-(int16_t) g.coeffs[0]); delta ^= swap & (delta ^ -delta); delta += 1; for (i = 0;i < NTRU_N;++i) { t = swap&(f.coeffs[i]^g.coeffs[i]); f.coeffs[i] ^= t; g.coeffs[i] ^= t; t = swap&(v.coeffs[i]^w.coeffs[i]); v.coeffs[i] ^= t; w.coeffs[i] ^= t; } for (i = 0;i < NTRU_N;++i) g.coeffs[i] = mod3((uint8_t) (g.coeffs[i]+sign*f.coeffs[i])); for (i = 0;i < NTRU_N;++i) w.coeffs[i] = mod3((uint8_t) (w.coeffs[i]+sign*v.coeffs[i])); for (i = 0;i < NTRU_N-1;++i) g.coeffs[i] = g.coeffs[i+1]; g.coeffs[NTRU_N-1] = 0; } sign = f.coeffs[0]; for (i = 0;i < NTRU_N-1;++i) r->coeffs[i] = mod3((uint8_t) (sign*v.coeffs[NTRU_N-2-i])); r->coeffs[NTRU_N-1] = 0; } #endif void testBug (void) { }