void autocorrelation_function::rearrange_image_to_acf_in(image_t& acf, const image_t* image) const {
    int H = height_/2;
    int W = width_/2;
    for (int i = 0; i <= H; ++i) {
      for (int j = 0; j <= W; ++j) {
	int acf_i;
	int acf_j;
	acf_i = H-1-i;
	acf_j = W-1-j;
	if (is_valid_idx(acf_i,acf_j)) { acf.at<float>(acf_i,acf_j) = image->at<float>(height_-1-i,width_-1-j); }
	acf_i = i+H;
	acf_j = j+W;
	if (is_valid_idx(acf_i,acf_j)) { acf.at<float>(acf_i,acf_j) = image->at<float>(i,j); }
	acf_i = H-1-i;
	acf_j = j+W;
	if (is_valid_idx(acf_i,acf_j)) { acf.at<float>(acf_i,acf_j) = image->at<float>(height_-1-i,j); }
	acf_i = i+H;
	acf_j = W-1-j;
	if (is_valid_idx(acf_i,acf_j)) { acf.at<float>(acf_i,acf_j) = image->at<float>(i,width_-1-j); }
      }
    }
  }
/**
   Verify an ECC signature
   @param sig         The signature to verify
   @param siglen      The length of the signature (octets)
   @param hash        The hash (message digest) that was signed
   @param hashlen     The length of the hash (octets)
   @param stat        Result of signature, 1==valid, 0==invalid
   @param key         The corresponding public ECC key
   @return CRYPT_OK if successful (even if the signature is not valid)
*/
int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
                    const unsigned char *hash, unsigned long hashlen, 
                    int *stat, ecc_key *key)
{
   ecc_point    *mG, *mQ;
   mp_int        r, s, v, w, u1, u2, e, p, m;
   mp_digit      mp;
   int           err;

   LTC_ARGCHK(sig  != NULL);
   LTC_ARGCHK(hash != NULL);
   LTC_ARGCHK(stat != NULL);
   LTC_ARGCHK(key  != NULL);

   /* default to invalid signature */
   *stat = 0;

   /* is the IDX valid ?  */
   if (is_valid_idx(key->idx) != 1) {
      return CRYPT_PK_INVALID_TYPE;
   }

   /* allocate ints */
   if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != MP_OKAY) {
      return CRYPT_MEM;
   }

   /* allocate points */
   mG = new_point();
   mQ = new_point();
   if (mQ  == NULL || mG == NULL) {
      err = CRYPT_MEM;
      goto done;
   }

   /* parse header */
   if ((err = der_decode_sequence_multi(sig, siglen,
                                  LTC_ASN1_INTEGER, 1UL, &r,
                                  LTC_ASN1_INTEGER, 1UL, &s,
                                  LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
      goto done;
   }

   /* get the order */
   if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY)                  { goto error; }

   /* get the modulus */
   if ((err = mp_read_radix(&m, (char *)sets[key->idx].prime, 64)) != MP_OKAY)                  { goto error; }

   /* check for zero */
   if (mp_iszero(&r) || mp_iszero(&s) || mp_cmp(&r, &p) != MP_LT || mp_cmp(&s, &p) != MP_LT) {
      err = CRYPT_INVALID_PACKET;
      goto done;
   }

   /* read hash */
   if ((err = mp_read_unsigned_bin(&e, (unsigned char *)hash, (int)hashlen)) != MP_OKAY)        { goto error; }

   /*  w  = s^-1 mod n */
   if ((err = mp_invmod(&s, &p, &w)) != MP_OKAY)                                                { goto error; }

   /* u1 = ew */
   if ((err = mp_mulmod(&e, &w, &p, &u1)) != MP_OKAY)                                           { goto error; }

   /* u2 = rw */
   if ((err = mp_mulmod(&r, &w, &p, &u2)) != MP_OKAY)                                           { goto error; }

   /* find mG = u1*G */
   if ((err = mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY)                 { goto error; }
   if ((err = mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY)                 { goto error; }
   mp_set(&mG->z, 1);  
   if ((err = ecc_mulmod(&u1, mG, mG, &m, 0)) != CRYPT_OK)                                      { goto done; }

   /* find mQ = u2*Q */
   if ((err = mp_copy(&key->pubkey.x, &mQ->x)) != MP_OKAY)                                      { goto error; }
   if ((err = mp_copy(&key->pubkey.y, &mQ->y)) != MP_OKAY)                                      { goto error; }
   if ((err = mp_copy(&key->pubkey.z, &mQ->z)) != MP_OKAY)                                      { goto error; }
   if ((err = ecc_mulmod(&u2, mQ, mQ, &m, 0)) != CRYPT_OK)                                      { goto done; }
  
   /* find the montgomery mp */
   if ((err = mp_montgomery_setup(&m, &mp)) != MP_OKAY)                                         { goto error; }
   /* add them */
   if ((err = add_point(mQ, mG, mG, &m, mp)) != CRYPT_OK)                                       { goto done; }
   
   /* reduce */
   if ((err = ecc_map(mG, &m, mp)) != CRYPT_OK)                                                 { goto done; }

   /* v = X_x1 mod n */
   if ((err = mp_mod(&mG->x, &p, &v)) != CRYPT_OK)                                              { goto done; }

   /* does v == r */
   if (mp_cmp(&v, &r) == MP_EQ) {
      *stat = 1;
   }

   /* clear up and return */
   err = CRYPT_OK;
   goto done;
error:
   err = mpi_to_ltc_error(err);
done:
   del_point(mG);
   del_point(mQ);
   mp_clear_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL);
   return err;
}
/**
  Sign a message digest
  @param in        The message digest to sign
  @param inlen     The length of the digest
  @param out       [out] The destination for the signature
  @param outlen    [in/out] The max size and resulting size of the signature
  @param prng      An active PRNG state
  @param wprng     The index of the PRNG you wish to use
  @param key       A private ECC key
  @return CRYPT_OK if successful
*/
int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, 
                        unsigned char *out, unsigned long *outlen, 
                        prng_state *prng, int wprng, ecc_key *key)
{
   ecc_key       pubkey;
   mp_int        r, s, e, p;
   int           err;

   LTC_ARGCHK(in     != NULL);
   LTC_ARGCHK(out    != NULL);
   LTC_ARGCHK(outlen != NULL);
   LTC_ARGCHK(key    != NULL);

   /* is this a private key? */
   if (key->type != PK_PRIVATE) {
      return CRYPT_PK_NOT_PRIVATE;
   }
   
   /* is the IDX valid ?  */
   if (is_valid_idx(key->idx) != 1) {
      return CRYPT_PK_INVALID_TYPE;
   }
   
   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
      return err;
   }

   /* get the hash and load it as a bignum into 'e' */
   /* init the bignums */
   if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != MP_OKAY) { 
      ecc_free(&pubkey);
      err = mpi_to_ltc_error(err);
      goto LBL_ERR;
   }
   if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY)        { goto error; }
   if ((err = mp_read_unsigned_bin(&e, (unsigned char *)in, (int)inlen)) != MP_OKAY)  { goto error; }

   /* make up a key and export the public copy */
   for (;;) {
      if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
         return err;
      }

      /* find r = x1 mod n */
      if ((err = mp_mod(&pubkey.pubkey.x, &p, &r)) != MP_OKAY)                           { goto error; }

      if (mp_iszero(&r)) {
         ecc_free(&pubkey);
      } else { 
        /* find s = (e + xr)/k */
        if ((err = mp_invmod(&pubkey.k, &p, &pubkey.k)) != MP_OKAY)            { goto error; } /* k = 1/k */
        if ((err = mp_mulmod(&key->k, &r, &p, &s)) != MP_OKAY)                 { goto error; } /* s = xr */
        if ((err = mp_addmod(&e, &s, &p, &s)) != MP_OKAY)                      { goto error; } /* s = e +  xr */
        if ((err = mp_mulmod(&s, &pubkey.k, &p, &s)) != MP_OKAY)               { goto error; } /* s = (e + xr)/k */

        if (mp_iszero(&s)) {
           ecc_free(&pubkey);
        } else {
           break;
        }
      }
   }

   /* store as SEQUENCE { r, s -- integer } */
   err = der_encode_sequence_multi(out, outlen,
                             LTC_ASN1_INTEGER, 1UL, &r,
                             LTC_ASN1_INTEGER, 1UL, &s,
                             LTC_ASN1_EOL, 0UL, NULL);
   goto LBL_ERR;
error:
   err = mpi_to_ltc_error(err);
LBL_ERR:
   mp_clear_multi(&r, &s, &p, &e, NULL);
   ecc_free(&pubkey);

   return err;   
}
Exemplo n.º 4
0
/**
  Sign a message digest using a DH private key 
  @param in      The data to sign
  @param inlen   The length of the input (octets)
  @param out     [out] The destination of the signature
  @param outlen  [in/out] The max size and resulting size of the output
  @param prng    An active PRNG state
  @param wprng   The index of the PRNG desired
  @param key     A private DH key
  @return CRYPT_OK if successful
*/
int dh_sign_hash(const unsigned char *in,  unsigned long inlen,
                       unsigned char *out, unsigned long *outlen,
                       prng_state *prng, int wprng, dh_key *key)
{
   mp_int         a, b, k, m, g, p, p1, tmp;
   unsigned char *buf;
   unsigned long  x, y;
   int            err;

   LTC_ARGCHK(in     != NULL);
   LTC_ARGCHK(out    != NULL);
   LTC_ARGCHK(outlen != NULL);
   LTC_ARGCHK(key    != NULL);

   /* check parameters */
   if (key->type != PK_PRIVATE) {
      return CRYPT_PK_NOT_PRIVATE;
   }

   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
      return err;
   }

   /* is the IDX valid ?  */
   if (is_valid_idx(key->idx) != 1) {
      return CRYPT_PK_INVALID_TYPE;
   }

   /* allocate ram for buf */
   buf = XMALLOC(520);

   /* make up a random value k,
    * since the order of the group is prime
    * we need not check if gcd(k, r) is 1 
    */
   if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) != 
       (unsigned long)(sets[key->idx].size)) {
      err = CRYPT_ERROR_READPRNG;
      goto LBL_ERR;
   }

   /* init bignums */
   if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != MP_OKAY) { 
      err = mpi_to_ltc_error(err);
      goto LBL_ERR;
   }

   /* load k and m */
   if ((err = mp_read_unsigned_bin(&m, (unsigned char *)in, inlen)) != MP_OKAY)        { goto error; }
   if ((err = mp_read_unsigned_bin(&k, buf, sets[key->idx].size)) != MP_OKAY)          { goto error; }

   /* load g, p and p1 */
   if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY)               { goto error; }
   if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY)              { goto error; }
   if ((err = mp_sub_d(&p, 1, &p1)) != MP_OKAY)                                     { goto error; }
   if ((err = mp_div_2(&p1, &p1)) != MP_OKAY)                                       { goto error; } /* p1 = (p-1)/2 */

   /* now get a = g^k mod p */
   if ((err = mp_exptmod(&g, &k, &p, &a)) != MP_OKAY)                               { goto error; }

   /* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */
   if ((err = mp_invmod(&k, &p1, &k)) != MP_OKAY)                                   { goto error; } /* k = 1/k mod p1 */
   if ((err = mp_mulmod(&a, &key->x, &p1, &tmp)) != MP_OKAY)                        { goto error; } /* tmp = xa */
   if ((err = mp_submod(&m, &tmp, &p1, &tmp)) != MP_OKAY)                           { goto error; } /* tmp = M - xa */
   if ((err = mp_mulmod(&k, &tmp, &p1, &b)) != MP_OKAY)                             { goto error; } /* b = (M - xa)/k */
   
   /* check for overflow */
   if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(&a) + mp_unsigned_bin_size(&b)) > *outlen) {
      err = CRYPT_BUFFER_OVERFLOW;
      goto LBL_ERR;
   }
   
   /* store header  */
   y = PACKET_SIZE;

   /* now store them both (a,b) */
   x = (unsigned long)mp_unsigned_bin_size(&a);
   STORE32L(x, out+y);  y += 4;
   if ((err = mp_to_unsigned_bin(&a, out+y)) != MP_OKAY)                            { goto error; }
   y += x;

   x = (unsigned long)mp_unsigned_bin_size(&b);
   STORE32L(x, out+y);  y += 4;
   if ((err = mp_to_unsigned_bin(&b, out+y)) != MP_OKAY)                            { goto error; }
   y += x;

   /* check if size too big */
   if (*outlen < y) {
      err = CRYPT_BUFFER_OVERFLOW;
      goto LBL_ERR;
   }

   /* store header */
   packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_SIGNED);
   *outlen = y;

   err = CRYPT_OK;
   goto LBL_ERR;
error:
   err = mpi_to_ltc_error(err);
LBL_ERR:
   mp_clear_multi(&tmp, &p1, &g, &p, &m, &k, &b, &a, NULL);

   XFREE(buf);

   return err;
}