Esempio n. 1
0
void create_file(char* filename)
{
  unsigned int j;
  FILE *urandom = fopen("/dev/urandom", "r");

  crypto_sign_keypair(pk, sk);
  for(j=0;j<MLEN;j++) 
      mi[j] = fgetc(urandom);
  crypto_sign(sm, &smlen, mi, MLEN, sk);    

  FILE *file;
  file=fopen(filename,"wb");

  if(file == NULL)
	printf("Unable to open file!\n");

  fwrite(pk, 1, CRYPTO_PUBLICKEYBYTES, file);
  fwrite(sm, 1, MLEN+CRYPTO_BYTES, file);
  fwrite(&smlen, sizeof(unsigned long long), 1, file);

  fclose(file);
  
  for(j=0;j<CRYPTO_PUBLICKEYBYTES;j++)
	pk[j] = fgetc(urandom);
  for(j=0;j<MLEN+CRYPTO_BYTES;j++)
	sm[j] = fgetc(urandom);
  smlen = fgetc(urandom);

  fclose(urandom);
}
void speed_ed25519()
{
  unsigned long long t[NTIMINGS];
  int i;
  unsigned char pk[32];
  unsigned char sk[64];
  
  // Benchmarking keypair
  for(i=0;i<NTIMINGS;i++)
  {
    t[i] = cpucycles();
    crypto_sign_keypair(pk, sk);
  }
  print_bench("sign_keypair",t,NTIMINGS);

  // Benchmarking sign
  for(i=0;i<NTIMINGS;i++)
  {
    t[i] = cpucycles();
    crypto_sign(sm, &smlen, msg, MLEN, sk);
  }
  print_bench("sign (59 bytes)",t,NTIMINGS);

  // Benchmarking sign_open
  for(i=0;i<NTIMINGS;i++)
  {
    t[i] = cpucycles();
    crypto_sign_open(mo, &mlen, sm, smlen, pk);
  }
  print_bench("sign_open (59 bytes)",t,NTIMINGS);
}
Esempio n. 3
0
PyObject *pycrypto_sign_keypair(PyObject *self){
  PyObject *pypk, *pysk, *pyret;
  unsigned char pk[crypto_sign_PUBLICKEYBYTES];
  unsigned char sk[crypto_sign_SECRETKEYBYTES];

  crypto_sign_keypair(pk, sk);

  pypk = PyBytes_FromStringAndSize((char *)pk, crypto_sign_PUBLICKEYBYTES);

  if (!pypk)
    return (PyObject *)0;

  pysk = PyBytes_FromStringAndSize((char *)sk, crypto_sign_SECRETKEYBYTES);

  if (!pysk){
    Py_DECREF(pypk);
    return (PyObject *)0;}

  pyret = PyTuple_New(2);

  if (!pyret){
    Py_DECREF(pypk);
    Py_DECREF(pysk);
    return (PyObject *)0;}

  PyTuple_SET_ITEM(pyret, 0, pypk);
  PyTuple_SET_ITEM(pyret, 1, pysk);
  return pyret;}
Esempio n. 4
0
static char * createGUID()
{
  sodium_init();

  unsigned char out[crypto_hash_sha512_BYTES];
  unsigned char sk[crypto_sign_SECRETKEYBYTES];
  int valid_pow = 0;
  while (valid_pow == 0){

    //Generate a key pair
    unsigned char pk[crypto_sign_PUBLICKEYBYTES];
    unsigned char sk[crypto_sign_SECRETKEYBYTES];
    crypto_sign_keypair(pk, sk);

    //Sign the public key
    const unsigned char * message = pk;
    int message_len = crypto_sign_PUBLICKEYBYTES;

    unsigned char signed_message[crypto_sign_BYTES + message_len];
    unsigned long long signed_message_len;

    crypto_sign(signed_message, &signed_message_len,
            message, message_len, sk);

    //Hash the signed key with sha512
    crypto_hash_sha512(out, signed_message, signed_message_len);
    char proof_of_work[32];
    memcpy(proof_of_work, &out[32], 32);
    char * pow = to_hex(proof_of_work, 3);
    valid_pow = test_pow(pow);
  }
  to_hex(sk, 32);
  return to_hex(sk, 32);
}
Esempio n. 5
0
bool unit_test_crypto_sign(){
  uint64_t len = HACL_UNIT_TESTS_SIZE * sizeof(uint8_t);
  uint8_t *plaintext = malloc(HACL_UNIT_TESTS_SIZE * sizeof (uint8_t));
  uint8_t *expected_signed_msg = malloc((HACL_UNIT_TESTS_SIZE+64) * sizeof (uint8_t));
  uint8_t *hacl_signed_msg = malloc((HACL_UNIT_TESTS_SIZE+64) * sizeof (uint8_t));
  uint8_t sk[64], pk[32];
  crypto_sign_keypair(pk, sk);
  READ_RANDOM_BYTES(len, plaintext);
  int a, res;
  bool pass = true;
  long long unsigned int smlen;
  for (int i = 0; i < 256; i++){
    tweet_crypto_sign(expected_signed_msg, &smlen, plaintext, i, sk);
    crypto_sign(hacl_signed_msg, &smlen, plaintext, i, sk);
    a = memcmp(hacl_signed_msg, expected_signed_msg, (i+64) * sizeof(uint8_t));
    if (a != 0){
      pass = false;
      printf("crypto_sign failed on input of size %d\n", i);
      break;
    }
    res = crypto_sign_open(hacl_signed_msg, &smlen, expected_signed_msg, i + 64, pk);
    if (res != 0) {
      pass = false;
      printf("crypto_sign_open returned value failed on input of size %d\n", i);
      break;
    }
    a = memcmp(hacl_signed_msg, plaintext, i * sizeof(uint8_t));
    if (a != 0){
      pass = false;
      printf("crypto_sign_open failed on input of size %d\n", i);
      break;
    }
  }
  if (!pass) return pass;
  tweet_crypto_sign(expected_signed_msg, &smlen, plaintext, HACL_UNIT_TESTS_SIZE, sk);
  crypto_sign(hacl_signed_msg, &smlen, plaintext, HACL_UNIT_TESTS_SIZE, sk);
  a = memcmp(hacl_signed_msg, expected_signed_msg, (HACL_UNIT_TESTS_SIZE+64) * sizeof (uint8_t));
  if (a != 0){
    pass = false;
    printf("crypto_sign failed on input of size %d\n.", HACL_UNIT_TESTS_SIZE);
  }
  res = crypto_sign_open(hacl_signed_msg, &smlen, expected_signed_msg, HACL_UNIT_TESTS_SIZE + 64, pk);
  if (res != 0) {
    pass = false;
    printf("crypto_sign_open returned value failed on input of size %d\n", HACL_UNIT_TESTS_SIZE);
  }
  a = memcmp(hacl_signed_msg, plaintext, HACL_UNIT_TESTS_SIZE * sizeof(uint8_t));
  if (a != 0){
    pass = false;
    printf("crypto_sign_open failed on input of size %d\n", HACL_UNIT_TESTS_SIZE);
  }

  free(plaintext);
  free(hacl_signed_msg);
  free(expected_signed_msg);

  return pass;
}
Esempio n. 6
0
CWalletTx GetValidReceive(ZCJoinSplit& params,
                          const libzcash::SpendingKey& sk, CAmount value,
                          bool randomInputs) {
    CMutableTransaction mtx;
    mtx.nVersion = 2; // Enable JoinSplits
    mtx.vin.resize(2);
    if (randomInputs) {
        mtx.vin[0].prevout.hash = GetRandHash();
        mtx.vin[1].prevout.hash = GetRandHash();
    } else {
        mtx.vin[0].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
        mtx.vin[1].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000002");
    }
    mtx.vin[0].prevout.n = 0;
    mtx.vin[1].prevout.n = 0;

    // Generate an ephemeral keypair.
    uint256 joinSplitPubKey;
    unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES];
    crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey);
    mtx.joinSplitPubKey = joinSplitPubKey;

    boost::array<libzcash::JSInput, 2> inputs = {
        libzcash::JSInput(), // dummy input
        libzcash::JSInput() // dummy input
    };

    boost::array<libzcash::JSOutput, 2> outputs = {
        libzcash::JSOutput(sk.address(), value),
        libzcash::JSOutput(sk.address(), value)
    };

    boost::array<libzcash::Note, 2> output_notes;

    // Prepare JoinSplits
    uint256 rt;
    JSDescription jsdesc {params, mtx.joinSplitPubKey, rt,
                          inputs, outputs, 2*value, 0, false};
    mtx.vjoinsplit.push_back(jsdesc);

    // Empty output script.
    CScript scriptCode;
    CTransaction signTx(mtx);
    uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL);

    // Add the signature
    assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
                                dataToBeSigned.begin(), 32,
                                joinSplitPrivKey
                               ) == 0);

    CTransaction tx {mtx};
    CWalletTx wtx {NULL, tx};
    return wtx;
}
Esempio n. 7
0
static int sign_keypair(lua_State *L) {

	unsigned char sk[crypto_sign_SECRETKEYBYTES];
	unsigned char pk[crypto_sign_PUBLICKEYBYTES];
	if (crypto_sign_keypair(pk, sk)) {
		lua_pushnil(L);
		lua_pushstring(L, "Failed to create keys.");
		return 2;
	}

	lua_pushlstring(L, (char*)sk, crypto_sign_SECRETKEYBYTES);
	lua_pushlstring(L, (char*)pk, crypto_sign_PUBLICKEYBYTES);
	return 2;
}
Esempio n. 8
0
void measure(void)
{
  int i;
  int loop;

  for (loop = 0;loop < LOOPS;++loop) {
    for (i = 0;i <= TIMINGS;++i) {
      cycles[i] = cpucycles();
      crypto_sign_keypair(pk,sk);
    }
    for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
    printentry(-1,"keypair_cycles",cycles,TIMINGS);

    for (mlen = 0;mlen <= MAXTEST_BYTES;mlen += 1 + mlen / 4) {
      randombytes(m,mlen);

      for (i = 0;i <= TIMINGS;++i) {
        cycles[i] = cpucycles();
        bytes[i] = crypto_sign(sm,&smlen,m,mlen,sk);
	if (bytes[i] == 0) bytes[i] = smlen;
      }
      for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
      printentry(mlen,"cycles",cycles,TIMINGS);
      printentry(mlen,"bytes",bytes,TIMINGS);

      for (i = 0;i <= TIMINGS;++i) {
        cycles[i] = cpucycles();
        bytes[i] = crypto_sign_open(t,&tlen,sm,smlen,pk);
	if (bytes[i] == 0) bytes[i] = tlen;
      }
      for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
      printentry(mlen,"open_cycles",cycles,TIMINGS);
      printentry(mlen,"open_bytes",bytes,TIMINGS);
    }
  }
}
Esempio n. 9
0
CWalletTx GetValidSpend(ZCJoinSplit& params,
                        const libzcash::SpendingKey& sk,
                        const libzcash::Note& note, CAmount value) {
    CMutableTransaction mtx;
    mtx.vout.resize(2);
    mtx.vout[0].nValue = value;
    mtx.vout[1].nValue = 0;

    // Generate an ephemeral keypair.
    uint256 joinSplitPubKey;
    unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES];
    crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey);
    mtx.joinSplitPubKey = joinSplitPubKey;

    // Fake tree for the unused witness
    ZCIncrementalMerkleTree tree;

    libzcash::JSOutput dummyout;
    libzcash::JSInput dummyin;

    {
        if (note.value > value) {
            libzcash::SpendingKey dummykey = libzcash::SpendingKey::random();
            libzcash::PaymentAddress dummyaddr = dummykey.address();
            dummyout = libzcash::JSOutput(dummyaddr, note.value - value);
        } else if (note.value < value) {
            libzcash::SpendingKey dummykey = libzcash::SpendingKey::random();
            libzcash::PaymentAddress dummyaddr = dummykey.address();
            libzcash::Note dummynote(dummyaddr.a_pk, (value - note.value), uint256(), uint256());
            tree.append(dummynote.cm());
            dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey);
        }
    }

    tree.append(note.cm());

    boost::array<libzcash::JSInput, 2> inputs = {
        libzcash::JSInput(tree.witness(), note, sk),
        dummyin
    };

    boost::array<libzcash::JSOutput, 2> outputs = {
        dummyout, // dummy output
        libzcash::JSOutput() // dummy output
    };

    boost::array<libzcash::Note, 2> output_notes;

    // Prepare JoinSplits
    uint256 rt = tree.root();
    JSDescription jsdesc {params, mtx.joinSplitPubKey, rt,
                          inputs, outputs, 0, value, false};
    mtx.vjoinsplit.push_back(jsdesc);

    // Empty output script.
    CScript scriptCode;
    CTransaction signTx(mtx);
    uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL);

    // Add the signature
    assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
                                dataToBeSigned.begin(), 32,
                                joinSplitPrivKey
                               ) == 0);
    CTransaction tx {mtx};
    CWalletTx wtx {NULL, tx};
    return wtx;
}
Esempio n. 10
0
static void
salt_handle_req(struct salt_pcb *sc, struct salt_msg *sm)
{
	const char 		*err;
	nif_bin_t 		pk;
	nif_bin_t 		sk;
	nif_bin_t 		rb;

	/* Preemptive termination check via dirty read. */
	if (sc->sc_exit_flag) {
		err = "exiting";
		goto fail_0;
	}

	/* Perform know request or reject unknown (forwards compatibility). */
	switch (sm->msg_type) {
	case SALT_MSG_BOXKEYPAIR_REQ:
		if (! enif_alloc_binary(crypto_box_PUBLICKEYBYTES, &pk)) {
			err = "enomem";
			goto fail_0;
		}
		if (! enif_alloc_binary(crypto_box_SECRETKEYBYTES, &sk)) {
			err = "enomem";
			goto fail_1;
		}
		
		crypto_box_keypair(pk.data, sk.data);
		salt_reply_keypair(sm, &pk, &sk);
		break;

	case SALT_MSG_SIGNKEYPAIR_REQ:
		if (! enif_alloc_binary(crypto_sign_PUBLICKEYBYTES, &pk)) {
			err = "enomem";
			goto fail_0;
		}
		if (! enif_alloc_binary(crypto_sign_SECRETKEYBYTES, &sk)) {
			err = "enomem";
			goto fail_1;
		}
		
		crypto_sign_keypair(pk.data, sk.data);
		salt_reply_keypair(sm, &pk, &sk);
		break;

	case SALT_MSG_RANDOMBYTES_REQ:
		if (! enif_alloc_binary(sm->msg_aux, &rb)) {
			err = "enomem";
			goto fail_0;
		}

		/* XXX not sure I want to rely on native RNG, but not sure either if salsa20 randombytes is kosher */
		/* XXX probably best to write one that uses dev random but also encrypts output with stream cipher? */
		randombytes_buf(rb.data, rb.size);
		salt_reply_bytes(sm, &rb);
		break;

	default:
		err = "unsupported";
		goto fail_0;
	}

	return ;

	/* Failure treatment. */
 fail_1:
	enif_release_binary(&pk);
 fail_0:
	salt_reply_error(sm, err);
	return ;
}
Esempio n. 11
0
static int
generate(const char *pk_file, const char *sk_file, const char *comment)
{
    char          *pwd = xsodium_malloc(PASSWORDMAXBYTES);
    char          *pwd2 = xsodium_malloc(PASSWORDMAXBYTES);
    SeckeyStruct  *seckey_struct = xsodium_malloc(sizeof(SeckeyStruct));
    PubkeyStruct  *pubkey_struct = xsodium_malloc(sizeof(PubkeyStruct));
    unsigned char *stream ;
    FILE          *fp;

    randombytes_buf(seckey_struct->keynum_sk.keynum,
                    sizeof seckey_struct->keynum_sk.keynum);
    crypto_sign_keypair(pubkey_struct->keynum_pk.pk,
                        seckey_struct->keynum_sk.sk);
    memcpy(seckey_struct->sig_alg, SIGALG, sizeof seckey_struct->sig_alg);
    memcpy(seckey_struct->kdf_alg, KDFALG, sizeof seckey_struct->kdf_alg);
    memcpy(seckey_struct->chk_alg, CHKALG, sizeof seckey_struct->chk_alg);
    randombytes_buf(seckey_struct->kdf_salt, sizeof seckey_struct->kdf_salt);
    le64_store(seckey_struct->kdf_opslimit_le,
               crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE);
    le64_store(seckey_struct->kdf_memlimit_le,
               crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE);
    seckey_chk(seckey_struct->keynum_sk.chk, seckey_struct);
    memcpy(pubkey_struct->keynum_pk.keynum, seckey_struct->keynum_sk.keynum,
           sizeof pubkey_struct->keynum_pk.keynum);
    memcpy(pubkey_struct->sig_alg, SIGALG, sizeof pubkey_struct->sig_alg);

    puts("Please enter a password to protect the secret key.\n");
    if (get_password(pwd, PASSWORDMAXBYTES, "Password: "******"Password (one more time): ") != 0) {
        exit_msg("get_password()");
    }
    if (strcmp(pwd, pwd2) != 0) {
        exit_msg("Passwords don't match");
    }
    printf("Deriving a key from the password in order to encrypt the secret key... ");
    fflush(stdout);
    stream = xsodium_malloc(sizeof seckey_struct->keynum_sk);
    if (crypto_pwhash_scryptsalsa208sha256
        (stream, sizeof seckey_struct->keynum_sk, pwd, strlen(pwd),
         seckey_struct->kdf_salt,
         le64_load(seckey_struct->kdf_opslimit_le),
         le64_load(seckey_struct->kdf_memlimit_le)) != 0) {
        abort();
    }
    sodium_free(pwd);
    sodium_free(pwd2);
    xor_buf((unsigned char *) (void *) &seckey_struct->keynum_sk, stream,
            sizeof seckey_struct->keynum_sk);
    sodium_free(stream);
    puts("done\n");

    if ((fp = fopen_create_useronly(sk_file)) == NULL) {
        exit_err(sk_file);
    }
    xfprintf(fp, "%s%s\n", COMMENT_PREFIX, comment);
    xfput_b64(fp, (unsigned char *) (void *) seckey_struct,
              sizeof *seckey_struct);
    xfclose(fp);
    sodium_free(seckey_struct);

    if ((fp = fopen(pk_file, "w")) == NULL) {
        exit_err(pk_file);
    }
    xfprintf(fp, COMMENT_PREFIX "minisign public key %" PRIX64 "\n",
             le64_load(pubkey_struct->keynum_pk.keynum));
    xfput_b64(fp, (unsigned char *) (void *) pubkey_struct,
              sizeof *pubkey_struct);
    xfclose(fp);

    printf("The secret key was saved as %s - Keep it secret!\n", sk_file);
    printf("The public key was saved as %s - That one can be public.\n\n", pk_file);
    puts("Files signed using this key pair can be verified with the following command:\n");
    printf("minisign -Vm <file> -P ");
    xfput_b64(stdout, (unsigned char *) (void *) pubkey_struct,
              sizeof *pubkey_struct);
    puts("");
    sodium_free(pubkey_struct);

    return 0;
}
int main(void)
{
  volatile unsigned char a; /* Mark the beginning of the stack */

  for(i=0;i<5;i++)
  {
    canary = random();
    WRITE_CANARY(&a);
    crypto_sign_keypair(pk,sk);
    newctr =(unsigned int)&a - (unsigned int)&_end - stack_count(canary);
    ctr = (newctr>ctr)?newctr:ctr;
  }
  print_stack(XSTR(crypto_sign_keypair),-1,ctr);

  for(i=0;i<5;i++)
  {
    canary = random();
    WRITE_CANARY(&a);
    crypto_sign(sm,&smlen,sm,0,sk);
    newctr =(unsigned int)&a - (unsigned int)&_end - stack_count(canary);
    ctr = (newctr>ctr)?newctr:ctr;
  }
  print_stack(XSTR(crypto_sign),0,ctr);

  for(i=0;i<5;i++)
  {
    canary = random();
    WRITE_CANARY(&a);
    crypto_sign_open(sm,&mlen,sm,smlen,pk);
    newctr =(unsigned int)&a - (unsigned int)&_end - stack_count(canary);
    ctr = (newctr>ctr)?newctr:ctr;
  }
  print_stack(XSTR(crypto_sign_open),smlen,ctr);

  for(j=1;j<=MAXTEST_BYTES;j<<=1)
  {
    mlen = j;

    for(i=0;i<5;i++)
    {
      canary = random();
      WRITE_CANARY(&a);
      crypto_sign(sm,&smlen,sm,mlen,sk);
      newctr =(unsigned int)&a - (unsigned int)&_end - stack_count(canary);
      ctr = (newctr>ctr)?newctr:ctr;
    }
    print_stack(XSTR(crypto_sign),mlen,ctr);

    for(i=0;i<5;i++)
    {
      canary = random();
      WRITE_CANARY(&a);
      crypto_sign_open(sm,&mlen,sm,smlen,pk);
      newctr =(unsigned int)&a - (unsigned int)&_end - stack_count(canary);
      ctr = (newctr>ctr)?newctr:ctr;
    }
    print_stack(XSTR(crypto_sign_open),smlen,ctr);
  }

  avr_end();
  return 0;
}
Esempio n. 13
0
/*
 * Create a new set of master keys.
 *
 * Seed is optional, can be NULL. It can be of any length and doesn't
 * require to have high entropy. It will be used as entropy source
 * in addition to the OSs CPRNG.
 *
 * WARNING: Don't use Entropy from the OSs CPRNG as seed!
 */
return_status master_keys_create(
		master_keys ** const keys, //output
		const buffer_t * const seed,
		buffer_t * const public_signing_key, //output, optional, can be NULL
		buffer_t * const public_identity_key //output, optional, can be NULL
		) {
	return_status status = return_status_init();


	//seeds
	buffer_t *crypto_seeds = NULL;

	if (keys == NULL) {
		throw(INVALID_INPUT, "Invalid input for master_keys_create.");
	}

	*keys = sodium_malloc(sizeof(master_keys));
	throw_on_failed_alloc(*keys);

	//initialize the buffers
	buffer_init_with_pointer((*keys)->public_signing_key, (*keys)->public_signing_key_storage, PUBLIC_MASTER_KEY_SIZE, PUBLIC_MASTER_KEY_SIZE);
	buffer_init_with_pointer((*keys)->private_signing_key, (*keys)->private_signing_key_storage, PRIVATE_MASTER_KEY_SIZE, PRIVATE_MASTER_KEY_SIZE);
	buffer_init_with_pointer((*keys)->public_identity_key, (*keys)->public_identity_key_storage, PUBLIC_KEY_SIZE, PUBLIC_KEY_SIZE);
	buffer_init_with_pointer((*keys)->private_identity_key, (*keys)->private_identity_key_storage, PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE);

	if (seed != NULL) { //use external seed
		//create the seed buffer
		crypto_seeds = buffer_create_with_custom_allocator(
				crypto_sign_SEEDBYTES + crypto_box_SEEDBYTES,
				crypto_sign_SEEDBYTES + crypto_box_SEEDBYTES,
				sodium_malloc,
				sodium_free);
		throw_on_failed_alloc(crypto_seeds);

		status = spiced_random(crypto_seeds, seed, crypto_seeds->buffer_length);
		throw_on_error(GENERIC_ERROR, "Failed to create spiced random data.");

		//generate the signing keypair
		int status_int = 0;
		status_int = crypto_sign_seed_keypair(
				(*keys)->public_signing_key->content,
				(*keys)->private_signing_key_storage,
				crypto_seeds->content);
		if (status_int != 0) {
			throw(KEYGENERATION_FAILED, "Failed to generate signing keypair.");
		}

		//generate the identity keypair
		status_int = crypto_box_seed_keypair(
				(*keys)->public_identity_key->content,
				(*keys)->private_identity_key->content,
				crypto_seeds->content + crypto_sign_SEEDBYTES);
		if (status_int != 0) {
			throw(KEYGENERATION_FAILED, "Failed to generate encryption keypair.");
		}
	} else { //don't use external seed
		//generate the signing keypair
		int status_int = 0;
		status_int = crypto_sign_keypair(
				(*keys)->public_signing_key->content,
				(*keys)->private_signing_key->content);
		if (status_int != 0) {
			throw(KEYGENERATION_FAILED, "Failed to generate signing keypair.");
		}

		//generate the identity keypair
		status_int = crypto_box_keypair(
				(*keys)->public_identity_key->content,
				(*keys)->private_identity_key->content);
		if (status_int != 0) {
			throw(KEYGENERATION_FAILED, "Failed to generate encryption keypair.");
		}
	}

	//copy the public keys if requested
	if (public_signing_key != NULL) {
		if (public_signing_key->buffer_length < PUBLIC_MASTER_KEY_SIZE) {
			public_signing_key->content_length = 0;
			throw(INCORRECT_BUFFER_SIZE, "Public master key buffer is too short.");
		}

		if (buffer_clone(public_signing_key, (*keys)->public_signing_key) != 0) {
			throw(BUFFER_ERROR, "Failed to copy public signing key.");
		}
	}
	if (public_identity_key != NULL) {
		if (public_identity_key->buffer_length < PUBLIC_KEY_SIZE) {
			public_identity_key->content_length = 0;
			throw(INCORRECT_BUFFER_SIZE, "Public encryption key buffer is too short.");
		}

		if (buffer_clone(public_identity_key, (*keys)->public_identity_key) != 0) {
			throw(BUFFER_ERROR, "Failed to copy public encryption key.");
		}
	}

cleanup:
	buffer_destroy_with_custom_deallocator_and_null_if_valid(crypto_seeds, sodium_free);

	on_error {
		if (keys != NULL) {
			sodium_free_and_null_if_valid(*keys);
		}

		return status;
	}

	if ((keys != NULL) && (*keys != NULL)) {
		sodium_mprotect_noaccess(*keys);
	}
	return status;
}
Esempio n. 14
0
void static RandomTransaction(CMutableTransaction &tx, bool fSingle, uint32_t consensusBranchId) {
    tx.fOverwintered = insecure_rand() % 2;
    if (tx.fOverwintered) {
        if (insecure_rand() % 2) {
            tx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
            tx.nVersion = sapling_version_dist(rng);
        } else {
            tx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
            tx.nVersion = overwinter_version_dist(rng);
        }
        tx.nExpiryHeight = (insecure_rand() % 2) ? insecure_rand() : 0;
    } else {
        tx.nVersion = insecure_rand() & 0x7FFFFFFF;
    }
    tx.vin.clear();
    tx.vout.clear();
    tx.vShieldedSpend.clear();
    tx.vShieldedOutput.clear();
    tx.vjoinsplit.clear();
    tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0;
    int ins = (insecure_rand() % 4) + 1;
    int outs = fSingle ? ins : (insecure_rand() % 4) + 1;
    int shielded_spends = (insecure_rand() % 4) + 1;
    int shielded_outs = (insecure_rand() % 4) + 1;
    int joinsplits = (insecure_rand() % 4);
    for (int in = 0; in < ins; in++) {
        tx.vin.push_back(CTxIn());
        CTxIn &txin = tx.vin.back();
        txin.prevout.hash = GetRandHash();
        txin.prevout.n = insecure_rand() % 4;
        RandomScript(txin.scriptSig);
        txin.nSequence = (insecure_rand() % 2) ? insecure_rand() : (unsigned int)-1;
    }
    for (int out = 0; out < outs; out++) {
        tx.vout.push_back(CTxOut());
        CTxOut &txout = tx.vout.back();
        txout.nValue = insecure_rand() % 100000000;
        RandomScript(txout.scriptPubKey);
    }
    if (tx.nVersionGroupId == SAPLING_VERSION_GROUP_ID) {
        tx.valueBalance = insecure_rand() % 100000000;
        for (int spend = 0; spend < shielded_spends; spend++) {
            SpendDescription sdesc;
            sdesc.cv = GetRandHash();
            sdesc.anchor = GetRandHash();
            sdesc.nullifier = GetRandHash();
            sdesc.rk = GetRandHash();
            randombytes_buf(sdesc.zkproof.begin(), sdesc.zkproof.size());
            tx.vShieldedSpend.push_back(sdesc);
        }
        for (int out = 0; out < shielded_outs; out++) {
            OutputDescription odesc;
            odesc.cv = GetRandHash();
            odesc.cm = GetRandHash();
            odesc.ephemeralKey = GetRandHash();
            randombytes_buf(odesc.encCiphertext.begin(), odesc.encCiphertext.size());
            randombytes_buf(odesc.outCiphertext.begin(), odesc.outCiphertext.size());
            randombytes_buf(odesc.zkproof.begin(), odesc.zkproof.size());
            tx.vShieldedOutput.push_back(odesc);
        }
    }
    if (tx.nVersion >= 2) {
        for (int js = 0; js < joinsplits; js++) {
            JSDescription jsdesc;
            if (insecure_rand() % 2 == 0) {
                jsdesc.vpub_old = insecure_rand() % 100000000;
            } else {
                jsdesc.vpub_new = insecure_rand() % 100000000;
            }

            jsdesc.anchor = GetRandHash();
            jsdesc.nullifiers[0] = GetRandHash();
            jsdesc.nullifiers[1] = GetRandHash();
            jsdesc.ephemeralKey = GetRandHash();
            jsdesc.randomSeed = GetRandHash();
            randombytes_buf(jsdesc.ciphertexts[0].begin(), jsdesc.ciphertexts[0].size());
            randombytes_buf(jsdesc.ciphertexts[1].begin(), jsdesc.ciphertexts[1].size());
            if (tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION) {
                libzcash::GrothProof zkproof;
                randombytes_buf(zkproof.begin(), zkproof.size());
                jsdesc.proof = zkproof;
            } else {
                jsdesc.proof = libzcash::PHGRProof::random_invalid();
            }
            jsdesc.macs[0] = GetRandHash();
            jsdesc.macs[1] = GetRandHash();

            tx.vjoinsplit.push_back(jsdesc);
        }

        unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES];
        crypto_sign_keypair(tx.joinSplitPubKey.begin(), joinSplitPrivKey);

        // Empty output script.
        CScript scriptCode;
        CTransaction signTx(tx);
        uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);

        assert(crypto_sign_detached(&tx.joinSplitSig[0], NULL,
                                    dataToBeSigned.begin(), 32,
                                    joinSplitPrivKey
                                    ) == 0);
    }
}
Esempio n. 15
0
// CryptoEngine constructor
CryptoEngine::CryptoEngine(const std::string &context):context_(context), file_utils_(context), hkdf_(context){

    try {

        if(context.empty()) {
            std::cout << "Cannot initialize the crypto engine with an empty context." << std::endl;
            throw g_crypto_engine_initialization_failure;
        }

        // Create the standard keys folder
        // IMPORTANT DO NOT REMOVE !!!!!
        // THE FOLDER CREATION CAN FAIL !!!!
        if(!file_utils_.CreateKeysFolder()) {
            std::cout << "Could not create the folder where to store the keys." << std::endl;
            throw g_crypto_engine_initialization_failure;
        }

        // ****************************************************
        // ######## HKDF MASTER KEY
        // Always generate a new HKDF master key when the crypto engine is initialized

        // create the nonce master key
        // init a uint8_t buffer
        uint8_t buffer_hkdf_master_key[KEY_SIZE];


        // read KEY_SIZE bytes into the buffer
        int hkdf_random_result = RAND_bytes(buffer_hkdf_master_key, KEY_SIZE);
        if (1 != hkdf_random_result) {
            std::cout << "Could not generate the HKDF master key. Not enough entropy" << std::endl;
            throw g_crypto_engine_initialization_failure;
        }

        nonce_master_key_ = std::string(reinterpret_cast<const char *>(buffer_hkdf_master_key), KEY_SIZE);

        if (nonce_master_key_.size() != KEY_SIZE) {
            std::cout << "The loaded HKDF master key is empty or too short." << std::endl;
            throw g_crypto_engine_initialization_failure;
        }


        // ****************************************************
        // ######## SALT KEY
        // Always generate a new SALT key when the crypto engine is initialized

        // create the nonce master key
        // init a uint8_t buffer
        uint8_t buffer_salt_key[KEY_SIZE];

        // read KEY_SIZE bytes into the buffer
        int salt_random_result = RAND_bytes(buffer_salt_key, KEY_SIZE);
        if (1 != salt_random_result) {
            std::cout << "Could not generate the salt key. Not enough entropy" << std::endl;
            throw g_crypto_engine_initialization_failure;
        }

        salt_ = std::string(reinterpret_cast<const char *>(buffer_salt_key), KEY_SIZE);

        if (salt_.size() != KEY_SIZE) {
            std::cout << "The loaded salt key is empty or too short." << std::endl;
            throw g_crypto_engine_initialization_failure;
        }


        // ****************************************************
        // ######## SECRET KEY
        // if the key already exists then load it
        if(file_utils_.KeyExists(kSecret)) {
            // read the key back
            secret_key_ = file_utils_.ReadKey(kSecret);
            // check the size of the key which should match the predefined one
            if (secret_key_.size() != KEY_SIZE) {
                std::cout << "The loaded secret key is empty or too short." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

        } else { // otherwise generate one

            // create the nonce master key
            // init a uint8_t buffer
            uint8_t buffer_secret_key[KEY_SIZE];

            // read KEY_SIZE bytes into the buffer
            int secret_random_result = RAND_bytes(buffer_secret_key, KEY_SIZE);
            if (1 != secret_random_result) {
                std::cout << "Could not generate the secret key. Not enough entropy" << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

            secret_key_ = std::string(reinterpret_cast<const char *>(buffer_secret_key), KEY_SIZE);

            if (secret_key_.size() != KEY_SIZE) {
                std::cout << "The loaded secret key is empty or too short." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

            if (!file_utils_.WriteKey(secret_key_,kSecret)) {
                std::cout << "Could not store the secret key." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }
        }

        // ****************************************************
        // ######## PUBLIC/PRIVATE KEY

        if(file_utils_.KeyExists(kPrivate) && file_utils_.KeyExists(kPublic)) {
            // read the keys back
            private_key_ = file_utils_.ReadKey(kPrivate);
            // check the size of the key which should match the predefined one
            if (private_key_.size() != KEY_SIZE) {
                std::cout << "The loaded private key is empty or too short." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

            public_key_ = file_utils_.ReadKey(kPublic);
            // check the size of the key which should match the predefined one
            if (public_key_.size() != KEY_SIZE) {
                std::cout << "The loaded public key is empty or too short." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

        } else { // otherwise generate them

            // generate the private/public key
            public_key_ = crypto_box_keypair(&private_key_);

            if (private_key_.size() != KEY_SIZE) {
                std::cout << "The loaded private key is empty or too short." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

            if (public_key_.size() != KEY_SIZE) {
                std::cout << "The loaded public key is empty or too short." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

            if (!file_utils_.WriteKey(private_key_,kPrivate)) {
                std::cout << "Could not store the private key." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }
            if (!file_utils_.WriteKey(public_key_, kPublic)) {
                std::cout << "Could not store the public key." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

        }

        // ****************************************************
        // ######## PUBLIC/PRIVATE SIGNING KEY

        if(file_utils_.KeyExists(kPrivateSign) && file_utils_.KeyExists(kPublicSign)) {
            // read the keys back
            sign_private_key_ = file_utils_.ReadKey(kPrivateSign);
            // check the size of the key which should match the predefined one
            if (sign_private_key_.size() != SIGNING_KEY_SIZE) {
                std::cout << "The loaded private signing key is empty or too short." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

            sign_public_key_ = file_utils_.ReadKey(kPublicSign);
            // check the size of the key which should match the predefined one
            if (sign_public_key_.size() != KEY_SIZE) {
                std::cout << "The loaded public signing key is empty or too short." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

        } else { // otherwise generate them

            // generate the private/public signing key
            sign_public_key_ = crypto_sign_keypair(&sign_private_key_);

            if (sign_private_key_.size() != SIGNING_KEY_SIZE) {
                std::cout << "The loaded private signing key is empty or too short." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

            if (sign_public_key_.size() != KEY_SIZE) {
                std::cout << "The loaded public signing key is empty or too short." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

            if (!file_utils_.WriteKey(sign_private_key_,kPrivateSign)) {
                std::cout << "Could not store the private signing key." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }
            if (!file_utils_.WriteKey(sign_public_key_, kPublicSign)) {
                std::cout << "Could not store the publicsigning key." << std::endl;
                throw g_crypto_engine_initialization_failure;
            }

        }

    } catch (std::exception &e) {
        std::cout << e.what() << std::endl;
        throw g_crypto_engine_initialization_failure;
    }
}
Esempio n. 16
0
int proc_sign(const ts::wstrings_c & pars)
{
    if (pars.size() < 3) return 0;

    ts::wstr_c arch = pars.get(1); ts::fix_path( arch, FNO_SIMPLIFY );
    ts::wstr_c proc = pars.get(2); ts::fix_path( proc, FNO_SIMPLIFY );

    if (!is_file_exists(arch.as_sptr()))
    {
        Print(FOREGROUND_RED, "arch file not found: %s\n", to_str(arch).cstr()); return 0;
    }
    if (!is_file_exists(proc.as_sptr()))
    {
        Print(FOREGROUND_RED, "proc file not found: %s\n", to_str(proc).cstr()); return 0;
    }
    ts::buf_c b; b.load_from_disk_file(arch);
    int archlen = b.size();
    ts::md5_c md5;
    md5.update(b.data(), b.size()); md5.done();
    ts::abp_c bp;
    b.load_from_disk_file(proc);
    bp.load(b.cstr());

    ts::wstr_c procpath = ts::fn_get_path(proc);
    auto pa = [&]( ts::asptr p ) ->ts::wstr_c
    {
        return ts::fn_join(procpath, to_wstr(bp.get_string(p)));
    };

    b.load_from_disk_file( pa(CONSTASTR("ver")) );
    ts::str_c ver = b.cstr();
    ver.replace_all('/','.').trim();

    ts::str_c ss(CONSTASTR("ver="));
    ss.append( ver );
    ss.append(CONSTASTR("\r\nurl="));

    ts::str_c path = bp.get_string(CONSTASTR("path"));
    path.replace_all(CONSTASTR("%ver%"), ver);
    path.replace_all(CONSTASTR("%https%"), CONSTASTR("https://"));
    path.replace_all(CONSTASTR("%http%"), CONSTASTR("http://"));
    path.appendcvt(ts::fn_get_name_with_ext(arch));


    ss.append(path);

    ss.append(CONSTASTR("\r\nsize="));
    ss.append_as_uint(archlen);
    ss.append(CONSTASTR("\r\nmd5="));
    ss.append_as_hex(md5.result(), 16);

    unsigned char pk[crypto_sign_PUBLICKEYBYTES];
    unsigned char sk[crypto_sign_SECRETKEYBYTES];
    b.clear();
    b.load_from_disk_file( pa(CONSTASTR("sk")) );
    if (b.size() != crypto_sign_SECRETKEYBYTES)
    {
        rebuild:
        crypto_sign_keypair(pk, sk);

        FILE *f = _wfopen(pa(CONSTASTR("sk")), L"wb");
        fwrite(sk, 1, sizeof(sk), f);
        fclose(f);

        ts::str_c spk;
        for(int i=0;i<crypto_sign_PUBLICKEYBYTES;++i)
            spk.append(CONSTASTR("0x")).append_as_hex(pk[i]).append(CONSTASTR(", "));
        spk.trunc_length(2);

        f = _wfopen(pa(CONSTASTR("pk")), L"wb");
        fwrite(spk.cstr(), 1, spk.get_length(), f);
        fclose(f);
    } else
    {
        memcpy(sk, b.data(), crypto_sign_SECRETKEYBYTES);
        crypto_sign_ed25519_sk_to_pk(pk, sk);

        b.load_from_disk_file( pa(CONSTASTR("pk")) );
        ts::token<char> t(b.cstr(), ',');
        int n = 0;
        for(;t; ++t, ++n)
        {
            if (n >= sizeof(pk)) goto rebuild;
            ts::str_c nx(*t);
            nx.trim();
            if (pk[n] != (byte)nx.as_uint())
                goto rebuild;
        }
        if (n < sizeof(pk)) goto rebuild;
    }

    unsigned char sig[crypto_sign_BYTES];
    unsigned long long siglen;
    crypto_sign_detached(sig,&siglen, (const byte *)ss.cstr(), ss.get_length(), sk);

    ss.append(CONSTASTR("\r\nsign="));
    ss.append_as_hex(sig, (int)siglen);

    if (CONSTASTR("github") == bp.get_string(CONSTASTR("wiki")))
    {
        ss.insert(0,CONSTASTR("[begin]\r\n"));
        ss.replace_all(CONSTASTR("\r\n"), CONSTASTR("`<br>\r\n`"));
        ss.replace_all(CONSTASTR("[begin]`"), CONSTASTR("[begin]"));
        ss.append(CONSTASTR("`<br>\r\n[end]<br>\r\n"));
    }

    FILE *f = _wfopen(pa(CONSTASTR("result")), L"wb");
    fwrite(ss.cstr(), 1, ss.get_length(), f);
    fclose(f);


    return 0;
}