Exemple #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;
}
Exemple #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;
}
Exemple #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;
}
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);
}
Exemple #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;
}
Exemple #6
0
int crypto_sign_edwards25519sha512batch_open(unsigned char *m,
                                             unsigned long long *mlen_p,
                                             const unsigned char *sm,
                                             unsigned long long smlen,
                                             const unsigned char *pk)
{
    unsigned char h[64];
    unsigned char t1[32], t2[32];
    unsigned long long mlen;
    ge_cached Ai;
    ge_p1p1 csa;
    ge_p2 cs;
    ge_p3 A;
    ge_p3 R;
    ge_p3 cs3;

    *mlen_p = 0;
    if (smlen < 64 || smlen > SIZE_MAX) {
        return -1;
    }
    mlen = smlen - 64;
    if (sm[smlen - 1] & 224) {
        return -1;
    }
    if (ge_frombytes_negate_vartime(&A, pk) != 0 ||
        ge_frombytes_negate_vartime(&R, sm) != 0) {
        return -1;
    }
    ge_p3_to_cached(&Ai, &A);
    crypto_hash_sha512(h, sm, mlen + 32);
    sc_reduce(h);
    ge_scalarmult_vartime(&cs3, h, &R);
    ge_add(&csa, &cs3, &Ai);
    ge_p1p1_to_p2(&cs, &csa);
    ge_tobytes(t1, &cs);
    t1[31] ^= 1 << 7;
    ge_scalarmult_base(&R, sm + 32 + mlen);
    ge_p3_tobytes(t2, &R);
    if (crypto_verify_32(t1, t2) != 0) {
        return -1;
    }
    *mlen_p = mlen;
    memmove(m, sm + 32, mlen);

    return 0;
}
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_pk_to_curve25519(unsigned char *curve25519_pk,
                                         const unsigned char *ed25519_pk)
{
    ge_p3 A;
    fe    x;
    fe    one_minus_y;

    ge_frombytes_negate_vartime(&A, ed25519_pk);
    fe_1(one_minus_y);
    fe_sub(one_minus_y, one_minus_y, A.Y);
    fe_invert(one_minus_y, one_minus_y);
    fe_1(x);
    fe_add(x, x, A.Y);
    fe_mul(x, x, one_minus_y);
    fe_tobytes(curve25519_pk, x);

    return 0;
}
Exemple #9
0
int Sign_publicSigningKeyToCurve25519(uint8_t curve25519keyOut[32], uint8_t publicSigningKey[32])
{
    ge_p3 A;
    fe    x;
    fe    one_minus_y;

    if (ge_frombytes_negate_vartime(&A, publicSigningKey) != 0) {
        return -1;
    }
    fe_1(one_minus_y);
    fe_sub(one_minus_y, one_minus_y, A.Y);
    fe_invert(one_minus_y, one_minus_y);
    fe_1(x);
    fe_add(x, x, A.Y);
    fe_mul(x, x, one_minus_y);
    fe_tobytes(curve25519keyOut, x);

    return 0;
}
Exemple #10
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);
}
Exemple #11
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;
}