Exemplo n.º 1
0
int main(void)
{
   int res, x, y;
   char buf[4096];
   FILE *out;
   mp_int a, b;
   
   mp_init(&a);
   mp_init(&b);
   
   out = fopen("drprimes.txt", "w");
   for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) {
   top:
       printf("Seeking a %d-bit safe prime\n", sizes[x] * DIGIT_BIT);
       mp_grow(&a, sizes[x]);
       mp_zero(&a);
       for (y = 1; y < sizes[x]; y++) {
           a.dp[y] = MP_MASK;
       }
       
       /* make a DR modulus */
       a.dp[0] = -1;
       a.used = sizes[x];
       
       /* now loop */
       res = 0;
       for (;;) { 
          a.dp[0] += 4;
          if (a.dp[0] >= MP_MASK) break;
          mp_prime_is_prime(&a, 1, &res);
          if (res == 0) continue;
          printf("."); fflush(stdout);
          mp_sub_d(&a, 1, &b);
          mp_div_2(&b, &b);
          mp_prime_is_prime(&b, 3, &res);  
          if (res == 0) continue;
          mp_prime_is_prime(&a, 3, &res);
          if (res == 1) break;
	}
        
        if (res != 1) {
           printf("Error not DR modulus\n"); sizes[x] += 1; goto top;
        } else {
           mp_toradix(&a, buf, 10);
           printf("\n\np == %s\n\n", buf);
           fprintf(out, "%d-bit prime:\np == %s\n\n", mp_count_bits(&a), buf); fflush(out);
        }           
   }
   fclose(out);
   
   mp_clear(&a);
   mp_clear(&b);
   
   return 0;
}
Exemplo n.º 2
0
static void grow_and_negate(mp_int *a, int size, mp_int *b) {
    int i;
    int actual_size = MAX(size, USED(a));
    mp_zero(b);
    mp_grow(b, actual_size);
    USED(b) = actual_size;
    for (i = 0; i < actual_size; i++) {
        DIGIT(b, i) = (~DIGIT(a, i)) & MP_MASK;
    }
    mp_add_d(b, 1, b);
}
Exemplo n.º 3
0
/* set to zero */
void mp_zero_multi (mp_int * mp, ...)
{
    mp_int* next_mp = mp;
    va_list args;
    va_start(args, mp);
    while (next_mp != NULL) {
        mp_zero(next_mp);
        next_mp = va_arg(args, mp_int*);
    }
    va_end(args);
}
Exemplo n.º 4
0
/* Negates a field element.  Assumes that 0 <= a < meth->irr */
mp_err
ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
{
    /* PRE: 0 <= a < p = meth->irr POST: 0 <= r < p, r = -a (mod p) */

    if (mp_cmp_z(a) == 0) {
        mp_zero(r);
        return MP_OKAY;
    }
    return mp_sub(&meth->irr, a, r);
}
Exemplo n.º 5
0
 mpint( T value_,
     typename boost::enable_if<
     typename boost::is_integral<
     typename boost::remove_cv< T >::type
     >::type
     >::type* = NULL
     ) {
   MPINT_SAFE_CALL( mp_init( &value ) );
   mp_zero( &value );
   from_string( boost::lexical_cast< std::string >( value_ ), 10 );
 }
Exemplo n.º 6
0
/* shift right a certain amount of digits */
void mp_rshd (mp_int * a, int b)
{
  int     x;

  /* if b <= 0 then ignore it */
  if (b <= 0) {
    return;
  }

  /* if b > used then simply zero it and return */
  if (a->used <= b) {
    mp_zero (a);
    return;
  }

  {
    register mp_digit *bottom, *top;

    /* shift the digits down */

    /* bottom */
    bottom = a->dp;

    /* top [offset into digits] */
    top = a->dp + b;

    /* this is implemented as a sliding window where 
     * the window is b-digits long and digits from 
     * the top of the window are copied to the bottom
     *
     * e.g.

     b-2 | b-1 | b0 | b1 | b2 | ... | bb |   ---->
                 /\                   |      ---->
                  \-------------------/      ---->
     */
    for (x = 0; x < (a->used - b); x++) {
      *bottom++ = *top++;
    }

    /* zero the top digits */
    for (; x < a->used; x++) {
      *bottom++ = 0;
    }
  }
  
  /* remove excess digits */
  a->used -= b;
}
Exemplo n.º 7
0
/* based on gmp's mpz_import.
 * see http://gmplib.org/manual/Integer-Import-and-Export.html
 */
int mp_import(mp_int* rop, size_t count, int order, size_t size, 
                            int endian, size_t nails, const void* op) {
	int result;
	size_t odd_nails, nail_bytes, i, j;
	unsigned char odd_nail_mask;

	mp_zero(rop);

	if (endian == 0) {
		union {
			unsigned int i;
			char c[4];
		} lint;
		lint.i = 0x01020304;

		endian = (lint.c[0] == 4) ? -1 : 1;
	}

	odd_nails = (nails % 8);
	odd_nail_mask = 0xff;
	for (i = 0; i < odd_nails; ++i) {
		odd_nail_mask ^= (1 << (7 - i));
	}
	nail_bytes = nails / 8;

	for (i = 0; i < count; ++i) {
		for (j = 0; j < (size - nail_bytes); ++j) {
			unsigned char byte = *(
					(unsigned char*)op + 
					(((order == 1) ? i : ((count - 1) - i)) * size) +
					((endian == 1) ? (j + nail_bytes) : (((size - 1) - j) - nail_bytes))
				);

			if (
				(result = mp_mul_2d(rop, ((j == 0) ? (8 - odd_nails) : 8), rop)) != MP_OKAY) {
				return result;
			}

			rop->dp[0] |= (j == 0) ? (byte & odd_nail_mask) : byte;
			rop->used  += 1;
		}
	}

	mp_clamp(rop);

	return MP_OKAY;
}
Exemplo n.º 8
0
static void from_num(MVMnum64 d, mp_int *a) {
    MVMnum64 d_digit = pow(2, DIGIT_BIT);
    MVMnum64 da      = fabs(d);
    MVMnum64 upper;
    MVMnum64 lower;
    MVMnum64 lowest;
    MVMnum64 rest;
    int      digits  = 0;

    mp_zero(a);

    while (da > d_digit * d_digit * d_digit) {;
        da /= d_digit;
        digits++;
    }
    mp_grow(a, digits + 3);

    /* populate the top 3 digits */
    upper = da / (d_digit*d_digit);
    rest = fmod(da, d_digit*d_digit);
    lower = rest / d_digit;
    lowest = fmod(rest,d_digit );
    if (upper >= 1) {
        mp_set_long(a, (unsigned long) upper);
        mp_mul_2d(a, DIGIT_BIT , a);
        DIGIT(a, 0) = (mp_digit) lower;
        mp_mul_2d(a, DIGIT_BIT , a);
    } else {
        if (lower >= 1) {
            mp_set_long(a, (unsigned long) lower);
            mp_mul_2d(a, DIGIT_BIT , a);
            a->used = 2;
        } else {
            a->used = 1;
        }
    }
    DIGIT(a, 0) = (mp_digit) lowest;

    /* shift the rest */
    mp_mul_2d(a, DIGIT_BIT * digits, a);
    if (d < 0)
        mp_neg(a, a);
    mp_clamp(a);
    mp_shrink(a);
}
Exemplo n.º 9
0
/* read a bigint from a file stream in ASCII */
int mp_fread(mp_int *a, int radix, FILE *stream)
{
   int err, ch, neg, y;
   unsigned pos;

   /* clear a */
   mp_zero(a);

   /* if first digit is - then set negative */
   ch = fgetc(stream);
   if (ch == (int)'-') {
      neg = MP_NEG;
      ch = fgetc(stream);
   } else {
      neg = MP_ZPOS;
   }

   for (;;) {
      pos = (unsigned)(ch - (int)'(');
      if (mp_s_rmap_reverse_sz < pos) {
         break;
      }

      y = (int)mp_s_rmap_reverse[pos];

      if ((y == 0xff) || (y >= radix)) {
         break;
      }

      /* shift up and add */
      if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
         return err;
      }
      if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
         return err;
      }

      ch = fgetc(stream);
   }
   if (mp_cmp_d(a, 0uL) != MP_EQ) {
      a->sign = neg;
   }

   return MP_OKAY;
}
Exemplo n.º 10
0
/* read a bigint from a file stream in ASCII */
int mp_fread(mp_int *a, int radix, FILE *stream)
{
   int err, ch, neg, y;

   /* clear a */
   mp_zero(a);

   /* if first digit is - then set negative */
   ch = fgetc(stream);
   if (ch == '-') {
      neg = MP_NEG;
      ch = fgetc(stream);
   } else {
      neg = MP_ZPOS;
   }

   for (;;) {
      /* find y in the radix map */
      for (y = 0; y < radix; y++) {
          if (mp_s_rmap[y] == ch) {
             break;
          }
      }
      if (y == radix) {
         break;
      }

      /* shift up and add */
      if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
         return err;
      }
      if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
         return err;
      }

      ch = fgetc(stream);
   }
   if (mp_cmp_d(a, 0) != MP_EQ) {
      a->sign = neg;
   }

   return MP_OKAY;
}
Exemplo n.º 11
0
int mp_rand(mp_int* a, int digits, WC_RNG* rng)
{
    int ret;
    mp_digit d;

    if (rng == NULL)
        return MISSING_RNG_E;

    if (a == NULL)
        return BAD_FUNC_ARG;

    mp_zero(a);
    if (digits <= 0) {
        return MP_OKAY;
    }

    /* first place a random non-zero digit */
    do {
        ret = get_rand_digit(rng, &d);
        if (ret != 0) {
            return ret;
        }
    } while (d == 0);

    if ((ret = mp_add_d(a, d, a)) != MP_OKAY) {
        return ret;
    }

    while (--digits > 0) {
        if ((ret = mp_lshd(a, 1)) != MP_OKAY) {
            return ret;
        }
        if ((ret = get_rand_digit(rng, &d)) != 0) {
            return ret;
        }
        if ((ret = mp_add_d(a, d, a)) != MP_OKAY) {
            return ret;
        }
    }

    return ret;
}
Exemplo n.º 12
0
/* computes a = 2**b 
 *
 * Simple algorithm which zeroes the int, grows it then just sets one bit
 * as required.
 */
int mp_2expt(mp_int * a, int b)
{
	int res;

	/* zero a as per default */
	mp_zero(a);

	/* grow a to accomodate the single bit */
	if ((res = mp_grow(a, b / DIGIT_BIT + 1)) != MP_OKAY) {
		return res;
	}

	/* set the used count of where the bit will go */
	a->used = b / DIGIT_BIT + 1;

	/* put the single bit in its place */
	a->dp[b / DIGIT_BIT] = 1 << (b % DIGIT_BIT);

	return MP_OKAY;
}
Exemplo n.º 13
0
/* reads a unsigned char array, assumes the msb is stored first [big endian] */
int
mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c)
{
  int     res;
  mp_zero (a);
  while (c-- > 0) {
    if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
      return res;
    }

    if (DIGIT_BIT != 7) {
      a->dp[0] |= *b++;
      a->used += 1;
    } else {
      a->dp[0] = (*b & MP_MASK);
      a->dp[1] |= ((*b++ >> 7U) & 1);
      a->used += 2;
    }
  }
  mp_clamp (a);
  return MP_OKAY;
}
Exemplo n.º 14
0
/* Retrieve an mp_int from the buffer.
 * Will fail for -ve since they shouldn't be required here.
 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
int buf_getmpint(buffer* buf, mp_int* mp) {

	unsigned int len;
	len = buf_getint(buf);
	
	if (len == 0) {
		mp_zero(mp);
		return DROPBEAR_SUCCESS;
	}

	/* check for negative */
	if (*buf_getptr(buf, 1) & (1 << (CHAR_BIT-1))) {
		return DROPBEAR_FAILURE;
	}

	if (mp_read_unsigned_bin(mp, buf_getptr(buf, len), len) != MP_OKAY) {
		return DROPBEAR_FAILURE;
	}

	buf_incrpos(buf, len);
	return DROPBEAR_SUCCESS;
}
Exemplo n.º 15
0
int mp_rand(mp_int *a, int digits)
{
   int     res;
   mp_digit d;

   mp_zero(a);
   if (digits <= 0) {
      return MP_OKAY;
   }

   /* first place a random non-zero digit */
   do {
      if (mp_rand_digit(&d) != MP_OKAY) {
         return MP_VAL;
      }
   } while (d == 0u);

   if ((res = mp_add_d(a, d, a)) != MP_OKAY) {
      return res;
   }

   while (--digits > 0) {
      if ((res = mp_lshd(a, 1)) != MP_OKAY) {
         return res;
      }

      if (mp_rand_digit(&d) != MP_OKAY) {
         return MP_VAL;
      }
      if ((res = mp_add_d(a, d, a)) != MP_OKAY) {
         return res;
      }
   }

   return MP_OKAY;
}
Exemplo n.º 16
0
/* If U = V, W = 0
 * If U > V, W = (U - V) mod M
 * If U < V, W = M - ((V - U) mod M) */
void
mp_modsub(const mp_digit *u, const mp_digit *v,
		  const mp_digit *m, mp_size msize, mp_digit *w)
{
    ASSERT(u != NULL);
    ASSERT(v != NULL);
    ASSERT(m != NULL);
    ASSERT(msize != 0);
    ASSERT(m[msize - 1] != 0);
    ASSERT(w != NULL);

    ASSERT(mp_cmp_n(u, m, msize) < 0);
    ASSERT(mp_cmp_n(v, m, msize) < 0);

    const int cmp = mp_cmp_n(u, v, msize);
    if (cmp == 0) {
	mp_zero(w, msize);
    } else if (cmp > 0) {
	ASSERT(mp_sub_n(u, v, msize, w) == 0);
    } else /* cmp < 0 */ {
	ASSERT(mp_sub_n(v, u, msize, w) == 0);	/* w <- v - u */
	ASSERT(mp_sub_n(m, w, msize, w) == 0);	/* w <- m - w */
    }
}
Exemplo n.º 17
0
/* Taken from mp_set_long, but portably accepts a 64-bit number. */
int MVM_bigint_mp_set_uint64(mp_int * a, MVMuint64 b) {
  int     x, res;

  mp_zero (a);

  /* set four bits at a time */
  for (x = 0; x < sizeof(MVMuint64) * 2; x++) {
    /* shift the number up four bits */
    if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
      return res;
    }

    /* OR in the top four bits of the source */
    a->dp[0] |= (b >> ((sizeof(MVMuint64)) * 8 - 4)) & 15;

    /* shift the source up to the next four bits */
    b <<= 4;

    /* ensure that digits are not clamped off */
    a->used += 1;
  }
  mp_clamp(a);
  return MP_OKAY;
}
Exemplo n.º 18
0
int main(int argc, char *argv[])
{
  unsigned char *raw, *out;
  int		rawlen, bits, outlen, ngen, ix, jx;
  mp_int	testval, q, ntries;
  mp_err	res;
  mp_digit      np;
  clock_t	start, end;

#ifdef MACOS
  argc = ccommand(&argv);
#endif

  /* We'll just use the C library's rand() for now, although this
     won't be good enough for cryptographic purposes */

  if((out = (unsigned char *)getenv("SEED")) == NULL) {
    srand((unsigned int)time(NULL));
  } else {
    srand((unsigned int)atoi((char *)out));
  }

  if(argc < 2) {
    fprintf(stderr, "Usage: %s <bits> [<count> [strong]]\n", argv[0]);
    return 1;
  }
	
  if((bits = abs(atoi(argv[1]))) < CHAR_BIT) {
    fprintf(stderr, "%s: please request at least %d bits.\n",
	    argv[0], CHAR_BIT);
    return 1;
  }

  /* If optional third argument is given, use that as the number of
     primes to generate; otherwise generate one prime only.
   */
  if(argc < 3) {
    ngen = 1;
  } else {
    ngen = abs(atoi(argv[2]));
  }

  /* If fourth argument is given, and is the word "strong", we'll 
     generate strong (Sophie Germain) primes. 
   */
  if(argc > 3 && strcmp(argv[3], "strong") == 0)
    g_strong = 1;

  /* testval - candidate being tested
     ntries  - number tried so far 
     q       - used in finding strong primes 
   */
  if((res = mp_init(&testval)) != MP_OKAY ||
     (res = mp_init(&ntries)) != MP_OKAY ||
     (res = mp_init(&q)) != MP_OKAY) {
    fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res));
    return 1;
  }
  
  if(g_strong) {
    printf("Requested %d strong prime values of at least %d bits.\n", 
	   ngen, bits);
  } else {
    printf("Requested %d prime values of at least %d bits.\n", ngen, bits);
  }

  rawlen = (bits / CHAR_BIT) + ((bits % CHAR_BIT) ? 1 : 0);

  if((raw = calloc(rawlen, sizeof(unsigned char))) == NULL) {
    fprintf(stderr, "%s: out of memory, sorry.\n", argv[0]);
    return 1;
  }

  /* This loop is one for each prime we need to generate */
  for(jx = 0; jx < ngen; jx++) {

    /*	Pack the initializer with random bytes	*/
    for(ix = 0; ix < rawlen; ix++) 
      raw[ix] = (rand() * rand()) & UCHAR_MAX;

    raw[0] |= 0x80;             /* set high-order bit of test value     */
    if(g_strong)
      raw[rawlen - 1] |= 7;     /* set low-order 3 bits of test value   */
    else
      raw[rawlen - 1] |= 1;     /* set low-order bit of test value      */

    /* Make an mp_int out of the initializer */
    mp_read_unsigned_bin(&testval, raw, rawlen);

    /* If we asked for a strong prime, shift down one bit so that when
       we double, we're still within the right range of bits ... this
       is why we OR'd with 7 instead of 1 above (leaves two bits set 
       so that the value remains congruent to 3 (mod 4)).
     */
    if(g_strong) {
      mp_copy(&testval, &q);
      mp_div_2(&testval, &testval);
    }      

    /* Initialize candidate counter */
    mp_zero(&ntries);
    mp_add_d(&ntries, 1, &ntries);

    start = clock(); /* time generation for this prime */
    for(;;) {
      /*
	Test for divisibility by small primes (of which there is a table 
	conveniently stored in mpprime.c)
      */
      np = prime_tab_size;

      if(mpp_divis_primes(&testval, &np) == MP_NO) {

	/* If we're trying for a strong prime, test 2p+1 before
	   running other primality tests */
	if(g_strong) {
	  np = prime_tab_size;
	  if(mpp_divis_primes(&q, &np) == MP_YES)
	    goto NEXT_CANDIDATE;
	}

	/* If that passed, run a Fermat test */
	res = mpp_fermat(&testval, 2);
	switch(res) {
	case MP_NO:     /* composite        */
	  goto NEXT_CANDIDATE;
	case MP_YES:    /* may be prime     */
	  break;
	default:
	  goto CLEANUP; /* some other error */
	}
	
	/* If that passed, run some Miller-Rabin tests	*/
	res = mpp_pprime(&testval, NUM_TESTS);
	switch(res) {
	case MP_NO:     /* composite        */
	  goto NEXT_CANDIDATE;
	case MP_YES:    /* may be prime     */
	  break;
	default:
	  goto CLEANUP; /* some other error */
	}

	/* At this point, we have strong evidence that our candidate
	   is itself prime.  If we want a strong prime, we need now
	   to test q = 2p + 1 for primality...
	 */
 	if(g_strong) {
	  if(res == MP_YES) {
	    fputc('.', stderr);

	    /* If we get here, we've already tested q against small
	       prime divisors, so we can just do the regular primality
	       testing
	     */

	    /* Fermat, as with its parent ... */
	    res = mpp_fermat(&q, 2);
	    switch(res) {
	    case MP_NO:     /* composite        */
	      goto NEXT_CANDIDATE;
	    case MP_YES:    /* may be prime     */
	      break;
	    default:
	      goto CLEANUP; /* some other error */
	    }

	    /* And, with Miller-Rabin, as with its parent ... */
	    res = mpp_pprime(&q, NUM_TESTS);
	    switch(res) {
	    case MP_NO:     /* composite        */
	      goto NEXT_CANDIDATE;
	    case MP_YES:    /* may be prime     */
	      break;
	    default:
	      goto CLEANUP; /* some other error */
	    }
	  
	    /* If it passed, we've got a winner */
	    if(res == MP_YES) {
	      fputc('\n', stderr);
	      mp_copy(&q, &testval);
	      break;
	    }

	  } /* end if(res == MP_YES) */

	} else {
	  /* We get here if g_strong is false */
	  if(res == MP_YES)
	    break;
	}
      } /* end if(not divisible by small primes) */
      
      /*
	If we're testing strong primes, skip to the next odd value
	congruent to 3 (mod 4).  Otherwise, just skip to the next odd
	value
       */
    NEXT_CANDIDATE:
      if(g_strong) {
	mp_add_d(&q, 4, &q);
	mp_div_2(&q, &testval);
      } else
	mp_add_d(&testval, 2, &testval);
      mp_add_d(&ntries, 1, &ntries);
    } /* end of loop to generate a single prime */
    end = clock();
    
    printf("After %d tests, the following value is still probably prime:\n",
	   NUM_TESTS);
    outlen = mp_radix_size(&testval, 10);
    out = calloc(outlen, sizeof(unsigned char));
    mp_toradix(&testval, out, 10);
    printf("10: %s\n", (char *)out);
    mp_toradix(&testval, out, 16);
    printf("16: %s\n\n", (char *)out);
    free(out);
    
    printf("Number of candidates tried: ");
    outlen = mp_radix_size(&ntries, 10);
    out = calloc(outlen, sizeof(unsigned char));
    mp_toradix(&ntries, out, 10);
    printf("%s\n", (char *)out);
    free(out);

    printf("This computation took %ld clock ticks (%.2f seconds)\n",
	   (end - start), ((double)(end - start) / CLOCKS_PER_SEC));
    
    fputc('\n', stdout);
  } /* end of loop to generate all requested primes */
  
 CLEANUP:
  if(res != MP_OKAY) 
    fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res));

  free(raw);
  mp_clear(&testval); mp_clear(&q); mp_clear(&ntries);
  
  return 0;
}
Exemplo n.º 19
0
/*
 * Try to find the two primes based on 2 exponents plus either a prime
 *   or a modulus.
 *
 * In: e, d and either p or n (depending on the setting of hasModulus).
 * Out: p,q.
 * 
 * Step 1, Since d = e**-1 mod phi, we know that d*e == 1 mod phi, or
 *	d*e = 1+k*phi, or d*e-1 = k*phi. since d is less than phi and e is
 *	usually less than d, then k must be an integer between e-1 and 1 
 *	(probably on the order of e).
 * Step 1a, If we were passed just a prime, we can divide k*phi by that
 *      prime-1 and get k*(q-1). This will reduce the size of our division
 *      through the rest of the loop.
 * Step 2, Loop through the values k=e-1 to 1 looking for k. k should be on
 *	the order or e, and e is typically small. This may take a while for
 *	a large random e. We are looking for a k that divides kphi
 *	evenly. Once we find a k that divides kphi evenly, we assume it 
 *	is the true k. It's possible this k is not the 'true' k but has 
 *	swapped factors of p-1 and/or q-1. Because of this, we 
 *	tentatively continue Steps 3-6 inside this loop, and may return looking
 *	for another k on failure.
 * Step 3, Calculate are tentative phi=kphi/k. Note: real phi is (p-1)*(q-1).
 * Step 4a, if we have a prime, kphi is already k*(q-1), so phi is or tenative
 *      q-1. q = phi+1. If k is correct, q should be the right length and 
 *      prime.
 * Step 4b, It's possible q-1 and k could have swapped factors. We now have a
 * 	possible solution that meets our criteria. It may not be the only 
 *      solution, however, so we keep looking. If we find more than one, 
 *      we will fail since we cannot determine which is the correct
 *      solution, and returning the wrong modulus will compromise both
 *      moduli. If no other solution is found, we return the unique solution.
 * Step 5a, If we have the modulus (n=pq), then use the following formula to 
 * 	calculate  s=(p+q): , phi = (p-1)(q-1) = pq  -p-q +1 = n-s+1. so
 *	s=n-phi+1.
 * Step 5b, Use n=pq and s=p+q to solve for p and q as follows:
 *	since q=s-p, then n=p*(s-p)= sp - p^2, rearranging p^2-s*p+n = 0.
 *	from the quadratic equation we have p=1/2*(s+sqrt(s*s-4*n)) and
 *	q=1/2*(s-sqrt(s*s-4*n)) if s*s-4*n is a perfect square, we are DONE.
 *	If it is not, continue in our look looking for another k. NOTE: the
 *	code actually distributes the 1/2 and results in the equations:
 *	sqrt = sqrt(s/2*s/2-n), p=s/2+sqrt, q=s/2-sqrt. The algebra saves us
 *	and extra divide by 2 and a multiply by 4.
 * 
 * This will return p & q. q may be larger than p in the case that p was given
 * and it was the smaller prime.
 */
static mp_err
rsa_get_primes_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q,
			      mp_int *n, PRBool hasModulus, 
			      unsigned int keySizeInBits)
{
    mp_int kphi; /* k*phi */
    mp_int k;    /* current guess at 'k' */
    mp_int phi;  /* (p-1)(q-1) */
    mp_int s;    /* p+q/2 (s/2 in the algebra) */
    mp_int r;    /* remainder */
    mp_int tmp; /* p-1 if p is given, n+1 is modulus is given */
    mp_int sqrt; /* sqrt(s/2*s/2-n) */
    mp_err err = MP_OKAY;
    unsigned int order_k;

    MP_DIGITS(&kphi) = 0;
    MP_DIGITS(&phi) = 0;
    MP_DIGITS(&s) = 0;
    MP_DIGITS(&k) = 0;
    MP_DIGITS(&r) = 0;
    MP_DIGITS(&tmp) = 0;
    MP_DIGITS(&sqrt) = 0;
    CHECK_MPI_OK( mp_init(&kphi) );
    CHECK_MPI_OK( mp_init(&phi) );
    CHECK_MPI_OK( mp_init(&s) );
    CHECK_MPI_OK( mp_init(&k) );
    CHECK_MPI_OK( mp_init(&r) );
    CHECK_MPI_OK( mp_init(&tmp) );
    CHECK_MPI_OK( mp_init(&sqrt) );

    /* our algorithm looks for a factor k whose maximum size is dependent
     * on the size of our smallest exponent, which had better be the public
     * exponent (if it's the private, the key is vulnerable to a brute force
     * attack).
     * 
     * since our factor search is linear, we need to limit the maximum
     * size of the public key. this should not be a problem normally, since 
     * public keys are usually small. 
     *
     * if we want to handle larger public key sizes, we should have
     * a version which tries to 'completely' factor k*phi (where completely
     * means 'factor into primes, or composites with which are products of
     * large primes). Once we have all the factors, we can sort them out and
     * try different combinations to form our phi. The risk is if (p-1)/2,
     * (q-1)/2, and k are all large primes. In any case if the public key
     * is small (order of 20 some bits), then a linear search for k is 
     * manageable.
     */
    if (mpl_significant_bits(e) > 23) {
	err=MP_RANGE;
	goto cleanup;
    }

    /* calculate k*phi = e*d - 1 */
    CHECK_MPI_OK( mp_mul(e, d, &kphi) );
    CHECK_MPI_OK( mp_sub_d(&kphi, 1, &kphi) );


    /* kphi is (e*d)-1, which is the same as k*(p-1)(q-1)
     * d < (p-1)(q-1), therefor k must be less than e-1
     * We can narrow down k even more, though. Since p and q are odd and both 
     * have their high bit set, then we know that phi must be on order of 
     * keySizeBits.
     */
    order_k = (unsigned)mpl_significant_bits(&kphi) - keySizeInBits;

    /* for (k=kinit; order(k) >= order_k; k--) { */
    /* k=kinit: k can't be bigger than  kphi/2^(keySizeInBits -1) */
    CHECK_MPI_OK( mp_2expt(&k,keySizeInBits-1) );
    CHECK_MPI_OK( mp_div(&kphi, &k, &k, NULL));
    if (mp_cmp(&k,e) >= 0) {
	/* also can't be bigger then e-1 */
        CHECK_MPI_OK( mp_sub_d(e, 1, &k) );
    }

    /* calculate our temp value */
    /* This saves recalculating this value when the k guess is wrong, which
     * is reasonably frequent. */
    /* for the modulus case, tmp = n+1 (used to calculate p+q = tmp - phi) */
    /* for the prime case, tmp = p-1 (used to calculate q-1= phi/tmp) */
    if (hasModulus) {
	CHECK_MPI_OK( mp_add_d(n, 1, &tmp) );
    } else {
	CHECK_MPI_OK( mp_sub_d(p, 1, &tmp) );
	CHECK_MPI_OK(mp_div(&kphi,&tmp,&kphi,&r));
	if (mp_cmp_z(&r) != 0) {
	    /* p-1 doesn't divide kphi, some parameter wasn't correct */
	    err=MP_RANGE;
	    goto cleanup;
	}
	mp_zero(q);
	/* kphi is now k*(q-1) */
    }

    /* rest of the for loop */
    for (; (err == MP_OKAY) && (mpl_significant_bits(&k) >= order_k); 
						err = mp_sub_d(&k, 1, &k)) {
	/* looking for k as a factor of kphi */
	CHECK_MPI_OK(mp_div(&kphi,&k,&phi,&r));
	if (mp_cmp_z(&r) != 0) {
	    /* not a factor, try the next one */
	    continue;
	}
	/* we have a possible phi, see if it works */
	if (!hasModulus) {
	    if ((unsigned)mpl_significant_bits(&phi) != keySizeInBits/2) {
		/* phi is not the right size */
		continue;
	    }
	    /* phi should be divisible by 2, since
	     * q is odd and phi=(q-1). */
	    if (mpp_divis_d(&phi,2) == MP_NO) {
		/* phi is not divisible by 4 */
		continue;
	    }
	    /* we now have a candidate for the second prime */
	    CHECK_MPI_OK(mp_add_d(&phi, 1, &tmp));
	    
	    /* check to make sure it is prime */
	    err = rsa_is_prime(&tmp);
	    if (err != MP_OKAY) {
		if (err == MP_NO) {
		    /* No, then we still have the wrong phi */
		    err = MP_OKAY;
        	    continue;
		}
		goto cleanup;
	    }
	    /*
	     * It is possible that we have the wrong phi if 
	     * k_guess*(q_guess-1) = k*(q-1) (k and q-1 have swapped factors).
	     * since our q_quess is prime, however. We have found a valid
	     * rsa key because:
	     *   q is the correct order of magnitude.
	     *   phi = (p-1)(q-1) where p and q are both primes.
	     *   e*d mod phi = 1.
	     * There is no way to know from the info given if this is the 
	     * original key. We never want to return the wrong key because if
	     * two moduli with the same factor is known, then euclid's gcd
	     * algorithm can be used to find that factor. Even though the 
	     * caller didn't pass the original modulus, it doesn't mean the
	     * modulus wasn't known or isn't available somewhere. So to be safe
	     * if we can't be sure we have the right q, we don't return any.
	     * 
	     * So to make sure we continue looking for other valid q's. If none
	     * are found, then we can safely return this one, otherwise we just
	     * fail */
	    if (mp_cmp_z(q) != 0) {
		/* this is the second valid q, don't return either, 
		 * just fail */
		err = MP_RANGE;
		break;
	    }
	    /* we only have one q so far, save it and if no others are found,
	     * it's safe to return it */
	    CHECK_MPI_OK(mp_copy(&tmp, q));
	    continue;
	}
	/* test our tentative phi */
	/* phi should be the correct order */
	if ((unsigned)mpl_significant_bits(&phi) != keySizeInBits) {
	    /* phi is not the right size */
	    continue;
	}
	/* phi should be divisible by 4, since
	 * p and q are odd and phi=(p-1)(q-1). */
	if (mpp_divis_d(&phi,4) == MP_NO) {
	    /* phi is not divisible by 4 */
	    continue;
	}
	/* n was given, calculate s/2=(p+q)/2 */
	CHECK_MPI_OK( mp_sub(&tmp, &phi, &s) );
	CHECK_MPI_OK( mp_div_2(&s, &s) );

	/* calculate sqrt(s/2*s/2-n) */
	CHECK_MPI_OK(mp_sqr(&s,&sqrt));
	CHECK_MPI_OK(mp_sub(&sqrt,n,&r));  /* r as a tmp */
	CHECK_MPI_OK(mp_sqrt(&r,&sqrt));
	/* make sure it's a perfect square */
	/* r is our original value we took the square root of */
	/* q is the square of our tentative square root. They should be equal*/
	CHECK_MPI_OK(mp_sqr(&sqrt,q)); /* q as a tmp */
	if (mp_cmp(&r,q) != 0) {
	    /* sigh according to the doc, mp_sqrt could return sqrt-1 */
	   CHECK_MPI_OK(mp_add_d(&sqrt,1,&sqrt));
	   CHECK_MPI_OK(mp_sqr(&sqrt,q));
	   if (mp_cmp(&r,q) != 0) {
		/* s*s-n not a perfect square, this phi isn't valid, find 			 * another.*/
		continue;
	    }
	}

	/* NOTE: In this case we know we have the one and only answer.
	 * "Why?", you ask. Because:
	 *    1) n is a composite of two large primes (or it wasn't a
	 *       valid RSA modulus).
	 *    2) If we know any number such that x^2-n is a perfect square 
	 *       and x is not (n+1)/2, then we can calculate 2 non-trivial
	 *       factors of n.
	 *    3) Since we know that n has only 2 non-trivial prime factors, 
	 *       we know the two factors we have are the only possible factors.
	 */

	/* Now we are home free to calculate p and q */
	/* p = s/2 + sqrt, q= s/2 - sqrt */
	CHECK_MPI_OK(mp_add(&s,&sqrt,p));
	CHECK_MPI_OK(mp_sub(&s,&sqrt,q));
	break;
    }
    if ((unsigned)mpl_significant_bits(&k) < order_k) {
	if (hasModulus || (mp_cmp_z(q) == 0)) {
	    /* If we get here, something was wrong with the parameters we 
	     * were given */
	    err = MP_RANGE; 
	}
    }
cleanup:
    mp_clear(&kphi);
    mp_clear(&phi);
    mp_clear(&s);
    mp_clear(&k);
    mp_clear(&r);
    mp_clear(&tmp);
    mp_clear(&sqrt);
    return err;
}
Exemplo n.º 20
0
/* integer signed division. 
 * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
 * HAC pp.598 Algorithm 14.20
 *
 * Note that the description in HAC is horribly 
 * incomplete.  For example, it doesn't consider 
 * the case where digits are removed from 'x' in 
 * the inner loop.  It also doesn't consider the 
 * case that y has fewer than three digits, etc..
 *
 * The overall algorithm is as described as 
 * 14.20 from HAC but fixed to treat these cases.
*/
int mp_div MPA(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
{
  mp_int  q, x, y, t1, t2;
  int     res, n, t, i, norm, neg;

  /* is divisor zero ? */
  if (mp_iszero (b) == 1) {
    return MP_VAL;
  }

  /* if a < b then q=0, r = a */
  if (mp_cmp_mag (a, b) == MP_LT) {
    if (d != NULL) {
      res = mp_copy (MPST, a, d);
    } else {
      res = MP_OKAY;
    }
    if (c != NULL) {
      mp_zero (c);
    }
    return res;
  }

  if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
    return res;
  }
  q.used = a->used + 2;

  if ((res = mp_init (&t1)) != MP_OKAY) {
    goto LBL_Q;
  }

  if ((res = mp_init (&t2)) != MP_OKAY) {
    goto LBL_T1;
  }

  if ((res = mp_init_copy (MPST, &x, a)) != MP_OKAY) {
    goto LBL_T2;
  }

  if ((res = mp_init_copy (MPST, &y, b)) != MP_OKAY) {
    goto LBL_X;
  }

  /* fix the sign */
  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
  x.sign = y.sign = MP_ZPOS;

  /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
  norm = mp_count_bits(&y) % DIGIT_BIT;
  if (norm < (int)(DIGIT_BIT-1)) {
     norm = (DIGIT_BIT-1) - norm;
     if ((res = mp_mul_2d (MPST, &x, norm, &x)) != MP_OKAY) {
       goto LBL_Y;
     }
     if ((res = mp_mul_2d (MPST, &y, norm, &y)) != MP_OKAY) {
       goto LBL_Y;
     }
  } else {
     norm = 0;
  }

  /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
  n = x.used - 1;
  t = y.used - 1;

  /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
  if ((res = mp_lshd (MPST, &y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
    goto LBL_Y;
  }

  while (mp_cmp (&x, &y) != MP_LT) {
    ++(q.dp[n - t]);
    if ((res = mp_sub (MPST, &x, &y, &x)) != MP_OKAY) {
      goto LBL_Y;
    }
  }

  /* reset y by shifting it back down */
  mp_rshd (&y, n - t);

  /* step 3. for i from n down to (t + 1) */
  for (i = n; i >= (t + 1); i--) {
    if (i > x.used) {
      continue;
    }

    /* step 3.1 if xi == yt then set q{i-t-1} to b-1, 
     * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
    if (x.dp[i] == y.dp[t]) {
      q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
    } else {
      mp_word tmp;
      tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
      tmp |= ((mp_word) x.dp[i - 1]);
      tmp /= ((mp_word) y.dp[t]);
      if (tmp > (mp_word) MP_MASK)
        tmp = MP_MASK;
      q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
    }

    /* while (q{i-t-1} * (yt * b + y{t-1})) > 
             xi * b**2 + xi-1 * b + xi-2 
     
       do q{i-t-1} -= 1; 
    */
    q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK;
    do {
      q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK;

      /* find left hand */
      mp_zero (&t1);
      t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
      t1.dp[1] = y.dp[t];
      t1.used = 2;
      if ((res = mp_mul_d (MPST, &t1, q.dp[i - t - 1], &t1)) != MP_OKAY) {
        goto LBL_Y;
      }

      /* find right hand */
      t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
      t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
      t2.dp[2] = x.dp[i];
      t2.used = 3;
    } while (mp_cmp_mag(&t1, &t2) == MP_GT);

    /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
    if ((res = mp_mul_d (MPST, &y, q.dp[i - t - 1], &t1)) != MP_OKAY) {
      goto LBL_Y;
    }

    if ((res = mp_lshd (MPST, &t1, i - t - 1)) != MP_OKAY) {
      goto LBL_Y;
    }

    if ((res = mp_sub (MPST, &x, &t1, &x)) != MP_OKAY) {
      goto LBL_Y;
    }

    /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
    if (x.sign == MP_NEG) {
      if ((res = mp_copy (MPST, &y, &t1)) != MP_OKAY) {
        goto LBL_Y;
      }
      if ((res = mp_lshd (MPST, &t1, i - t - 1)) != MP_OKAY) {
        goto LBL_Y;
      }
      if ((res = mp_add (MPST, &x, &t1, &x)) != MP_OKAY) {
        goto LBL_Y;
      }

      q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK;
    }
  }

  /* now q is the quotient and x is the remainder 
   * [which we have to normalize] 
   */
  
  /* get sign before writing to c */
  x.sign = x.used == 0 ? MP_ZPOS : a->sign;

  if (c != NULL) {
    mp_clamp (&q);
    mp_managed_copy (MPST, &q, c);
    c->sign = neg;
  }

  if (d != NULL) {
    mp_div_2d (MPST, &x, norm, &x, NULL);
    mp_managed_copy (MPST, &x, d);
  }

  res = MP_OKAY;

LBL_Y:mp_clear (&y);
LBL_X:mp_clear (&x);
LBL_T2:mp_clear (&t2);
LBL_T1:mp_clear (&t1);
LBL_Q:mp_clear (&q);
  return res;
}
Exemplo n.º 21
0
/* slower bit-bang division... also smaller */
int mp_div MPA(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
{
   mp_int ta, tb, tq, q;
   int    res, n, n2;

  /* is divisor zero ? */
  if (mp_iszero (b) == 1) {
    return MP_VAL;
  }

  /* if a < b then q=0, r = a */
  if (mp_cmp_mag (a, b) == MP_LT) {
    if (d != NULL) {
      res = mp_copy (a, d);
    } else {
      res = MP_OKAY;
    }
    if (c != NULL) {
      mp_zero (c);
    }
    return res;
  }
	
  /* init our temps */
  if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) {
     return res;
  }


  mp_set(&tq, 1);
  n = mp_count_bits(a) - mp_count_bits(b);
  if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
      ((res = mp_abs(b, &tb)) != MP_OKAY) || 
      ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
      ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
      goto LBL_ERR;
  }

  while (n-- >= 0) {
     if (mp_cmp(&tb, &ta) != MP_GT) {
        if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
            ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
           goto LBL_ERR;
        }
     }
     if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
         ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
           goto LBL_ERR;
     }
  }

  /* now q == quotient and ta == remainder */
  n  = a->sign;
  n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
  if (c != NULL) {
     mp_exch(c, &q);
     c->sign  = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
  }
  if (d != NULL) {
     mp_exch(d, &ta);
     d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
  }
LBL_ERR:
   mp_clear_multi(&ta, &tb, &tq, &q, NULL);
   return res;
}
Exemplo n.º 22
0
/* set to a digit */
void mp_set (mp_int * a, mp_digit b)
{
  mp_zero (a);
  a->dp[0] = b & MP_MASK;
  a->used  = (a->dp[0] != 0) ? 1 : 0;
}
Exemplo n.º 23
0
/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
 * using Montgomery point multiplication algorithm Mxy() in appendix of
 * Lopex, J. and Dahab, R.  "Fast multiplication on elliptic curves over
 * GF(2^m) without precomputation". Returns: 0 on error 1 if return value
 * should be the point at infinity 2 otherwise */
static int
gf2m_Mxy(const mp_int *x, const mp_int *y, mp_int *x1, mp_int *z1,
                 mp_int *x2, mp_int *z2, const ECGroup *group)
{
        mp_err res = MP_OKAY;
        int ret = 0;
        mp_int t3, t4, t5;

        MP_DIGITS(&t3) = 0;
        MP_DIGITS(&t4) = 0;
        MP_DIGITS(&t5) = 0;
        MP_CHECKOK(mp_init(&t3, FLAG(x2)));
        MP_CHECKOK(mp_init(&t4, FLAG(x2)));
        MP_CHECKOK(mp_init(&t5, FLAG(x2)));

        if (mp_cmp_z(z1) == 0) {
                mp_zero(x2);
                mp_zero(z2);
                ret = 1;
                goto CLEANUP;
        }

        if (mp_cmp_z(z2) == 0) {
                MP_CHECKOK(mp_copy(x, x2));
                MP_CHECKOK(group->meth->field_add(x, y, z2, group->meth));
                ret = 2;
                goto CLEANUP;
        }

        MP_CHECKOK(mp_set_int(&t5, 1));
        if (group->meth->field_enc) {
                MP_CHECKOK(group->meth->field_enc(&t5, &t5, group->meth));
        }

        MP_CHECKOK(group->meth->field_mul(z1, z2, &t3, group->meth));

        MP_CHECKOK(group->meth->field_mul(z1, x, z1, group->meth));
        MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
        MP_CHECKOK(group->meth->field_mul(z2, x, z2, group->meth));
        MP_CHECKOK(group->meth->field_mul(z2, x1, x1, group->meth));
        MP_CHECKOK(group->meth->field_add(z2, x2, z2, group->meth));

        MP_CHECKOK(group->meth->field_mul(z2, z1, z2, group->meth));
        MP_CHECKOK(group->meth->field_sqr(x, &t4, group->meth));
        MP_CHECKOK(group->meth->field_add(&t4, y, &t4, group->meth));
        MP_CHECKOK(group->meth->field_mul(&t4, &t3, &t4, group->meth));
        MP_CHECKOK(group->meth->field_add(&t4, z2, &t4, group->meth));

        MP_CHECKOK(group->meth->field_mul(&t3, x, &t3, group->meth));
        MP_CHECKOK(group->meth->field_div(&t5, &t3, &t3, group->meth));
        MP_CHECKOK(group->meth->field_mul(&t3, &t4, &t4, group->meth));
        MP_CHECKOK(group->meth->field_mul(x1, &t3, x2, group->meth));
        MP_CHECKOK(group->meth->field_add(x2, x, z2, group->meth));

        MP_CHECKOK(group->meth->field_mul(z2, &t4, z2, group->meth));
        MP_CHECKOK(group->meth->field_add(z2, y, z2, group->meth));

        ret = 2;

  CLEANUP:
        mp_clear(&t3);
        mp_clear(&t4);
        mp_clear(&t5);
        if (res == MP_OKAY) {
                return ret;
        } else {
                return 0;
        }
}
Exemplo n.º 24
0
/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G + 
 * k2 * P(x, y), where G is the generator (base point) of the group of
 * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
 * Uses mixed Jacobian-affine coordinates. Input and output values are
 * assumed to be NOT field-encoded. Uses algorithm 15 (simultaneous
 * multiple point multiplication) from Brown, Hankerson, Lopez, Menezes.
 * Software Implementation of the NIST Elliptic Curves over Prime Fields. */
mp_err
ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
				   const mp_int *py, mp_int *rx, mp_int *ry,
				   const ECGroup *group)
{
	mp_err res = MP_OKAY;
	mp_int precomp[4][4][2];
	mp_int rz;
	const mp_int *a, *b;
	unsigned int i, j;
	int ai, bi, d;

	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++) {
			MP_DIGITS(&precomp[i][j][0]) = 0;
			MP_DIGITS(&precomp[i][j][1]) = 0;
		}
	}
	MP_DIGITS(&rz) = 0;

	ARGCHK(group != NULL, MP_BADARG);
	ARGCHK(!((k1 == NULL)
			 && ((k2 == NULL) || (px == NULL)
				 || (py == NULL))), MP_BADARG);

	/* if some arguments are not defined used ECPoint_mul */
	if (k1 == NULL) {
		return ECPoint_mul(group, k2, px, py, rx, ry);
	} else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
		return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
	}

	/* initialize precomputation table */
	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++) {
			MP_CHECKOK(mp_init(&precomp[i][j][0]));
			MP_CHECKOK(mp_init(&precomp[i][j][1]));
		}
	}

	/* fill precomputation table */
	/* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
	if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
		a = k2;
		b = k1;
		if (group->meth->field_enc) {
			MP_CHECKOK(group->meth->
					   field_enc(px, &precomp[1][0][0], group->meth));
			MP_CHECKOK(group->meth->
					   field_enc(py, &precomp[1][0][1], group->meth));
		} else {
			MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
			MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
		}
		MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
		MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
	} else {
		a = k1;
		b = k2;
		MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
		MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
		if (group->meth->field_enc) {
			MP_CHECKOK(group->meth->
					   field_enc(px, &precomp[0][1][0], group->meth));
			MP_CHECKOK(group->meth->
					   field_enc(py, &precomp[0][1][1], group->meth));
		} else {
			MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
			MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
		}
	}
	/* precompute [*][0][*] */
	mp_zero(&precomp[0][0][0]);
	mp_zero(&precomp[0][0][1]);
	MP_CHECKOK(group->
			   point_dbl(&precomp[1][0][0], &precomp[1][0][1],
						 &precomp[2][0][0], &precomp[2][0][1], group));
	MP_CHECKOK(group->
			   point_add(&precomp[1][0][0], &precomp[1][0][1],
						 &precomp[2][0][0], &precomp[2][0][1],
						 &precomp[3][0][0], &precomp[3][0][1], group));
	/* precompute [*][1][*] */
	for (i = 1; i < 4; i++) {
		MP_CHECKOK(group->
				   point_add(&precomp[0][1][0], &precomp[0][1][1],
							 &precomp[i][0][0], &precomp[i][0][1],
							 &precomp[i][1][0], &precomp[i][1][1], group));
	}
	/* precompute [*][2][*] */
	MP_CHECKOK(group->
			   point_dbl(&precomp[0][1][0], &precomp[0][1][1],
						 &precomp[0][2][0], &precomp[0][2][1], group));
	for (i = 1; i < 4; i++) {
		MP_CHECKOK(group->
				   point_add(&precomp[0][2][0], &precomp[0][2][1],
							 &precomp[i][0][0], &precomp[i][0][1],
							 &precomp[i][2][0], &precomp[i][2][1], group));
	}
	/* precompute [*][3][*] */
	MP_CHECKOK(group->
			   point_add(&precomp[0][1][0], &precomp[0][1][1],
						 &precomp[0][2][0], &precomp[0][2][1],
						 &precomp[0][3][0], &precomp[0][3][1], group));
	for (i = 1; i < 4; i++) {
		MP_CHECKOK(group->
				   point_add(&precomp[0][3][0], &precomp[0][3][1],
							 &precomp[i][0][0], &precomp[i][0][1],
							 &precomp[i][3][0], &precomp[i][3][1], group));
	}

	d = (mpl_significant_bits(a) + 1) / 2;

	/* R = inf */
	MP_CHECKOK(mp_init(&rz));
	MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));

        for (i = d; i-- > 0;) {
		ai = MP_GET_BIT(a, 2 * i + 1);
		ai <<= 1;
		ai |= MP_GET_BIT(a, 2 * i);
		bi = MP_GET_BIT(b, 2 * i + 1);
		bi <<= 1;
		bi |= MP_GET_BIT(b, 2 * i);
		/* R = 2^2 * R */
		MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
		MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
		/* R = R + (ai * A + bi * B) */
		MP_CHECKOK(ec_GFp_pt_add_jac_aff
				   (rx, ry, &rz, &precomp[ai][bi][0], &precomp[ai][bi][1],
					rx, ry, &rz, group));
	}

	MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));

	if (group->meth->field_dec) {
		MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
		MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
	}

  CLEANUP:
	mp_clear(&rz);
	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++) {
			mp_clear(&precomp[i][j][0]);
			mp_clear(&precomp[i][j][1]);
		}
	}
	return res;
}
Exemplo n.º 25
0
/* Sets P(px, py, pz) to be the point at infinity.  Uses Jacobian
 * coordinates. */
mp_err
ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
{
	mp_zero(pz);
	return MP_OKAY;
}
Exemplo n.º 26
0
/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
 * a, b and p are the elliptic curve coefficients and the prime that
 * determines the field GFp.  Elliptic curve points P and R can be
 * identical.  Uses mixed Jacobian-affine coordinates. Assumes input is
 * already field-encoded using field_enc, and returns output that is still 
 * field-encoded. Uses 4-bit window method. */
mp_err
ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px, const mp_int *py,
				  mp_int *rx, mp_int *ry, const ECGroup *group)
{
	mp_err res = MP_OKAY;
	mp_int precomp[16][2], rz;
	int i, ni, d;

	MP_DIGITS(&rz) = 0;
	for (i = 0; i < 16; i++) {
		MP_DIGITS(&precomp[i][0]) = 0;
		MP_DIGITS(&precomp[i][1]) = 0;
	}

	ARGCHK(group != NULL, MP_BADARG);
	ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);

	/* initialize precomputation table */
	for (i = 0; i < 16; i++) {
		MP_CHECKOK(mp_init(&precomp[i][0]));
		MP_CHECKOK(mp_init(&precomp[i][1]));
	}

	/* fill precomputation table */
	mp_zero(&precomp[0][0]);
	mp_zero(&precomp[0][1]);
	MP_CHECKOK(mp_copy(px, &precomp[1][0]));
	MP_CHECKOK(mp_copy(py, &precomp[1][1]));
	for (i = 2; i < 16; i++) {
		MP_CHECKOK(group->
				   point_add(&precomp[1][0], &precomp[1][1],
							 &precomp[i - 1][0], &precomp[i - 1][1],
							 &precomp[i][0], &precomp[i][1], group));
	}

	d = (mpl_significant_bits(n) + 3) / 4;

	/* R = inf */
	MP_CHECKOK(mp_init(&rz));
	MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));

	for (i = d - 1; i >= 0; i--) {
		/* compute window ni */
		ni = MP_GET_BIT(n, 4 * i + 3);
		ni <<= 1;
		ni |= MP_GET_BIT(n, 4 * i + 2);
		ni <<= 1;
		ni |= MP_GET_BIT(n, 4 * i + 1);
		ni <<= 1;
		ni |= MP_GET_BIT(n, 4 * i);
		/* R = 2^4 * R */
		MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
		MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
		MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
		MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
		/* R = R + (ni * P) */
		MP_CHECKOK(ec_GFp_pt_add_jac_aff
				   (rx, ry, &rz, &precomp[ni][0], &precomp[ni][1], rx, ry,
					&rz, group));
	}

	/* convert result S to affine coordinates */
	MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));

  CLEANUP:
	mp_clear(&rz);
	for (i = 0; i < 16; i++) {
		mp_clear(&precomp[i][0]);
		mp_clear(&precomp[i][1]);
	}
	return res;
}
Exemplo n.º 27
0
/* this function is less generic than mp_n_root, simpler and faster */
int mp_sqrt(const mp_int *arg, mp_int *ret)
{
   int res;
   mp_int t1, t2;
   int i, j, k;
#ifndef NO_FLOATING_POINT
   volatile double d;
   mp_digit dig;
#endif

   /* must be positive */
   if (arg->sign == MP_NEG) {
      return MP_VAL;
   }

   /* easy out */
   if (mp_iszero(arg) == MP_YES) {
      mp_zero(ret);
      return MP_OKAY;
   }

   i = (arg->used / 2) - 1;
   j = 2 * i;
   if ((res = mp_init_size(&t1, i+2)) != MP_OKAY) {
      return res;
   }

   if ((res = mp_init(&t2)) != MP_OKAY) {
      goto E2;
   }

   for (k = 0; k < i; ++k) {
      t1.dp[k] = (mp_digit) 0;
   }

#ifndef NO_FLOATING_POINT

   /* Estimate the square root using the hardware floating point unit. */

   d = 0.0;
   for (k = arg->used-1; k >= j; --k) {
      d = ldexp(d, DIGIT_BIT) + (double)(arg->dp[k]);
   }

   /*
    * At this point, d is the nearest floating point number to the most
    * significant 1 or 2 mp_digits of arg. Extract its square root.
    */

   d = sqrt(d);

   /* dig is the most significant mp_digit of the square root */

   dig = (mp_digit) ldexp(d, -DIGIT_BIT);

   /*
    * If the most significant digit is nonzero, find the next digit down
    * by subtracting DIGIT_BIT times thie most significant digit.
    * Subtract one from the result so that our initial estimate is always
    * low.
    */

   if (dig) {
      t1.used = i+2;
      d -= ldexp((double) dig, DIGIT_BIT);
      if (d >= 1.0) {
         t1.dp[i+1] = dig;
         t1.dp[i] = ((mp_digit) d) - 1;
      } else {
         t1.dp[i+1] = dig-1;
         t1.dp[i] = MP_DIGIT_MAX;
      }
   } else {
      t1.used = i+1;
      t1.dp[i] = ((mp_digit) d) - 1;
   }

#else

   /* Estimate the square root as having 1 in the most significant place. */

   t1.used = i + 2;
   t1.dp[i+1] = (mp_digit) 1;
   t1.dp[i] = (mp_digit) 0;

#endif

   /* t1 > 0  */
   if ((res = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) {
      goto E1;
   }
   if ((res = mp_add(&t1, &t2, &t1)) != MP_OKAY) {
      goto E1;
   }
   if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) {
      goto E1;
   }
   /* And now t1 > sqrt(arg) */
   do {
      if ((res = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) {
         goto E1;
      }
      if ((res = mp_add(&t1, &t2, &t1)) != MP_OKAY) {
         goto E1;
      }
      if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) {
         goto E1;
      }
      /* t1 >= sqrt(arg) >= t2 at this point */
   } while (mp_cmp_mag(&t1, &t2) == MP_GT);

   mp_exch(&t1, ret);

E1:
   mp_clear(&t2);
E2:
   mp_clear(&t1);
   return res;
}
Exemplo n.º 28
0
/* Initialize a new instance. */
static void initialize(PARROT_INTERP, STable *st, void *data) {
    P6bigintBody *body = (P6bigintBody *)data;
    mp_init(&body->i);
    mp_zero(&body->i);
}
Exemplo n.º 29
0
 void clear() {
   mp_zero( &value );
 }
Exemplo n.º 30
0
/* read a string [ASCII] in a given radix */
int mp_read_radix (mp_int * a, const char *str, int radix)
{
  int     y, res, neg;
  char    ch;

  /* zero the digit bignum */
  mp_zero(a);

  /* make sure the radix is ok */
  if ((radix < 2) || (radix > 64)) {
    return MP_VAL;
  }

  /* if the leading digit is a 
   * minus set the sign to negative. 
   */
  if (*str == '-') {
    ++str;
    neg = MP_NEG;
  } else {
    neg = MP_ZPOS;
  }

  /* set the integer to the default of zero */
  mp_zero (a);
  
  /* process each digit of the string */
  while (*str != '\0') {
    /* if the radix <= 36 the conversion is case insensitive
     * this allows numbers like 1AB and 1ab to represent the same  value
     * [e.g. in hex]
     */
    ch = (radix <= 36) ? (char)toupper((int)*str) : *str;
    for (y = 0; y < 64; y++) {
      if (ch == mp_s_rmap[y]) {
         break;
      }
    }

    /* if the char was found in the map 
     * and is less than the given radix add it
     * to the number, otherwise exit the loop. 
     */
    if (y < radix) {
      if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
         return res;
      }
      if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
         return res;
      }
    } else {
      break;
    }
    ++str;
  }
  
  /* set the sign only if a != 0 */
  if (mp_iszero(a) != MP_YES) {
     a->sign = neg;
  }
  return MP_OKAY;
}