bignum *bigdecrement(bignum *n,size_t by_n) { ABORT_NABN(n); while(by_n--) bigsub(n,&BIGONE,n); return n; }
/* * DH stage 2-epsilon: given a number f, validate it to ensure it's in * range. (RFC 4253 section 8: "Values of 'e' or 'f' that are not in * the range [1, p-1] MUST NOT be sent or accepted by either side." * Also, we rule out 1 and p-1 too, since that's easy to do and since * they lead to obviously weak keys that even a passive eavesdropper * can figure out.) */ const char *dh_validate_f(void *handle, Bignum f) { struct dh_ctx *ctx = (struct dh_ctx *)handle; if (bignum_cmp(f, One) <= 0) { return "f value received is too small"; } else { Bignum pm1 = bigsub(ctx->p, One); int cmp = bignum_cmp(f, pm1); freebn(pm1); if (cmp >= 0) return "f value received is too large"; } return NULL; }
// Returns in r the solution of x == r[k] (mod m[k]), k = 0, ..., n-1 void crt (rawtype *r, rawtype *m, size_t n) { size_t t, k; rawtype *mm = new rawtype[n], *x = new rawtype[n], *s = new rawtype[n]; modint y; rawtype o; o = modint::modulus; mm[0] = m[0]; for (t = 1; t < n; t++) mm[t] = bigmul (mm, mm, m[t], t); for (t = 0; t < n; t++) s[t] = 0; for (k = 0; k < n; k++) { setmodulus (m[k]); y = 1; for (t = 0; t < n; t++) if (t != k) y *= m[t]; y = r[k] / y; bigdiv (x, mm, m[k], n); x[n - 1] = bigmul (x, x, y, n - 1); if (bigadd (s, x, n) || bigcmp (s, mm, n) > 0) bigsub (s, mm, n); } moveraw (r, s, n); setmodulus (o); delete[] mm; delete[] x; delete[] s; }
// Adds n words from s to d, returns overflow carry bit rawtype baseadd (rawtype *dest, rawtype *src1, rawtype *src2, size_t len, rawtype carry) { size_t t; for (t = len; t--;) { dest[t] = src1[t]; bigadd (dest + t, &carry, 1); if ((src2 && bigadd (dest + t, src2 + t, 1) != 0) || bigcmp (dest + t, &Base, 1) >= 0) { bigsub (dest + t, &Base, 1); carry = 1; } else { carry = 0; } } return carry; }
// Subtracts n words s from d, returns subtract carry bit (1) rawtype basesub (rawtype *dest, rawtype *src1, rawtype *src2, size_t len, rawtype carry) { size_t t; rawtype tmp; for (t = len; t--;) { dest[t] = (src1 ? src1[t] : 0); tmp = (src2 ? src2[t] : 0); bigadd (&tmp, &carry, 1); if (bigsub (dest + t, &tmp, 1) != 0) { bigadd (dest + t, &Base, 1); carry = 1; } else { carry = 0; } } return carry; }
int main() { long j,n,l; while(scanf("%s",str)==1&&strcmp(str,"0")) { j=strlen(str)-1; l=j+1; while(l>9) { n=str[j]-'0'; str[j]='\0'; bigsub(str,equ[n]); j--; l=strlen(str); } n=atol(str); if((n==0)||(n>=17&&n%17==0)) printf("1"); else printf("0"); printf("\n"); } return 0; }