int main(void) { u8 output[64], stream[64]; ECRYPT_ctx ctx; int i; // test the permutation first for(i=0;i<64;i++) stream[i]=(i+1); for(i=0;i<2048;i++) { salsa20_wordtobyte(output, (u32*)stream); } bin2hex("permutation result", output, 64); memset(&ctx, 0, sizeof(ctx)); ECRYPT_keysetup(&ctx, tv_key, 256, 64); ECRYPT_ivsetup(&ctx, tv_nonce); for(i=0;i<2048;i++) { ECRYPT_keystream_bytes(&ctx, stream, 64); } bin2hex("stream result", stream, 64); return 0; }
static void salsa20_encrypt_bytes(struct salsa20_ctx *ctx, u8 *dst, const u8 *src, unsigned int bytes) { u8 buf[64]; if (dst != src) memcpy(dst, src, bytes); while (bytes) { salsa20_wordtobyte(buf, ctx->input); ctx->input[8] = PLUSONE(ctx->input[8]); if (!ctx->input[8]) ctx->input[9] = PLUSONE(ctx->input[9]); if (bytes <= 64) { crypto_xor(dst, buf, bytes); return; } crypto_xor(dst, buf, 64); bytes -= 64; dst += 64; } }
void chacha_xor(chacha_ctx_t *x,const unsigned char *in,unsigned char *out,unsigned bytes) { unsigned char output[64]; unsigned i; if (!bytes) return; for (;;) { salsa20_wordtobyte(output,x->input); x->input[12] += 1; if (bytes <= 64) { for (i = 0;i < bytes;++i) out[i] = in[i] ^ output[i]; return; } for (i = 0;i < 64;++i) out[i] = in[i] ^ output[i]; bytes -= 64; out += 64; in += 64; } }
void ECRYPT_encrypt_bytes(ECRYPT_ctx *x,const u8 *m,u8 *c,u32 bytes) { u8 output[64]; unsigned int i; if (!bytes) return; for (;;) { salsa20_wordtobyte(output,x->input); x->input[8] = PLUSONE(x->input[8]); if (!x->input[8]) { x->input[9] = PLUSONE(x->input[9]); /* stopping at 2^70 bytes per nonce is user's responsibility */ } if (bytes <= 64) { for (i = 0;i < bytes;++i) c[i] = m[i] ^ output[i]; return; } for (i = 0;i < 64;++i) c[i] = m[i] ^ output[i]; bytes -= 64; c += 64; m += 64; } }
void chacha_encrypt_bytes(u32 *x,const byte *m,byte *c,u32 bytes) { byte output[64]; int i; if (!bytes) return; for (;;) { salsa20_wordtobyte(output,x); x[12] = PLUSONE(x[12]); if (!x[12]) { x[13] = PLUSONE(x[13]); /* stopping at 2^70 bytes per nonce is user's responsibility */ } if (bytes <= 64) { for (i = 0;i < bytes;++i) c[i] = m[i] ^ output[i]; return; } for (i = 0;i < 64;++i) c[i] = m[i] ^ output[i]; bytes -= 64; c += 64; m += 64; } }
void ECRYPT_Salsa::ECRYPT_encrypt_bytes(void *xa,const u8 *m,u8 *c,u32 bytes) { SALSA_ctx* x = (SALSA_ctx*)xa; u8 output[64]; int i; if (!bytes) return; for (;;) { salsa20_wordtobyte(output,x->input, numRounds); x->input[8] = PLUSONE(x->input[8]); if (!x->input[8]) { x->input[9] = PLUSONE(x->input[9]); /* stopping at 2^70 bytes per nonce is user's responsibility */ } if (bytes <= 64) { for (i = 0;i < bytes;++i) c[i] = m[i] ^ output[i]; return; } for (i = 0;i < 64;++i) c[i] = m[i] ^ output[i]; bytes -= 64; c += 64; m += 64; } }