bool encrypt(encrypted_private& out_private, const ec_secret& secret, const std::string& passphrase, uint8_t version, bool compressed) { ek_salt salt; if (!address_salt(salt, secret, version, compressed)) return false; const auto derived = split(scrypt_private(normal(passphrase), salt)); const auto prefix = parse_encrypted_private::prefix_factory(version, false); auto encrypted1 = xor_data<half>(secret, derived.left); aes256_encrypt(derived.right, encrypted1); auto encrypted2 = xor_data<half>(secret, derived.left, half); aes256_encrypt(derived.right, encrypted2); return build_checked_array(out_private, { prefix, set_flags(compressed), salt, encrypted1, encrypted2 }); }
static bool create_public_key(encrypted_public& out_public, const one_byte& flags, const ek_salt& salt, const ek_entropy& entropy, const hash_digest& derived1, const hash_digest& derived2, const ec_secret& secret, uint8_t version) { ec_compressed point; if (!secret_to_public(point, secret)) return false; const auto prefix = parse_encrypted_public::prefix_factory(version); const auto hash = point_hash(point); auto encrypted1 = xor_data<half>(hash, derived1); aes256_encrypt(derived2, encrypted1); auto encrypted2 = xor_data<half>(hash, derived1, half); aes256_encrypt(derived2, encrypted2); const auto sign = point_sign(point.front(), derived2); return build_checked_array(out_public, { prefix, flags, salt, entropy, sign, encrypted1, encrypted2 }); }
static void create_private_key(encrypted_private& out_private, const one_byte& flags, const ek_salt& salt, const ek_entropy& entropy, const hash_digest& derived1, const hash_digest& derived2, const ek_seed& seed, uint8_t version) { const auto prefix = parse_encrypted_private::prefix_factory(version, true); auto encrypt1 = xor_data<half>(seed, derived1); aes256_encrypt(derived2, encrypt1); const auto combined = splice(slice<quarter, half>(encrypt1), slice<half, half + quarter>(seed)); auto encrypt2 = xor_data<half>(combined, derived1, 0, half); aes256_encrypt(derived2, encrypt2); const auto quarter1 = slice<0, quarter>(encrypt1); build_checked_array(out_private, { prefix, flags, salt, entropy, quarter1, encrypt2 }); }
/* FIXME: Generalize so that it generates a few more blocks at a * time. */ static void yarrow_generate_block(struct yarrow256_ctx *ctx, uint8_t *block) { unsigned i; aes256_encrypt(&ctx->key, sizeof(ctx->counter), block, ctx->counter); /* Increment counter, treating it as a big-endian number. This is * machine independent, and follows appendix B of the NIST * specification of cipher modes of operation. * * We could keep a representation of the counter as 4 32-bit values, * and write entire words (in big-endian byteorder) into the counter * block, whenever they change. */ for (i = sizeof(ctx->counter); i--; ) { if (++ctx->counter[i]) break; } }
void yarrow256_fast_reseed(struct yarrow256_ctx *ctx) { uint8_t digest[SHA256_DIGEST_SIZE]; unsigned i; #if YARROW_DEBUG fprintf(stderr, "yarrow256_fast_reseed\n"); #endif /* We feed two block of output using the current key into the pool * before emptying it. */ if (ctx->seeded) { uint8_t blocks[AES_BLOCK_SIZE * 2]; yarrow_generate_block(ctx, blocks); yarrow_generate_block(ctx, blocks + AES_BLOCK_SIZE); sha256_update(&ctx->pools[YARROW_FAST], sizeof(blocks), blocks); } sha256_digest(&ctx->pools[YARROW_FAST], sizeof(digest), digest); /* Iterate */ yarrow_iterate(digest); aes256_set_encrypt_key(&ctx->key, digest); ctx->seeded = 1; /* Derive new counter value */ memset(ctx->counter, 0, sizeof(ctx->counter)); aes256_encrypt(&ctx->key, sizeof(ctx->counter), ctx->counter, ctx->counter); /* Reset estimates. */ for (i = 0; i<ctx->nsources; i++) ctx->sources[i].estimate[YARROW_FAST] = 0; }
int test_aes256() { char tmp[16]; aes256_key skey; int i; #ifndef SMALL_CODE u32 old_p; #endif #ifdef SMALL_CODE /* initialize AES tables */ aes256_gentab(); #else /* allow execute code from key buffer */ if (VirtualProtect(&skey, sizeof(skey), PAGE_EXECUTE_READWRITE, &old_p) == 0) { return 0; } #endif /* test basic assembler inmpementation */ for (i = 0; i < array_num(aes256_vectors); i++) { #ifdef SMALL_CODE aes256_set_key(aes256_vectors[i].key, &skey); aes256_encrypt(aes256_vectors[i].plaintext, tmp, &skey); #else aes256_asm_set_key(aes256_vectors[i].key, &skey); aes256_asm_encrypt(aes256_vectors[i].plaintext, tmp, &skey); #endif if (memcmp(aes256_vectors[i].ciphertext, tmp, sizeof(tmp)) != 0) { return 0; } #ifdef SMALL_CODE aes256_decrypt(aes256_vectors[i].ciphertext, tmp, &skey); #else aes256_asm_decrypt(aes256_vectors[i].ciphertext, tmp, &skey); #endif if (memcmp(aes256_vectors[i].plaintext, tmp, sizeof(tmp)) != 0) { return 0; } #if !defined(SMALL_CODE) || !defined(_M_X64) /* test AES with VIA Padlock API */ if (aes256_padlock_available() != 0) { #ifdef SMALL_CODE aes256_padlock_encrypt(aes256_vectors[i].plaintext, tmp, &skey); #else aes256_padlock_encrypt(aes256_vectors[i].plaintext, tmp, 1, &skey); #endif if (memcmp(aes256_vectors[i].ciphertext, tmp, sizeof(tmp)) != 0) { return 0; } #ifdef SMALL_CODE aes256_padlock_decrypt(aes256_vectors[i].ciphertext, tmp, &skey); #else aes256_padlock_decrypt(aes256_vectors[i].ciphertext, tmp, 1, &skey); #endif if (memcmp(aes256_vectors[i].plaintext, tmp, sizeof(tmp)) != 0) { return 0; } } #endif } return 1; }
int main(int ac, char **av) { if(ac < 4) fprintf(stderr, "Usage: %s <src> <dst> <pwd>\n", av[0]); else aes256_encrypt(av[1], av[2], av[3]); return 0; }