blob: 91d949c5d478e7b58583b256995aa725ea246dfe [file] [log] [blame] [raw]
/*
* Copyright 2015-2016 Rivoreo
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
package org.rivoreo.crypto;
public class ECIES_ChaCha20 extends ECIES implements ECIES.NonceListener {
public ECIES_ChaCha20(SECTDomainParameters dp, int chacha20_key_size) {
super(dp);
if(chacha20_key_size != 16 && chacha20_key_size != 32) {
throw new IllegalArgumentException("chacha20_key_size can only be 16 or 32");
}
key_size = chacha20_key_size;
nonce = new byte[8];
set_symmetric_crypt_nonce_listener(this, 8);
}
public ECIES_ChaCha20(SECTDomainParameters dp) {
this(dp, 32);
}
private final int key_size;
private final byte[] nonce;
public void set_nonce(byte[] nonce) {
if(nonce.length < 8) throw new IllegalArgumentException("nonce.length < 8");
for(int i=0; i<8; i++) this.nonce[i] = nonce[i];
}
protected int get_symmetric_key_bytes() {
return key_size;
}
protected void ctr_crypt(byte[] data, int len, final byte[] key) {
System.err.printf("method: org.rivoreo.crypto.ECIES_ChaCha20::ctr_crypt(byte[%d], %d, final byte[%d])\n", data.length, len, key.length);
ChaCha20 ctx = new ChaCha20(key, key_size, nonce);
ctx.encrypt(data, len);
}
protected void cbc_mac(byte[] mac, final byte[] data, int len, final byte[] key) {
System.err.printf("method: org.rivoreo.crypto.ECIES_ChaCha20::cbc_mac(byte[%d], final byte[%d], %d, final byte[%d])\n", mac.length, data.length, len, key.length);
ChaCha20 ctx = new ChaCha20(key, key_size, nonce);
int blen, i, di = 0;
int_to_bytes(mac, 0, 0);
int_to_bytes(mac, 4, len);
ctx.encrypt(mac, ECIES_CHUNK_OVERHEAD);
while(len > 0) {
blen = Math.min(ECIES_CHUNK_OVERHEAD, len);
i = 0;
while(i < blen) mac[i++] ^= data[di++];
ctx.encrypt(mac, ECIES_CHUNK_OVERHEAD);
len -= blen;
}
}
protected void davies_meyer(byte[] out, final byte[] in, int ilen) {
System.err.printf("method: org.rivoreo.crypto.ECIES_ChaCha20::davies_meyer(byte[%d], final byte[%d], %d)\n", out.length, in.length, ilen);
debug_print_bytes(nonce, 8);
int i, offset = 0;
byte[] buffer = new byte[key_size / 2];
ChaCha20 ctx;
for(i = 0; i < key_size / 2; i++) out[i] = 0;
while(ilen-- > 0) {
ctx = new ChaCha20(sub_byte_array(in, offset), key_size, nonce);
for(i = 0; i < buffer.length; i++) buffer[i] = out[i];
ctx.encrypt(buffer, buffer.length);
debug_print_bytes(buffer, buffer.length);
for(i = 0; i < buffer.length; i++) out[i] ^= buffer[i];
offset += key_size;
}
}
}