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;
}
Exemple #2
0
void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) {
    sha512_context hash;
    unsigned char hram[64];
    unsigned char r[64];
    ge_p3 R;


    sha512_init(&hash);
    sha512_update(&hash, private_key + 32, 32);
    sha512_update(&hash, message, message_len);
    sha512_final(&hash, r);

    sc_reduce(r);
    ge_scalarmult_base(&R, r);
    ge_p3_tobytes(signature, &R);

    sha512_init(&hash);
    sha512_update(&hash, signature, 32);
    sha512_update(&hash, public_key, 32);
    sha512_update(&hash, message, message_len);
    sha512_final(&hash, hram);

    sc_reduce(hram);
    sc_muladd(signature + 32, hram, private_key, r);
}
Exemple #3
0
void Sign_signMsg(uint8_t keyPair[64], struct Message* msg, struct Random* rand)
{
    // az is set to the secret key followed by another secret value
    // which since we don't have a secret seed in this algorithm is just the
    // hash of the secret key and 32 bytes of random
    uint8_t az[64];
    uint8_t r[64];
    ge_p3 R;
    uint8_t hram[64];

    Bits_memcpy(az, keyPair, 32);
    Random_bytes(rand, &az[32], 32);
    crypto_hash_sha512(az,az,64);
    Bits_memcpy(az, keyPair, 32);
    az[0] &= 248;
    az[31] &= 63;
    az[31] |= 64;

    // hash message + secret number
    Message_push(msg, &az[32], 32, NULL);
    crypto_hash_sha512(r, msg->bytes, msg->length);

    // Replace secret number with public key
    Bits_memcpy(msg->bytes, &keyPair[32], 32);

    // push pointMul(r) to message
    sc_reduce(r);
    ge_scalarmult_base(&R,r);
    Message_shift(msg, 32, NULL);
    ge_p3_tobytes(msg->bytes,&R);

    crypto_hash_sha512(hram, msg->bytes, msg->length);
    sc_reduce(hram);
    sc_muladd(&msg->bytes[32], hram, az, r);
}
Exemple #4
0
int crypto_sign(
  unsigned char *sm,unsigned long long *smlen,
  const unsigned char *m,unsigned long long mlen,
  const unsigned char *sk
)
{
  unsigned char az[64];
  unsigned char r[64];
  unsigned char hram[64];
  ge_p3 R;
  unsigned long long i;

  crypto_hash_sha512(az,sk,32);
  az[0] &= 248;
  az[31] &= 63;
  az[31] |= 64;

  *smlen = mlen + 64;
  for (i = 0;i < mlen;++i) sm[64 + i] = m[i];
  for (i = 0;i < 32;++i) sm[32 + i] = az[32 + i];
  crypto_hash_sha512(r,sm + 32,mlen + 32);
  for (i = 0;i < 32;++i) sm[32 + i] = sk[32 + i];

  sc_reduce(r);
  ge_scalarmult_base(&R,r);
  ge_p3_tobytes(sm,&R);

  crypto_hash_sha512(hram,sm,mlen + 64);
  sc_reduce(hram);
  sc_muladd(sm + 32,hram,az,r);

  return 0;
}
static themis_status_t ed_point_sign(uint8_t pos, const uint8_t *scalar, const ge_p3 *point, uint8_t *signature)
{
	uint8_t r[ED25519_GE_LENGTH];
	ge_p3 R;
	uint8_t k[64];

	soter_hash_ctx_t hash_ctx;
	size_t hash_length = 64;

	themis_status_t res;

	generate_random_32(r);
	ge_scalarmult_base(&R, r);
	ge_p3_tobytes(k, &R);

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

	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_scalarmult_blinded(&R, r, point);
	ge_p3_tobytes(k, &R);

	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)
	{
		return res;
	}

	if (THEMIS_SUCCESS == res)
	{
		sc_reduce(k);
		memcpy(signature, k, ED25519_GE_LENGTH);
		sc_muladd(signature + ED25519_GE_LENGTH, k, scalar, r);
	}

	return res;
}
Exemple #6
0
void ed25519_sign(unsigned char *signature, const unsigned char *message, int32_t message_len, const unsigned char *public_key, const unsigned char *private_key) {
	sha3_context ctx;
	unsigned char hram[64];
    unsigned char r[64];
    ge_p3 R;


	sha3_init512(&ctx);
	sha3_update(&ctx, private_key + 32, 32);
	sha3_update(&ctx, message, message_len);
	sha3_finalize(&ctx, &r);

    sc_reduce(r);
    ge_scalarmult_base(&R, r);
    ge_p3_tobytes(signature, &R);

	sha3_init512(&ctx);
	sha3_update(&ctx, signature, 32);
	sha3_update(&ctx, public_key, 32);
	sha3_update(&ctx, message, message_len);
	sha3_finalize(&ctx, hram);

    sc_reduce(hram);
    sc_muladd(signature + 32, hram, private_key, r);
}
Exemple #7
0
/* see http://crypto.stackexchange.com/a/6215/4697 */
void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) {
    const unsigned char SC_1[32] = {1}; /* scalar with value 1 */
    
    unsigned char n[32]; 
    ge_p3 nB;
    ge_p1p1 A_p1p1;
    ge_p3 A;
    ge_p3 public_key_unpacked;
    ge_cached T;

    int i;

    /* copy the scalar and clear highest bit */
    for (i = 0; i < 31; ++i) {
        n[i] = scalar[i];
    }
    n[31] = scalar[31] & 127;

    /* private key: a = n + t */
    if (private_key) {
        sc_muladd(private_key, SC_1, n, private_key);
    }

    /* public key: A = nB + T */
    if (public_key) {
        /* if we know the private key we don't need a point addition, which is faster */
        /* using a "timing attack" you could find out wether or not we know the private
           key, but this information seems rather useless - if this is important pass
           public_key and private_key seperately in 2 function calls */
        if (private_key) {
            ge_scalarmult_base(&A, private_key);
        } else {
            /* unpack public key into T */
            ge_frombytes_negate_vartime(&public_key_unpacked, public_key);
            fe_neg(public_key_unpacked.X, public_key_unpacked.X); // undo negate
            fe_neg(public_key_unpacked.T, public_key_unpacked.T); // undo negate
            ge_p3_to_cached(&T, &public_key_unpacked);

            /* calculate n*B */
            ge_scalarmult_base(&nB, n);

            /* A = n*B + T */
            ge_add(&A_p1p1, &nB, &T);
            ge_p1p1_to_p3(&A, &A_p1p1);
        }
            
        /* pack public key */
        ge_p3_tobytes(public_key, &A);
    }
}
Exemple #8
0
int
_crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p,
                              const unsigned char *m, unsigned long long mlen,
                              const unsigned char *sk, int prehashed)
{
    crypto_hash_sha512_state hs;
    unsigned char            az[64];
    unsigned char            nonce[64];
    unsigned char            hram[64];
    ge_p3                    R;

    _crypto_sign_ed25519_ref10_hinit(&hs, prehashed);

#ifdef ED25519_NONDETERMINISTIC
    memcpy(az, sk, 32);
    _crypto_sign_ed25519_synthetic_r_hv(&hs, nonce, az);
#else
    crypto_hash_sha512(az, sk, 32);
    crypto_hash_sha512_update(&hs, az + 32, 32);
#endif

    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, nonce);

    memmove(sig + 32, sk + 32, 32);

    sc_reduce(nonce);
    ge_scalarmult_base(&R, nonce);
    ge_p3_tobytes(sig, &R);

    _crypto_sign_ed25519_ref10_hinit(&hs, prehashed);
    crypto_hash_sha512_update(&hs, sig, 64);
    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, hram);

    sc_reduce(hram);
    _crypto_sign_ed25519_clamp(az);
    sc_muladd(sig + 32, hram, az, nonce);

    sodium_memzero(az, sizeof az);
    sodium_memzero(nonce, sizeof nonce);

    if (siglen_p != NULL) {
        *siglen_p = 64U;
    }
    return 0;
}
Exemple #9
0
int
crypto_sign_detached(unsigned char *sig, unsigned long long *siglen,
                     const unsigned char *m, unsigned long long mlen,
                     const unsigned char *sk)
{
    crypto_hash_sha512_state hs;
    unsigned char pk[32];
    unsigned char az[64];
    unsigned char nonce[64];
    unsigned char hram[64];
    ge_p3 R;

    memmove(pk, sk + 32, 32);

    crypto_hash_sha512(az, sk, 32);
    az[0] &= 248;
    az[31] &= 63;
    az[31] |= 64;

    crypto_hash_sha512_init(&hs);
    crypto_hash_sha512_update(&hs, az + 32, 32);
    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, nonce);

    memmove(sig + 32, pk, 32);

    sc_reduce(nonce);
    ge_scalarmult_base(&R, nonce);
    ge_p3_tobytes(sig, &R);

    crypto_hash_sha512_init(&hs);
    crypto_hash_sha512_update(&hs, sig, 64);
    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, hram);

    sc_reduce(hram);
    sc_muladd(sig + 32, hram, az, nonce);

    sodium_memzero(az, sizeof az);
    sodium_memzero(nonce, sizeof nonce);

    if (siglen != NULL) {
        *siglen = 64U;
    }
    return 0;
}
Exemple #10
0
/* NEW: Compare to pristine crypto_sign() 
   Uses explicit private key for nonce derivation and as scalar,
   instead of deriving both from a master key.
*/
int crypto_sign_modified(
  unsigned char *sm,
  const unsigned char *m,unsigned long long mlen,
  const unsigned char *sk, const unsigned char* pk,
  const unsigned char* random
)
{
  unsigned char nonce[64];
  unsigned char hram[64];
  ge_p3 R;
  int count=0;

  memmove(sm + 64,m,mlen);
  memmove(sm + 32,sk,32); /* NEW: Use privkey directly for nonce derivation */

  /* NEW : add prefix to separate hash uses - see .h */
  sm[0] = 0xFE;
  for (count = 1; count < 32; count++)
    sm[count] = 0xFF;

  /* NEW: add suffix of random data */
  memmove(sm + mlen + 64, random, 64);

  crypto_hash_sha512(nonce,sm,mlen + 128);
  memmove(sm + 32,pk,32);

  sc_reduce(nonce);
  ge_scalarmult_base(&R,nonce);
  ge_p3_tobytes(sm,&R);

  crypto_hash_sha512(hram,sm,mlen + 64);
  sc_reduce(hram);
  sc_muladd(sm + 32,hram,sk,nonce); /* NEW: Use privkey directly */

  /* NEW: Try to erase any traces of privkey or 
     nonce left in the stack from sc_muladd. */
  zeroize_stack();

  zeroize(nonce, 64);
  return 0;
}
Exemple #11
0
int crypto_sign(
  unsigned char *sig,
  const unsigned char *m, size_t mlen,
  const unsigned char *sk,const unsigned char *pk
)
{
  unsigned char nonce[64];
  unsigned char hram[64];
  ge_p3 R;

  crypto_hash_sha512_2(nonce, sk+32, 32, m, mlen);

  sc_reduce(nonce);
  ge_scalarmult_base(&R,nonce);
  ge_p3_tobytes(sig,&R);

  crypto_hash_sha512_3(hram, sig, 32, pk, 32, m, mlen);
  sc_reduce(hram);
  sc_muladd(sig + 32,hram,sk,nonce);

  return 0;
}
Exemple #12
0
int crypto_sign_edwards25519sha512batch(unsigned char *sm,
                                        unsigned long long *smlen_p,
                                        const unsigned char *m,
                                        unsigned long long mlen,
                                        const unsigned char *sk)
{
    crypto_hash_sha512_state hs;
    unsigned char nonce[64];
    unsigned char hram[64];
    unsigned char sig[64];
    ge_p3 A;
    ge_p3 R;

    crypto_hash_sha512_init(&hs);
    crypto_hash_sha512_update(&hs, sk + 32, 32);
    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, nonce);
    ge_scalarmult_base(&A, sk);
    ge_p3_tobytes(sig + 32, &A);
    sc_reduce(nonce);
    ge_scalarmult_base(&R, nonce);
    ge_p3_tobytes(sig, &R);
    crypto_hash_sha512_init(&hs);
    crypto_hash_sha512_update(&hs, sig, 32);
    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, hram);
    sc_reduce(hram);
    sc_muladd(sig + 32, hram, nonce, sk);
    sodium_memzero(hram, sizeof hram);
    memmove(sm + 32, m, (size_t) mlen);
    memcpy(sm, sig, 32);
    memcpy(sm + 32 + mlen, sig + 32, 32);
    *smlen_p = mlen + 64U;

    return 0;
}
Exemple #13
0
void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) {
    CC_SHA512_CTX hash;
    unsigned char hram[64];
    unsigned char r[64];
    ge_p3 R;

    CC_SHA512_Init(&hash);
    CC_SHA512_Update(&hash, private_key + 32, 32);
    CC_SHA512_Update_Long(&hash, message, message_len);
    CC_SHA512_Final(r, &hash);

    sc_reduce(r);
    ge_scalarmult_base(&R, r);
    ge_p3_tobytes(signature, &R);

    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(hram, &hash);

    sc_reduce(hram);
    sc_muladd(signature + 32, hram, private_key, r);
}
Exemple #14
0
/*
    in     contains the message to sign
    inlen  is the length of the message to sign
    out    is the buffer to write the signature
    outLen [in/out] input size of out buf
                     output gets set as the final length of out
    key    is the ed25519 key to use when signing
    return 0 on success
 */
int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
                        word32 *outLen, ed25519_key* key)
{
    ge_p3  R;
    byte   nonce[SHA512_DIGEST_SIZE];
    byte   hram[SHA512_DIGEST_SIZE];
    byte   az[ED25519_PRV_KEY_SIZE];
    Sha512 sha;
    int    ret;

    /* sanity check on arguments */
    if (in == NULL || out == NULL || outLen == NULL || key == NULL)
        return BAD_FUNC_ARG;

    /* check and set up out length */
    if (*outLen < ED25519_SIG_SIZE) {
        *outLen = ED25519_SIG_SIZE;
        return BUFFER_E;
    }
    *outLen = ED25519_SIG_SIZE;

    /* step 1: create nonce to use where nonce is r in
       r = H(h_b, ... ,h_2b-1,M) */
    ret = wc_Sha512Hash(key->k, ED25519_KEY_SIZE, az);
    if (ret != 0)
        return ret;

    /* apply clamp */
    az[0]  &= 248;
    az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */
    az[31] |= 64;

    ret = wc_InitSha512(&sha);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Update(&sha, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Update(&sha, in, inlen);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Final(&sha, nonce);
    if (ret != 0)
        return ret;

    sc_reduce(nonce);

    /* step 2: computing R = rB where rB is the scalar multiplication of
       r and B */
    ge_scalarmult_base(&R,nonce);
    ge_p3_tobytes(out,&R);

    /* step 3: hash R + public key + message getting H(R,A,M) then
       creating S = (r + H(R,A,M)a) mod l */
    ret = wc_InitSha512(&sha);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Update(&sha, out, 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, in, inlen);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Final(&sha, hram);
    if (ret != 0)
        return ret;

    sc_reduce(hram);
    sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);

    return ret;
}