Beispiel #1
0
int isPrime2(int n) {
  int nc = n-1;
  int s = 0;
  while ((nc&1) == 0) {
    s += 1;
    nc >>= 1;
  }
  int d = n>>s;
  int a = 2;
  while (a <= 3) {
    if (isPrime1(a)) {
      if (modpow(a,d,n) != 1 & modpow(a,d,n) != n-1) {
	int r = 0;
	int worked = 0;
	while ((r <= s-1) & (r <= s)) {
	  if (modpow(a, (2<<r)*d, n) == n-1) {
	    worked = 1;
	  }
	  r += 1;
	}
	if (worked == 0) {
	  return 0;
	}
      }
    }
    a++;
  }
  return 1;
}
Beispiel #2
0
/**
 * is_prime(uint64_t n, unsigned int k):
 *
 * SYNOPSIS 
 *  Tests if a given candidate is prime with a given number of rounds of
 *  the Miller-Rabin-Test.
 *
 * DESCRIPTION
 *  is_prime() first tests primitely, and if the number passes it,
 *  goes on with the Miller-Rabin-Test. We do this because dividing is faster
 *  than the test.
 *  Note that even here, we don't know for sure if the given number is prime,
 *  it's only a probability test.
 *
 * RETURN VALUE
 *  1 if candidate passes the test, otherwise 0
 */
int is_prime(uint64_t n, unsigned int k) {
	if (n == 2)
		return 1;
	if (n == 1 || (n & 1) == 0)
		return 0;
	if (primitive_test(n) == NO_PRIME)
		return 0;
	
	uint64_t t, a, y, d = n-1;
	while ((d & 1) == 0) {
		d >>= 1;
	}
	int count;
	for (count=0; count < k; count++) {
		a = rand()/100;
		t = d;
		y = modpow(a, t, n);
		while (t != n-1 && y != 1 && y != n-1) {
			y = (y*y) % n;
			t <<= 1;
		}
		if (y != n-1 && (t & 1) == 0)
			return 0;
	}
	return 1;
}
Beispiel #3
0
/*
 * DH stage 2: given a number f, compute K = f^x mod p.
 */
Bignum dh_find_K(void *handle, Bignum f)
{
    struct dh_ctx *ctx = (struct dh_ctx *)handle;
    Bignum ret;
    ret = modpow(f, ctx->x, ctx->p);
    return ret;
}
Beispiel #4
0
int rsaencrypt(unsigned char *data, int length, struct RSAKey *key)
{
    Bignum b1, b2;
    int i;
    unsigned char *p;

    if (key->bytes < length + 4)
	return 0;		       /* RSA key too short! */

    memmove(data + key->bytes - length, data, length);
    data[0] = 0;
    data[1] = 2;

    for (i = 2; i < key->bytes - length - 1; i++) {
	do {
	    data[i] = random_byte();
	} while (data[i] == 0);
    }
    data[key->bytes - length - 1] = 0;

    b1 = bignum_from_bytes(data, key->bytes);

    b2 = modpow(b1, key->exponent, key->modulus);

    p = data;
    for (i = key->bytes; i--;) {
	*p++ = bignum_byte(b2, i);
    }

    freebn(b1);
    freebn(b2);

    return 1;
}
// find smallest primitive root of _n (assuming _n is prime)
unsigned int primitive_root(unsigned int _n)
{
    // find unique factors of _n-1
    unsigned int unique_factors[MAX_FACTORS];
    unsigned int num_unique_factors = 0;
    unsigned int n = _n-1;
    unsigned int k;
    do {
        for (k=2; k<=n; k++) {
            if ( (n%k)==0 ) {
                // k is a factor of (_n-1)
                n /= k;

                // add element to end of table
                unique_factors[num_unique_factors] = k;

                // increment counter only if element is unique
                if (num_unique_factors == 0)
                    num_unique_factors++;
                else if (unique_factors[num_unique_factors-1] != k)
                    num_unique_factors++;
                break;
            }
        }
    } while (n > 1 && num_unique_factors < MAX_FACTORS);

#if 0
    // print unique factors
    printf("found %u unique factors of n-1 = %u\n", num_unique_factors, _n-1);
    for (k=0; k<num_unique_factors; k++)
        printf("  %3u\n", unique_factors[k]);
#endif

    // search for minimum integer for which
    //   g^( (_n-1)/m ) != 1 (mod _n)
    // for all unique roots 'm'
    unsigned int g;
    int root_found = 0;
    for (g=2; g<_n; g++) {
        int is_root = 1;
        for (k=0; k<num_unique_factors; k++) {
            unsigned int e = (_n-1) / unique_factors[k];
            if ( modpow(g,e,_n) == 1 ) {
                // not a root
                is_root = 0;
                break;
            }
        }

        if (is_root) {
            //printf("  %u is a primitive root!\n", g);
            root_found = 1;
            break;
        }
    }

    return g;
}
Beispiel #6
0
/** \brief Preforms RSA encryption on plaintext m using exponent e and modulus n\n
 * m^e mod n
 *
 * \param m int Plaintext
 * \param e int Encryption Exponent
 * \param n int Modulus
 * \return int Ciphertext
 *
 */
int RSA::encode(int m, int e, int n)
{
    int c;

	m &= 0x000000ff;

    c = modpow(m, e, n);
    return c;
}
long long ncr_modp(const long long x, const long long y, const long long p)
{

	long long temp, result;
	
	temp = fact_modp(x, p) * fact_modp(y, p) % p;
	result =  modpow(temp, p-2, p) * fact_modp(x + y, p);
	
	return result % p;
}
Beispiel #8
0
void rsaencrypt(unsigned char *data, int length, struct RSAKey *key) {
    Bignum b1, b2;
    int w, i;
    unsigned char *p;

    debug(key->exponent);

    memmove(data+key->bytes-length, data, length);
    data[0] = 0;
    data[1] = 2;

    for (i = 2; i < key->bytes-length-1; i++) {
	do {
	    data[i] = random_byte();
	} while (data[i] == 0);
    }
    data[key->bytes-length-1] = 0;

    w = (key->bytes+1)/2;

    b1 = newbn(w);
    b2 = newbn(w);

    p = data;
    for (i=1; i<=w; i++)
	b1[i] = 0;
    for (i=0; i<key->bytes; i++) {
	unsigned char byte = *p++;
	if ((key->bytes-i) & 1)
	    b1[w-i/2] |= byte;
	else
	    b1[w-i/2] |= byte<<8;
    }

    debug(b1);

    modpow(b1, key->exponent, key->modulus, b2);

    debug(b2);

    p = data;
    for (i=0; i<key->bytes; i++) {
	unsigned char b;
	if (i & 1)
	    b = b2[w-i/2] & 0xFF;
	else
	    b = b2[w-i/2] >> 8;
	*p++ = b;
    }

    freebn(b1);
    freebn(b2);
}
Beispiel #9
0
static void *dss_createkey(unsigned char *pub_blob, int pub_len,  unsigned char *priv_blob, int priv_len)
{
    dss_key *dss;
    char *pb = (char *) priv_blob;
    char *hash;
    int hashlen;
    SHA_State s;
    unsigned char digest[20];
    Bignum ytest;

    dss = dss_newkey((char *) pub_blob, pub_len);
    if (!dss)
        return NULL;
    dss->x = getmp(&pb, &priv_len);
    if (!dss->x) {
        dss_freekey(dss);
        return NULL;
    }

    /*
     * Check the obsolete hash in the old DSS key format.
     */
    hashlen = -1;
    getstring(&pb, &priv_len, &hash, &hashlen);
    if (hashlen == 20) 
	{
	SHA_Init(&s);
	sha_mpint(&s, dss->p);
	sha_mpint(&s, dss->q);
	sha_mpint(&s, dss->g);
	SHA_Final(&s, digest);

	if (0 != memcmp(hash, digest, 20)) 
	{
	    dss_freekey(dss);
	    return NULL;
	}
    }

    /*
     * Now ensure g^x mod p really is y.
     */
    ytest = modpow(dss->g, dss->x, dss->p);
    if (0 != bignum_cmp(ytest, dss->y)) 
	{
		dss_freekey(dss);
        freebn(ytest);
		return NULL;
    }
    freebn(ytest);

    return dss;
}
Beispiel #10
0
static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen)
{
    struct dss_key *dss = (struct dss_key *) key;
    Bignum k, gkp, hash, kinv, hxr, r, s;
    unsigned char digest[20];
    unsigned char *bytes;
    int nbytes, i;

    SHA_Simple(data, datalen, digest);

    k = dss_gen_k("DSA deterministic k generator", dss->q, dss->x,
                  digest, sizeof(digest));
    kinv = modinv(k, dss->q);	       /* k^-1 mod q */
    assert(kinv);

    /*
     * Now we have k, so just go ahead and compute the signature.
     */
    gkp = modpow(dss->g, k, dss->p);   /* g^k mod p */
    r = bigmod(gkp, dss->q);	       /* r = (g^k mod p) mod q */
    freebn(gkp);

    hash = bignum_from_bytes(digest, 20);
    hxr = bigmuladd(dss->x, r, hash);  /* hash + x*r */
    s = modmul(kinv, hxr, dss->q);     /* s = k^-1 * (hash + x*r) mod q */
    freebn(hxr);
    freebn(kinv);
    freebn(k);
    freebn(hash);

    /*
     * Signature blob is
     * 
     *   string  "ssh-dss"
     *   string  two 20-byte numbers r and s, end to end
     * 
     * i.e. 4+7 + 4+40 bytes.
     */
    nbytes = 4 + 7 + 4 + 40;
    bytes = snewn(nbytes, unsigned char);
    PUT_32BIT(bytes, 7);
    memcpy(bytes + 4, "ssh-dss", 7);
    PUT_32BIT(bytes + 4 + 7, 40);
    for (i = 0; i < 20; i++) {
	bytes[4 + 7 + 4 + i] = bignum_byte(r, 19 - i);
	bytes[4 + 7 + 4 + 20 + i] = bignum_byte(s, 19 - i);
    }
    freebn(r);
    freebn(s);

    *siglen = nbytes;
    return bytes;
}
function SPRP(N,a) {
  var d = N-1; s = 1;  			// Assumes N is odd!
  while ( ((d=d/2) & 1) == 0) s++;	// Using d>>1 changed the sign of d!
  // Now N-1 = d*2^s with d odd
  var b = modpow(a,d,N);
  if (b == 1) return true;
  if (b+1 == N) return true;
  while (s-- > 1) {
    b = modmult(b,b,N);
    if (b+1 == N) return true;
  }
  return false;
}
Beispiel #12
0
int main(void) {
    modmult(P1, P2, bigmod, a);   debug(a);
    modmult(a, P3, bigmod, mod);  debug(mod);

    sub(P1, One, a);              debug(a);
    sub(P2, One, b);              debug(b);
    modmult(a, b, bigmod, c);     debug(c);
    sub(P3, One, a);              debug(a);
    modmult(a, c, bigmod, b);     debug(b);

    modpow(Two, b, mod, a);       debug(a);

    return 0;
}
Beispiel #13
0
/*
 * DH stage 1: invent a number x between 1 and q, and compute e =
 * g^x mod p. Return e.
 * 
 * If `nbits' is greater than zero, it is used as an upper limit
 * for the number of bits in x. This is safe provided that (a) you
 * use twice as many bits in x as the number of bits you expect to
 * use in your session key, and (b) the DH group is a safe prime
 * (which SSH demands that it must be).
 * 
 * P. C. van Oorschot, M. J. Wiener
 * "On Diffie-Hellman Key Agreement with Short Exponents".
 * Advances in Cryptology: Proceedings of Eurocrypt '96
 * Springer-Verlag, May 1996.
 */
Bignum dh_create_e(void *handle, int nbits)
{
    struct dh_ctx *ctx = (struct dh_ctx *)handle;
    int i;

    int nbytes;
    unsigned char *buf;

    nbytes = ssh1_bignum_length(ctx->qmask);
    buf = snewn(nbytes, unsigned char);

    do {
	/*
	 * Create a potential x, by ANDing a string of random bytes
	 * with qmask.
	 */
	if (ctx->x)
	    freebn(ctx->x);
	if (nbits == 0 || nbits > bignum_bitcount(ctx->qmask)) {
	    ssh1_write_bignum(buf, ctx->qmask);
	    for (i = 2; i < nbytes; i++)
		buf[i] &= random_byte();
	    ssh1_read_bignum(buf, nbytes, &ctx->x);   /* can't fail */
	} else {
	    int b, nb;
	    ctx->x = bn_power_2(nbits);
	    b = nb = 0;
	    for (i = 0; i < nbits; i++) {
		if (nb == 0) {
		    nb = 8;
		    b = random_byte();
		}
		bignum_set_bit(ctx->x, i, b & 1);
		b >>= 1;
		nb--;
	    }
	}
    } while (bignum_cmp(ctx->x, One) <= 0 || bignum_cmp(ctx->x, ctx->q) >= 0);

    sfree(buf);

    /*
     * Done. Now compute e = g^x mod p.
     */
    ctx->e = modpow(ctx->g, ctx->x, ctx->p);

    return ctx->e;
}
Beispiel #14
0
static int rsa2_verifysig(void *key, char *sig, int siglen,
			  char *data, int datalen)
{
    struct RSAKey *rsa = (struct RSAKey *) key;
    Bignum in, out;
    char *p;
    int slen;
    int bytes, i, j, ret;
    unsigned char hash[20];

    getstring(&sig, &siglen, &p, &slen);
    if (!p || slen != 7 || memcmp(p, "ssh-rsa", 7)) {
	return 0;
    }
    in = getmp(&sig, &siglen);
    out = modpow(in, rsa->exponent, rsa->modulus);
    freebn(in);

    ret = 1;

    bytes = (bignum_bitcount(rsa->modulus)+7) / 8;
    /* Top (partial) byte should be zero. */
    if (bignum_byte(out, bytes - 1) != 0)
	ret = 0;
    /* First whole byte should be 1. */
    if (bignum_byte(out, bytes - 2) != 1)
	ret = 0;
    /* Most of the rest should be FF. */
    for (i = bytes - 3; i >= 20 + ASN1_LEN; i--) {
	if (bignum_byte(out, i) != 0xFF)
	    ret = 0;
    }
    /* Then we expect to see the asn1_weird_stuff. */
    for (i = 20 + ASN1_LEN - 1, j = 0; i >= 20; i--, j++) {
	if (bignum_byte(out, i) != asn1_weird_stuff[j])
	    ret = 0;
    }
    /* Finally, we expect to see the SHA-1 hash of the signed data. */
    SHA_Simple(data, datalen, hash);
    for (i = 19, j = 0; i >= 0; i--, j++) {
	if (bignum_byte(out, i) != hash[j])
	    ret = 0;
    }
    freebn(out);

    return ret;
}
Beispiel #15
0
bool RSAKey::Verify( const CString &data, const CString &sig ) const
{
	Bignum in, out;
	int bytes, i, j;
	unsigned char hash[20];

	in = bignum_from_bytes( (const unsigned char *) sig.data(), sig.size() );

	/* Base (in) must be smaller than the modulus. */
	if( bignum_cmp(in, this->modulus) >= 0 )
	{
		freebn(in);
		return false;
	}
	out = modpow(in, this->exponent, this->modulus);
	freebn(in);

	bool ret = true;

	bytes = (bignum_bitcount(this->modulus)+7) / 8;
	/* Top (partial) byte should be zero. */
	if (bignum_byte(out, bytes - 1) != 0)
		ret = 0;
	/* First whole byte should be 1. */
	if (bignum_byte(out, bytes - 2) != 1)
		ret = 0;
	/* Most of the rest should be FF. */
	for (i = bytes - 3; i >= 20; i--) {
		if (bignum_byte(out, i) != 0xFF)
			ret = 0;
	}
	/* Finally, we expect to see the SHA-1 hash of the signed data. */
	SHA_Simple( data.data(), data.size(), hash );
	for (i = 19, j = 0; i >= 0; i--, j++) {
		if (bignum_byte(out, i) != hash[j])
			ret = false;
	}
	freebn(out);

	return ret;
}
bool Miller(unsigned long long N)
{
	if(N<2)return false;
	else if(N<4) return true;
	else if((N&1)==0)return false;
	unsigned long long D=N-1,S=0;
	while((D&1)==0)
	{
		D>>=1;
		S++;
	}
	for(int a=0;a<5;a++)
	{
		unsigned long long ad=modpow(rand()%(N-4)+2,D,N);
		if(ad==1||ad==N-1) continue;
		for(unsigned long long r=0;r<S-1;r++)
			if((ad=modmult(ad,ad,N))==N-1)
				goto BPP;
		return false;
		BPP:;
	}
	return true;
}
Beispiel #17
0
int main(){
  long long int t,i,j,k;
  long long int V,N;
  scanf("%lld",&t);
  while(t--){
    long long int P[100];
    long long int Q[100];
    long long int L[100];

    long long int V,N,p0,p1,A0,B0,C0,M0,q0,q1,A1,B1,C1,M1;

    scanf("%lld %lld",&V,&N);
    scanf("%lld %lld %lld %lld %lld %lld",&p0,&p1,&A0,&B0,&C0,&M0);
    scanf("%lld %lld %lld %lld %lld %lld",&q0,&q1,&A1,&B1,&C1,&M1);

    P[0] = p0;
    P[1] = p1;
    Q[0] = q0;
    Q[1] = q1;
    for(j=2;j<N;j++){
      P[j] = ( A0*A0*P[j-1] + B0*P[j-2] + C0 )%M0;
      Q[j] = ( A1*A1*Q[j-1] + B1*Q[j-2] + C1 )%M1;
    }
    for(j=0;j<N;j++){
      L[j] = P[j]*(M1)+ Q[j] + 1;
    }

    long long int ans,temp;
    ans = V;
    for(j=0;j<N;j++){
      ans = (modpow(ans,L[j]-1,MOD))%MOD;
    }
    
    printf("%lld\n",ans);
  }
  return 0;
}
int main(int argc, char*argv[]) {
    // transform size (must be prime)
    unsigned int nfft = 17;

    int dopt;
    while ((dopt = getopt(argc,argv,"uhn:")) != EOF) {
        switch (dopt) {
        case 'h':   usage();                return 0;
        case 'n':   nfft = atoi(optarg);    break;
        default:
            exit(1);
        }
    }

    // validate input
    if ( nfft <= 2 || !is_prime(nfft)) {
        fprintf(stderr,"error: %s, input transform size must be prime and greater than two\n", argv[0]);
        exit(1);
    }

    unsigned int i;

    // create and initialize data arrays
    float complex * x      = (float complex *) malloc(nfft * sizeof(float complex));
    float complex * y      = (float complex *) malloc(nfft * sizeof(float complex));
    float complex * y_test = (float complex *) malloc(nfft * sizeof(float complex));
    if (x == NULL || y == NULL || y_test == NULL) {
        fprintf(stderr,"error: %s, not enough memory for allocation\n", argv[0]);
        exit(1);
    }
    for (i=0; i<nfft; i++) {
        //x[i] = randnf() + _Complex_I*randnf();
        x[i] = (float)i + _Complex_I*(3 - (float)i);
        y[i] = 0.0f;
    }

    // compute output for testing
    dft_run(nfft, x, y_test, DFT_FORWARD, 0);

    // 
    // run Rader's algorithm
    //

    // compute primitive root of nfft
    unsigned int g = primitive_root(nfft);

    // create and initialize sequence
    unsigned int * s = (unsigned int *)malloc((nfft-1)*sizeof(unsigned int));
    for (i=0; i<nfft-1; i++)
        s[i] = modpow(g, i+1, nfft);

#if DEBUG
    printf("computed primitive root of %u as %u\n", nfft, g);
    // generate sequence (sanity check)
    printf("s = [");
    for (i=0; i<nfft-1; i++)
        printf("%4u", s[i]);
    printf("]\n");
#endif

    // compute DFT of sequence { exp(-j*2*pi*g^i/nfft }, size: nfft-1
    // NOTE: R[0] = -1, |R[k]| = sqrt(nfft) for k != 0
    // NOTE: R can be pre-computed
    float complex * r = (float complex*)malloc((nfft-1)*sizeof(float complex));
    float complex * R = (float complex*)malloc((nfft-1)*sizeof(float complex));
    for (i=0; i<nfft-1; i++)
        r[i] = cexpf(-_Complex_I*2*M_PI*s[i]/(float)(nfft));
    dft_run(nfft-1, r, R, DFT_FORWARD, 0);

    // compute DFT of permuted sequence, size: nfft-1
    float complex * xp = (float complex*)malloc((nfft-1)*sizeof(float complex));
    float complex * Xp = (float complex*)malloc((nfft-1)*sizeof(float complex));
    for (i=0; i<nfft-1; i++) {
        // reverse sequence
        unsigned int k = s[nfft-1-i-1];
        xp[i] = x[k];
    }
    dft_run(nfft-1, xp, Xp, DFT_FORWARD, 0);

    // compute inverse FFT of product
    for (i=0; i<nfft-1; i++)
        Xp[i] *= R[i];
    dft_run(nfft-1, Xp, xp, DFT_REVERSE, 0);

    // set DC value
    y[0] = 0.0f;
    for (i=0; i<nfft; i++)
        y[0] += x[i];

    // reverse permute result, scale, and add offset x[0]
    for (i=0; i<nfft-1; i++) {
        unsigned int k = s[i];

        y[k] = xp[i] / (float)(nfft-1) + x[0];
    }

    // free internal memory
    free(r);
    free(R);
    free(xp);
    free(Xp);
    free(s);

    // 
    // print results
    //
    for (i=0; i<nfft; i++) {
        printf("  y[%3u] = %12.6f + j*%12.6f (expected %12.6f + j%12.6f)\n",
            i,
            crealf(y[i]),      cimagf(y[i]),
            crealf(y_test[i]), cimagf(y_test[i]));
    }

    // compute error
    float rmse = 0.0f;
    for (i=0; i<nfft; i++) {
        float e = cabsf(y[i] - y_test[i]);
        rmse += e*e;
    }
    rmse = sqrtf(rmse / (float)nfft);
    printf("RMS error : %12.4e (%s)\n", rmse, rmse < 1e-3 ? "pass" : "FAIL");

    // free allocated memory
    free(x);
    free(y);
    free(y_test);

    return 0;
}
Beispiel #19
0
/*
 * This function is a wrapper on modpow(). It has the same effect
 * as modpow(), but employs RSA blinding to protect against timing
 * attacks.
 */
static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key)
{
    Bignum random, random_encrypted, random_inverse;
    Bignum input_blinded, ret_blinded;
    Bignum ret;

    SHA512_State ss;
    unsigned char digest512[64];
    int digestused = lenof(digest512);
    int hashseq = 0;

    /*
     * Start by inventing a random number chosen uniformly from the
     * range 2..modulus-1. (We do this by preparing a random number
     * of the right length and retrying if it's greater than the
     * modulus, to prevent any potential Bleichenbacher-like
     * attacks making use of the uneven distribution within the
     * range that would arise from just reducing our number mod n.
     * There are timing implications to the potential retries, of
     * course, but all they tell you is the modulus, which you
     * already knew.)
     * 
     * To preserve determinism and avoid Pageant needing to share
     * the random number pool, we actually generate this `random'
     * number by hashing stuff with the private key.
     */
    while (1) {
	int bits, byte, bitsleft, v;
	random = copybn(key->modulus);
	/*
	 * Find the topmost set bit. (This function will return its
	 * index plus one.) Then we'll set all bits from that one
	 * downwards randomly.
	 */
	bits = bignum_bitcount(random);
	byte = 0;
	bitsleft = 0;
	while (bits--) {
	    if (bitsleft <= 0) {
		bitsleft = 8;
		/*
		 * Conceptually the following few lines are equivalent to
		 *    byte = random_byte();
		 */
		if (digestused >= lenof(digest512)) {
		    unsigned char seqbuf[4];
		    PUT_32BIT(seqbuf, hashseq);
		    pSHA512_Init(&ss);
		    SHA512_Bytes(&ss, "RSA deterministic blinding", 26);
		    SHA512_Bytes(&ss, seqbuf, sizeof(seqbuf));
		    sha512_mpint(&ss, key->private_exponent);
		    pSHA512_Final(&ss, digest512);
		    hashseq++;

		    /*
		     * Now hash that digest plus the signature
		     * input.
		     */
		    pSHA512_Init(&ss);
		    SHA512_Bytes(&ss, digest512, sizeof(digest512));
		    sha512_mpint(&ss, input);
		    pSHA512_Final(&ss, digest512);

		    digestused = 0;
		}
		byte = digest512[digestused++];
	    }
	    v = byte & 1;
	    byte >>= 1;
	    bitsleft--;
	    bignum_set_bit(random, bits, v);
	}

	/*
	 * Now check that this number is strictly greater than
	 * zero, and strictly less than modulus.
	 */
	if (bignum_cmp(random, Zero) <= 0 ||
	    bignum_cmp(random, key->modulus) >= 0) {
	    freebn(random);
	    continue;
	} else {
	    break;
	}
    }

    /*
     * RSA blinding relies on the fact that (xy)^d mod n is equal
     * to (x^d mod n) * (y^d mod n) mod n. We invent a random pair
     * y and y^d; then we multiply x by y, raise to the power d mod
     * n as usual, and divide by y^d to recover x^d. Thus an
     * attacker can't correlate the timing of the modpow with the
     * input, because they don't know anything about the number
     * that was input to the actual modpow.
     * 
     * The clever bit is that we don't have to do a huge modpow to
     * get y and y^d; we will use the number we just invented as
     * _y^d_, and use the _public_ exponent to compute (y^d)^e = y
     * from it, which is much faster to do.
     */
    random_encrypted = modpow(random, key->exponent, key->modulus);
    random_inverse = modinv(random, key->modulus);
    input_blinded = modmul(input, random_encrypted, key->modulus);
    ret_blinded = modpow(input_blinded, key->private_exponent, key->modulus);
    ret = modmul(ret_blinded, random_inverse, key->modulus);

    freebn(ret_blinded);
    freebn(input_blinded);
    freebn(random_inverse);
    freebn(random_encrypted);
    freebn(random);

    return ret;
}
Beispiel #20
0
Bignum RSAKey::Encrypt(const Bignum input) const
{
	return modpow( input, this->exponent, this->modulus );
}
Beispiel #21
0
/** \brief Preforms RSA decryption on ciphertext c using exponent d and modulus n
 * c^d mod n
 *
 * \param c int Ciphertext
 * \param d int Private Exponent
 * \param n int Modulus
 * \return int  Plaintext
 *
 */
int RSA::decode(int c, int d, int n)
{
    int m;
    m = modpow(c, d, n);
    return m;
}
Beispiel #22
0
int dsa_generate(struct dss_key *key, int bits, progfn_t pfn,
		 void *pfnparam)
{
    Bignum qm1, power, g, h, tmp;
    unsigned pfirst, qfirst;
    int progress;

    /*
     * Set up the phase limits for the progress report. We do this
     * by passing minus the phase number.
     *
     * For prime generation: our initial filter finds things
     * coprime to everything below 2^16. Computing the product of
     * (p-1)/p for all prime p below 2^16 gives about 20.33; so
     * among B-bit integers, one in every 20.33 will get through
     * the initial filter to be a candidate prime.
     *
     * Meanwhile, we are searching for primes in the region of 2^B;
     * since pi(x) ~ x/log(x), when x is in the region of 2^B, the
     * prime density will be d/dx pi(x) ~ 1/log(B), i.e. about
     * 1/0.6931B. So the chance of any given candidate being prime
     * is 20.33/0.6931B, which is roughly 29.34 divided by B.
     *
     * So now we have this probability P, we're looking at an
     * exponential distribution with parameter P: we will manage in
     * one attempt with probability P, in two with probability
     * P(1-P), in three with probability P(1-P)^2, etc. The
     * probability that we have still not managed to find a prime
     * after N attempts is (1-P)^N.
     * 
     * We therefore inform the progress indicator of the number B
     * (29.34/B), so that it knows how much to increment by each
     * time. We do this in 16-bit fixed point, so 29.34 becomes
     * 0x1D.57C4.
     */
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 1, 0x2800);
    pfn(pfnparam, PROGFN_EXP_PHASE, 1, -0x1D57C4 / 160);
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 2, 0x40 * bits);
    pfn(pfnparam, PROGFN_EXP_PHASE, 2, -0x1D57C4 / bits);

    /*
     * In phase three we are finding an order-q element of the
     * multiplicative group of p, by finding an element whose order
     * is _divisible_ by q and raising it to the power of (p-1)/q.
     * _Most_ elements will have order divisible by q, since for a
     * start phi(p) of them will be primitive roots. So
     * realistically we don't need to set this much below 1 (64K).
     * Still, we'll set it to 1/2 (32K) to be on the safe side.
     */
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 3, 0x2000);
    pfn(pfnparam, PROGFN_EXP_PHASE, 3, -32768);

    /*
     * In phase four we are finding an element x between 1 and q-1
     * (exclusive), by inventing 160 random bits and hoping they
     * come out to a plausible number; so assuming q is uniformly
     * distributed between 2^159 and 2^160, the chance of any given
     * attempt succeeding is somewhere between 0.5 and 1. Lacking
     * the energy to arrange to be able to specify this probability
     * _after_ generating q, we'll just set it to 0.75.
     */
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 4, 0x2000);
    pfn(pfnparam, PROGFN_EXP_PHASE, 4, -49152);

    pfn(pfnparam, PROGFN_READY, 0, 0);

    invent_firstbits(&pfirst, &qfirst);
    /*
     * Generate q: a prime of length 160.
     */
    key->q = primegen(160, 2, 2, NULL, 1, pfn, pfnparam, qfirst);
    /*
     * Now generate p: a prime of length `bits', such that p-1 is
     * divisible by q.
     */
    key->p = primegen(bits-160, 2, 2, key->q, 2, pfn, pfnparam, pfirst);

    /*
     * Next we need g. Raise 2 to the power (p-1)/q modulo p, and
     * if that comes out to one then try 3, then 4 and so on. As
     * soon as we hit a non-unit (and non-zero!) one, that'll do
     * for g.
     */
    power = bigdiv(key->p, key->q);    /* this is floor(p/q) == (p-1)/q */
    h = bignum_from_long(1);
    progress = 0;
    while (1) {
	pfn(pfnparam, PROGFN_PROGRESS, 3, ++progress);
	g = modpow(h, power, key->p);
	if (bignum_cmp(g, One) > 0)
	    break;		       /* got one */
	tmp = h;
	h = bignum_add_long(h, 1);
	freebn(tmp);
    }
    key->g = g;
    freebn(h);

    /*
     * Now we're nearly done. All we need now is our private key x,
     * which should be a number between 1 and q-1 exclusive, and
     * our public key y = g^x mod p.
     */
    qm1 = copybn(key->q);
    decbn(qm1);
    progress = 0;
    while (1) {
	int i, v, byte, bitsleft;
	Bignum x;

	pfn(pfnparam, PROGFN_PROGRESS, 4, ++progress);
	x = bn_power_2(159);
	byte = 0;
	bitsleft = 0;

	for (i = 0; i < 160; i++) {
	    if (bitsleft <= 0)
		bitsleft = 8, byte = random_byte();
	    v = byte & 1;
	    byte >>= 1;
	    bitsleft--;
	    bignum_set_bit(x, i, v);
	}

	if (bignum_cmp(x, One) <= 0 || bignum_cmp(x, qm1) >= 0) {
	    freebn(x);
	    continue;
	} else {
	    key->x = x;
	    break;
	}
    }
    freebn(qm1);

    key->y = modpow(key->g, key->x, key->p);

    return 1;
}
Beispiel #23
0
/**
 * get_shared_key(uint64_t partner_public, uint64_t own_secret, uint64_t prime):
 *
 * SYNOPSIS
 *  Gets the shared key for our the given public key of our partner, 
 *  our own secret, and the prime
 *
 * RETURN VALUE
 *  64-bit integer
 */
uint64_t get_shared_key(uint64_t partner_public, uint64_t own_secret, uint64_t prime) {
	return modpow(partner_public, own_secret, prime);
}
Beispiel #24
0
/**
 * gen_public_key(uint64_t g, uint64_t secret, uint64_t prime):
 *
 * SYNOPSIS
 *  Generates the public key
 *
 * RETURN VALUE
 *  64-bit integer
 */
uint64_t gen_public_key(uint64_t g, uint64_t secret, uint64_t prime) {
	return modpow(g, secret, prime);
}
Beispiel #25
0
/*
 * Generate a prime. We arrange to select a prime with the property
 * (prime % modulus) != residue (to speed up use in RSA).
 */
Bignum primegen(int bits, int modulus, int residue,
                int phase, progfn_t pfn, void *pfnparam) {
    int i, k, v, byte, bitsleft, check, checks;
    unsigned long delta, moduli[NPRIMES+1], residues[NPRIMES+1];
    Bignum p, pm1, q, wqp, wqp2;
    int progress = 0;

    byte = 0; bitsleft = 0;

    STARTOVER:

    pfn(pfnparam, phase, ++progress);

    /*
     * Generate a k-bit random number with top and bottom bits set.
     */
    p = newbn((bits+15)/16);
    for (i = 0; i < bits; i++) {
        if (i == 0 || i == bits-1)
            v = 1;
        else {
            if (bitsleft <= 0)
                bitsleft = 8; byte = random_byte();
            v = byte & 1;
            byte >>= 1;
            bitsleft--;
        }
        bignum_set_bit(p, i, v);
    }

    /*
     * Ensure this random number is coprime to the first few
     * primes, by repeatedly adding 2 to it until it is.
     */
    for (i = 0; i < NPRIMES; i++) {
        moduli[i] = primes[i];
        residues[i] = bignum_mod_short(p, primes[i]);
    }
    moduli[NPRIMES] = modulus;
    residues[NPRIMES] = (bignum_mod_short(p, (unsigned short)modulus)
                         + modulus - residue);
    delta = 0;
    while (1) {
        for (i = 0; i < (sizeof(moduli) / sizeof(*moduli)); i++)
            if (!((residues[i] + delta) % moduli[i]))
                break;
        if (i < (sizeof(moduli) / sizeof(*moduli))) {/* we broke */
            delta += 2;
            if (delta < 2) {
                freebn(p);
                goto STARTOVER;
            }
            continue;
        }
        break;
    }
    q = p;
    p = bignum_add_long(q, delta);
    freebn(q);

    /*
     * Now apply the Miller-Rabin primality test a few times. First
     * work out how many checks are needed.
     */
    checks = 27;
    if (bits >= 150) checks = 18;
    if (bits >= 200) checks = 15;
    if (bits >= 250) checks = 12;
    if (bits >= 300) checks = 9;
    if (bits >= 350) checks = 8;
    if (bits >= 400) checks = 7;
    if (bits >= 450) checks = 6;
    if (bits >= 550) checks = 5;
    if (bits >= 650) checks = 4;
    if (bits >= 850) checks = 3;
    if (bits >= 1300) checks = 2;

    /*
     * Next, write p-1 as q*2^k.
     */
    for (k = 0; bignum_bit(p, k) == !k; k++);   /* find first 1 bit in p-1 */
    q = bignum_rshift(p, k);
    /* And store p-1 itself, which we'll need. */
    pm1 = copybn(p);
    decbn(pm1);

    /*
     * Now, for each check ...
     */
    for (check = 0; check < checks; check++) {
        Bignum w;

        /*
         * Invent a random number between 1 and p-1 inclusive.
         */
        while (1) {
            w = newbn((bits+15)/16);
            for (i = 0; i < bits; i++) {
                if (bitsleft <= 0)
                    bitsleft = 8; byte = random_byte();
                v = byte & 1;
                byte >>= 1;
                bitsleft--;
                bignum_set_bit(w, i, v);
            }
            if (bignum_cmp(w, p) >= 0 || bignum_cmp(w, Zero) == 0) {
                freebn(w);
                continue;
            }
            break;
        }

        pfn(pfnparam, phase, ++progress);

        /*
         * Compute w^q mod p.
         */
        wqp = modpow(w, q, p);
        freebn(w);

        /*
         * See if this is 1, or if it is -1, or if it becomes -1
         * when squared at most k-1 times.
         */
        if (bignum_cmp(wqp, One) == 0 || bignum_cmp(wqp, pm1) == 0) {
            freebn(wqp);
            continue;
        }
        for (i = 0; i < k-1; i++) {
            wqp2 = modmul(wqp, wqp, p);
            freebn(wqp);
            wqp = wqp2;
            if (bignum_cmp(wqp, pm1) == 0)
                break;
        }
        if (i < k-1) {
            freebn(wqp);
            continue;
        }

        /*
         * It didn't. Therefore, w is a witness for the
         * compositeness of p.
         */
        freebn(p);
        freebn(pm1);
        freebn(q);
        goto STARTOVER;
    }

    /*
     * We have a prime!
     */
    freebn(q);
    freebn(pm1);
    return p;
}
Beispiel #26
0
static int dss_verifysig(void *key, char *sig, int siglen,
			 char *data, int datalen)
{
    struct dss_key *dss = (struct dss_key *) key;
    char *p;
    int slen;
    char hash[20];
    Bignum r, s, w, gu1p, yu2p, gu1yu2p, u1, u2, sha, v;
    int ret;

    if (!dss->p)
	return 0;

#ifdef DEBUG_DSS
    {
	int i;
	printf("sig:");
	for (i = 0; i < siglen; i++)
	    printf("  %02x", (unsigned char) (sig[i]));
	printf("\n");
    }
#endif
    /*
     * Commercial SSH (2.0.13) and OpenSSH disagree over the format
     * of a DSA signature. OpenSSH is in line with the IETF drafts:
     * it uses a string "ssh-dss", followed by a 40-byte string
     * containing two 160-bit integers end-to-end. Commercial SSH
     * can't be bothered with the header bit, and considers a DSA
     * signature blob to be _just_ the 40-byte string containing
     * the two 160-bit integers. We tell them apart by measuring
     * the length: length 40 means the commercial-SSH bug, anything
     * else is assumed to be IETF-compliant.
     */
    if (siglen != 40) {		       /* bug not present; read admin fields */
	getstring(&sig, &siglen, &p, &slen);
	if (!p || slen != 7 || memcmp(p, "ssh-dss", 7)) {
	    return 0;
	}
	sig += 4, siglen -= 4;	       /* skip yet another length field */
    }
    r = get160(&sig, &siglen);
    s = get160(&sig, &siglen);
    if (!r || !s)
	return 0;

    /*
     * Step 1. w <- s^-1 mod q.
     */
    w = modinv(s, dss->q);

    /*
     * Step 2. u1 <- SHA(message) * w mod q.
     */
    SHA_Simple(data, datalen, (unsigned char *)hash);
    p = hash;
    slen = 20;
    sha = get160(&p, &slen);
    u1 = modmul(sha, w, dss->q);

    /*
     * Step 3. u2 <- r * w mod q.
     */
    u2 = modmul(r, w, dss->q);

    /*
     * Step 4. v <- (g^u1 * y^u2 mod p) mod q.
     */
    gu1p = modpow(dss->g, u1, dss->p);
    yu2p = modpow(dss->y, u2, dss->p);
    gu1yu2p = modmul(gu1p, yu2p, dss->p);
    v = modmul(gu1yu2p, One, dss->q);

    /*
     * Step 5. v should now be equal to r.
     */

    ret = !bignum_cmp(v, r);

    freebn(w);
    freebn(sha);
    freebn(gu1p);
    freebn(yu2p);
    freebn(gu1yu2p);
    freebn(v);
    freebn(r);
    freebn(s);

    return ret;
}
Beispiel #27
0
/** \brief Preforms RSA decryption on ciphertext c using exponent d and modulus n
 * c^d mod n
 *
 * \param c int Ciphertext
 * \param d int Private Exponent
 * \param n int Modulus
 * \return int  Plaintext
 *
 */
int decodeRSA(int c, int d, int n)
{
    int m;
    m = modpow(c, d, n);
    return m;
}
Beispiel #28
0
static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen)
{
    /*
     * The basic DSS signing algorithm is:
     * 
     *  - invent a random k between 1 and q-1 (exclusive).
     *  - Compute r = (g^k mod p) mod q.
     *  - Compute s = k^-1 * (hash + x*r) mod q.
     * 
     * This has the dangerous properties that:
     * 
     *  - if an attacker in possession of the public key _and_ the
     *    signature (for example, the host you just authenticated
     *    to) can guess your k, he can reverse the computation of s
     *    and work out x = r^-1 * (s*k - hash) mod q. That is, he
     *    can deduce the private half of your key, and masquerade
     *    as you for as long as the key is still valid.
     * 
     *  - since r is a function purely of k and the public key, if
     *    the attacker only has a _range of possibilities_ for k
     *    it's easy for him to work through them all and check each
     *    one against r; he'll never be unsure of whether he's got
     *    the right one.
     * 
     *  - if you ever sign two different hashes with the same k, it
     *    will be immediately obvious because the two signatures
     *    will have the same r, and moreover an attacker in
     *    possession of both signatures (and the public key of
     *    course) can compute k = (hash1-hash2) * (s1-s2)^-1 mod q,
     *    and from there deduce x as before.
     * 
     *  - the Bleichenbacher attack on DSA makes use of methods of
     *    generating k which are significantly non-uniformly
     *    distributed; in particular, generating a 160-bit random
     *    number and reducing it mod q is right out.
     * 
     * For this reason we must be pretty careful about how we
     * generate our k. Since this code runs on Windows, with no
     * particularly good system entropy sources, we can't trust our
     * RNG itself to produce properly unpredictable data. Hence, we
     * use a totally different scheme instead.
     * 
     * What we do is to take a SHA-512 (_big_) hash of the private
     * key x, and then feed this into another SHA-512 hash that
     * also includes the message hash being signed. That is:
     * 
     *   proto_k = SHA512 ( SHA512(x) || SHA160(message) )
     * 
     * This number is 512 bits long, so reducing it mod q won't be
     * noticeably non-uniform. So
     * 
     *   k = proto_k mod q
     * 
     * This has the interesting property that it's _deterministic_:
     * signing the same hash twice with the same key yields the
     * same signature.
     * 
     * Despite this determinism, it's still not predictable to an
     * attacker, because in order to repeat the SHA-512
     * construction that created it, the attacker would have to
     * know the private key value x - and by assumption he doesn't,
     * because if he knew that he wouldn't be attacking k!
     *
     * (This trick doesn't, _per se_, protect against reuse of k.
     * Reuse of k is left to chance; all it does is prevent
     * _excessively high_ chances of reuse of k due to entropy
     * problems.)
     * 
     * Thanks to Colin Plumb for the general idea of using x to
     * ensure k is hard to guess, and to the Cambridge University
     * Computer Security Group for helping to argue out all the
     * fine details.
     */
    struct dss_key *dss = (struct dss_key *) key;
    SHA512_State ss;
    unsigned char digest[20], digest512[64];
    Bignum proto_k, k, gkp, hash, kinv, hxr, r, s;
    unsigned char *bytes;
    int nbytes, i;

    SHA_Simple(data, datalen, digest);

    /*
     * Hash some identifying text plus x.
     */
    SHA512_Init(&ss);
    SHA512_Bytes(&ss, "DSA deterministic k generator", 30);
    sha512_mpint(&ss, dss->x);
    SHA512_Final(&ss, digest512);

    /*
     * Now hash that digest plus the message hash.
     */
    SHA512_Init(&ss);
    SHA512_Bytes(&ss, digest512, sizeof(digest512));
    SHA512_Bytes(&ss, digest, sizeof(digest));
    SHA512_Final(&ss, digest512);

    memset(&ss, 0, sizeof(ss));

    /*
     * Now convert the result into a bignum, and reduce it mod q.
     */
    proto_k = bignum_from_bytes(digest512, 64);
    k = bigmod(proto_k, dss->q);
    freebn(proto_k);

    memset(digest512, 0, sizeof(digest512));

    /*
     * Now we have k, so just go ahead and compute the signature.
     */
    gkp = modpow(dss->g, k, dss->p);   /* g^k mod p */
    r = bigmod(gkp, dss->q);	       /* r = (g^k mod p) mod q */
    freebn(gkp);

    hash = bignum_from_bytes(digest, 20);
    kinv = modinv(k, dss->q);	       /* k^-1 mod q */
    hxr = bigmuladd(dss->x, r, hash);  /* hash + x*r */
    s = modmul(kinv, hxr, dss->q);     /* s = k^-1 * (hash + x*r) mod q */
    freebn(hxr);
    freebn(kinv);
    freebn(hash);

    /*
     * Signature blob is
     * 
     *   string  "ssh-dss"
     *   string  two 20-byte numbers r and s, end to end
     * 
     * i.e. 4+7 + 4+40 bytes.
     */
    nbytes = 4 + 7 + 4 + 40;
    bytes = snewn(nbytes, unsigned char);
    PUT_32BIT(bytes, 7);
    memcpy(bytes + 4, "ssh-dss", 7);
    PUT_32BIT(bytes + 4 + 7, 40);
    for (i = 0; i < 20; i++) {
	bytes[4 + 7 + 4 + i] = bignum_byte(r, 19 - i);
	bytes[4 + 7 + 4 + 20 + i] = bignum_byte(s, 19 - i);
    }
    freebn(r);
    freebn(s);

    *siglen = nbytes;
    return bytes;
}
Beispiel #29
0
/** \brief Preforms RSA encryption on plaintext m using exponent e and modulus n\n
 * m^e mod n
 *
 * \param m int Plaintext
 * \param e int Encryption Exponent
 * \param n int Modulus
 * \return int Ciphertext
 *
 */
int encodeRSA(int m, int e, int n)
{
    int c;
    c = modpow(m, e, n);
    return c;
}