Example #1
0
int crypto_sign_open(
  unsigned char *m,unsigned long long *mlen,
  const unsigned char *sm,unsigned long long smlen,
  const unsigned char *pk
)
{
  unsigned char h[64];
  unsigned char checkr[32];
  ge_p3 A;
  ge_p2 R;
  unsigned long long i;

  *mlen = -1;
  if (smlen < 64) return -1;
  if (sm[63] & 224) return -2;
  if (ge_frombytes_negate_vartime(&A,pk) != 0) return -3;

  for (i = 0;i < smlen;++i) m[i] = sm[i];
  for (i = 0;i < 32;++i) m[32 + i] = pk[i];
  SHA512(m, smlen, h);
  sc_reduce(h);

  ge_double_scalarmult_vartime(&R,h,&A,sm + 32);
  ge_tobytes(checkr,&R);
  if (crypto_verify_32(checkr,sm) != 0) {
    for (i = 0;i < smlen;++i) m[i] = 0;
    return crypto_verify_32(checkr,sm);
  }

  for (i = 0;i < smlen - 64;++i) m[i] = sm[64 + i];
  for (i = smlen - 64;i < smlen;++i) m[i] = 0;
  *mlen = smlen - 64;
  return 0;
}
Example #2
0
int crypto_sign_open(
  unsigned char *sm, unsigned long long smlen,
  const unsigned char *pk
)
{
  unsigned char scopy[32];
  unsigned char h[64];
  unsigned char rcheck[32];
  ge_p3 A;
  ge_p2 R;

  if (smlen < 64) goto badsig;
  if (sm[63] & 224) goto badsig;
  if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig;

  memmove(scopy,sm + 32,32);

  memmove(sm + 32,pk,32);
  crypto_hash_sha512(h,sm,smlen);
  sc_reduce(h);

  ge_double_scalarmult_vartime(&R,h,&A,scopy);
  ge_tobytes(rcheck,&R);
  if (crypto_verify_32(rcheck,sm) == 0)
    return 0;

badsig:
  return -1;
}
Example #3
0
int crypto_sign_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) {
    unsigned char h[64];
    unsigned char checker[32];
    SHA512_CTX hash;
    ge_p3 A;
    ge_p2 R;

    if (signature[63] & 224) {
        return -1;
    }

    if (ge_frombytes_negate_vartime(&A, public_key) != 0) {
        return -2;
    }

    SHA512_Init(&hash);
    SHA512_Update(&hash, signature, 32);
    SHA512_Update(&hash, public_key, 32);
    SHA512_Update(&hash, message, message_len);
    SHA512_Final(h, &hash);

    sc_reduce(h);
    ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
    ge_tobytes(checker, &R);

    if (!(crypto_verify_32(checker, signature) == 0)) {
        return -3;
    }

    return 0;
}
Example #4
0
int	cced25519_verify(const struct ccdigest_info *di,
                     size_t mlen, const void *inMsg,
                     const ccec25519signature sig,
                     const ccec25519pubkey pk)
{
  const uint8_t * const m = (const uint8_t *) inMsg;
  ccdigest_di_decl(di, dc);
  uint8_t h[64];
  uint8_t checkr[32];
  ge_p3 A;
  ge_p2 R;

  ASSERT_DIGEST_SIZE(di);
  if (ge_frombytes_negate_vartime(&A,pk) != 0) return -1;

  ccdigest_init(di,dc);
  ccdigest_update(di,dc,32,sig);
  ccdigest_update(di,dc,32,pk);
  ccdigest_update(di,dc,mlen,m);
  ccdigest_final(di,dc,h);
  ccdigest_di_clear(di,dc);
  sc_reduce(h);

  ge_double_scalarmult_vartime(&R,h,&A,sig + 32);
  ge_tobytes(checkr,&R);
  return crypto_verify_32(checkr,sig);
}
Example #5
0
int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) {
    unsigned char h[64];
    unsigned char checker[32];
    CC_SHA512_CTX hash;
    ge_p3 A;
    ge_p2 R;
	
    if (signature[63] & 224) {
        return 0;
    }
	
    if (ge_frombytes_negate_vartime(&A, public_key) != 0) {
        return 0;
    }
	
    CC_SHA512_Init(&hash);
    CC_SHA512_Update(&hash, signature, 32);
    CC_SHA512_Update(&hash, public_key, 32);
    CC_SHA512_Update_Long(&hash, message, message_len);
    CC_SHA512_Final(h, &hash);
    
    sc_reduce(h);
    ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
    ge_tobytes(checker, &R);
	
    if (!consttime_equal(checker, signature)) {
        return 0;
    }
	
    return 1;
}
static themis_status_t ed_dbl_base_sign(uint8_t pos, const uint8_t *scalar1, const uint8_t *scalar2, const ge_p3 *base1, const ge_p3 *base2, uint8_t *signature)
{
	uint8_t r1[ED25519_GE_LENGTH];
	uint8_t r2[ED25519_GE_LENGTH];
	ge_p3 R1;
	ge_p2 R2;
	uint8_t k[64];

	soter_hash_ctx_t hash_ctx;
	size_t hash_length = 64;

	themis_status_t res;

	generate_random_32(r1);
	generate_random_32(r2);
	ge_scalarmult_blinded(&R1, r1, base2);
	ge_double_scalarmult_vartime(&R2, r2, base1, r1);

	res = soter_hash_init(&hash_ctx, SOTER_HASH_SHA512);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	ge_p3_tobytes(k, &R1);
	res = soter_hash_update(&hash_ctx, k, ED25519_GE_LENGTH);
	if (THEMIS_SUCCESS != res)
	{
		soter_hash_final(&hash_ctx, k, &hash_length);
		return res;
	}

	ge_tobytes(k, &R2);
	res = soter_hash_update(&hash_ctx, k, ED25519_GE_LENGTH);
	if (THEMIS_SUCCESS != res)
	{
		soter_hash_final(&hash_ctx, k, &hash_length);
		return res;
	}

	res = soter_hash_update(&hash_ctx, &pos, sizeof(pos));
	if (THEMIS_SUCCESS != res)
	{
		soter_hash_final(&hash_ctx, k, &hash_length);
		return res;
	}

	res = soter_hash_final(&hash_ctx, k, &hash_length);

	if (THEMIS_SUCCESS == res)
	{
		sc_reduce(k);
		memcpy(signature, k, ED25519_GE_LENGTH);
		sc_muladd(signature + ED25519_GE_LENGTH, k, scalar1, r1);
		sc_muladd(signature + (2 * ED25519_GE_LENGTH), k, scalar2, r2);
	}

	return res;
}
static void corrupt_bob_step2(secure_comparator_t *bob, const void *input, size_t input_length, void *output, size_t *output_length)
{
	/* Let's assume bob is malicious and uses zeroes instead of random numbers */

	ge_p3 g2a;
	ge_p3 g3a;

	ge_p3 g2b;
	ge_p3 g3b;

	ge_frombytes_vartime(&g2a, (const unsigned char *)input);
	ge_frombytes_vartime(&g3a, ((const unsigned char *)input) + (3 * ED25519_GE_LENGTH));

	if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != secure_comparator_proceed_compare(bob, input, input_length, output, output_length))
	{
		testsuite_fail_if(true, "secure_comparator_proceed_compare failed");
		return;
	}

	memset(bob->rand2, 0, sizeof(bob->rand2));
	memset(bob->rand3, 0, sizeof(bob->rand3));

	ge_scalarmult_base(&g2b, bob->rand2);
	ge_scalarmult_base(&g3b, bob->rand3);

	ge_scalarmult_blinded(&(bob->g2), bob->rand2, &g2a);
	ge_scalarmult_blinded(&(bob->g3), bob->rand3, &g3a);

	memset(bob->rand, 0, sizeof(bob->rand));

	ge_scalarmult_blinded(&(bob->P), bob->rand, &(bob->g3));
	ge_double_scalarmult_vartime((ge_p2 *)&(bob->Q), bob->secret, &(bob->g2), bob->rand);
	ge_p2_to_p3(&(bob->Q), (const ge_p2 *)&(bob->Q));

	ge_p3_tobytes((unsigned char *)output, &g2b);
	ed_sign(3, bob->rand2, ((unsigned char *)output) + ED25519_GE_LENGTH);

	ge_p3_tobytes(((unsigned char *)output) + (3 * ED25519_GE_LENGTH), &g3b);
	ed_sign(4, bob->rand3, ((unsigned char *)output) + (4 * ED25519_GE_LENGTH));

	ge_p3_tobytes(((unsigned char *)output) + (6 * ED25519_GE_LENGTH), &(bob->P));
	ge_p3_tobytes(((unsigned char *)output) + (7 * ED25519_GE_LENGTH), &(bob->Q));
	ed_dbl_base_sign(5, bob->rand, bob->secret, &(bob->g2), &(bob->g3), ((unsigned char *)output) + (8 * ED25519_GE_LENGTH));
}
Example #8
0
int
crypto_sign_verify_detached(const unsigned char *sig, const unsigned char *m,
                            unsigned long long mlen, const unsigned char *pk)
{
    crypto_hash_sha512_state hs;
    unsigned char h[64];
    unsigned char rcheck[32];
    unsigned int  i;
    unsigned char d = 0;
    ge_p3 A;
    ge_p2 R;

#ifdef ED25519_PREVENT_MALLEABILITY
    if (crypto_sign_check_S_lt_l(sig + 32) != 0) {
        return -1;
    }
#else
    if (sig[63] & 224) {
        return -1;
    }
#endif
    if (ge_frombytes_negate_vartime(&A, pk) != 0) {
        return -1;
    }
    for (i = 0; i < 32; ++i) {
        d |= pk[i];
    }
    if (d == 0) {
        return -1;
    }
    crypto_hash_sha512_init(&hs);
    crypto_hash_sha512_update(&hs, sig, 32);
    crypto_hash_sha512_update(&hs, pk, 32);
    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, h);
    sc_reduce(h);

    ge_double_scalarmult_vartime(&R, h, &A, sig + 32);
    ge_tobytes(rcheck, &R);

    return crypto_verify_32(rcheck, sig) | (-(rcheck - sig == 0)) |
           sodium_memcmp(sig, rcheck, 32);
}
Example #9
0
/*
   sig     is array of bytes containing the signature
   siglen  is the length of sig byte array
   msg     the array of bytes containing the message
   msglen  length of msg array
   stat    will be 1 on successful verify and 0 on unsuccessful
*/
int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg,
                          word32 msglen, int* stat, ed25519_key* key)
{
    byte   rcheck[ED25519_KEY_SIZE];
    byte   h[SHA512_DIGEST_SIZE];
    ge_p3  A;
    ge_p2  R;
    int    ret;
    Sha512 sha;

    /* sanity check on arguments */
    if (sig == NULL || msg == NULL || stat == NULL || key == NULL)
        return BAD_FUNC_ARG;

    /* set verification failed by default */
    *stat = 0;

    /* check on basics needed to verify signature */
    if (siglen < ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
        return BAD_FUNC_ARG;

    /* uncompress A (public key), test if valid, and negate it */
    if (ge_frombytes_negate_vartime(&A, key->p) != 0)
        return BAD_FUNC_ARG;

    /* find H(R,A,M) and store it as h */
    ret  = wc_InitSha512(&sha);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Update(&sha, sig,    ED25519_SIG_SIZE/2);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Update(&sha, msg,    msglen);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Final(&sha,  h);
    if (ret != 0)
        return ret;

    sc_reduce(h);

    /*
       Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
       SB - H(R,A,M)A saving decompression of R
    */
    ret = ge_double_scalarmult_vartime(&R, h, &A, sig + (ED25519_SIG_SIZE/2));
    if (ret != 0)
        return ret;

    ge_tobytes(rcheck, &R);

    /* comparison of R created to R in sig */
    ret = ConstantCompare(rcheck, sig, ED25519_SIG_SIZE/2);
    if (ret != 0)
        return ret;

    /* set the verification status */
    *stat = 1;

    return ret;
}