blob: 2f2556c3a06dea378105b328472682fae10c34f9 [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_XTEA extends ECIES {
public ECIES_XTEA(SECTDomainParameters dp) {
super(dp);
}
private void debug_print_integers(int[] a, int len) {
for(int i=0; i<a.length; i++) System.err.printf("0x%x\n", a[i]);
}
/*
private void init_key(int[] k, int offset, final byte[] key) {
System.err.printf("method: org.rivoreo.crypto.ECIES_XTEA::init_key(int[%d], %d, final byte[%d])\n", k.length, offset, key.length);
k[offset] = unsigned_bytes_to_int(key, 0);
k[offset + 1] = unsigned_bytes_to_int(key, 4);
k[offset + 2] = unsigned_bytes_to_int(key, 8);
k[offset + 3] = unsigned_bytes_to_int(key, 12);
}
*/
private void init_key(int[] k, final byte[] key) {
//init_key(k, 0, key);
k[0] = unsigned_bytes_to_int(key, 0);
k[1] = unsigned_bytes_to_int(key, 4);
k[2] = unsigned_bytes_to_int(key, 8);
k[3] = unsigned_bytes_to_int(key, 12);
}
/*
private void encipher_block(byte[] data, final int[] k) {
System.err.printf("method: org.rivoreo.crypto.ECIES_XTEA::encipher_block(byte[%d], final int[%d])\n", data.length, k.length);
long sum = 0, delta = 0x9e3779b9l;
long y = unsigned_bytes_to_int(data, 0), z = unsigned_bytes_to_int(data, 4);
//System.err.printf("encipher_block: y = %d, z = %d\n", y, z);
System.err.printf("encipher_block: delta = %d\n", delta);
for(int i = 0; i < 32; i++) {
y += ((z << 4 ^ z >>> 5) + z) ^ (sum + k[(int)(sum & 3)]);
System.err.printf("encipher_block: y = %d\n", y);
sum += delta;
System.err.printf("encipher_block: sum = %d\n", sum);
z += ((y << 4 ^ y >>> 5) + y) ^ (sum + k[(int)(sum >>> 11 & 3)]);
System.err.printf("encipher_block: z = %d\n", z);
}
int_to_bytes(data, 0, (int)y);
int_to_bytes(data, 4, (int)z);
}
*/
private void encipher_block(byte[] data, final int[] k) {
System.err.printf("method: org.rivoreo.crypto.ECIES_XTEA::encipher_block(byte[%d], final int[%d])\n", data.length, k.length);
long sum = 0, delta = 0x9e3779b9l;
int y = unsigned_bytes_to_int(data, 0), z = unsigned_bytes_to_int(data, 4);
//System.err.printf("encipher_block: y = %d, z = %d\n", y, z);
//System.err.printf("encipher_block: delta = %d\n", delta);
for(int i = 0; i < 32; i++) {
//y += ((z << 4 ^ z >>> 5) + z) ^ (sum + k[(int)(sum & 3)]);
y = (int)((long)y + (((z << 4 ^ z >>> 5) + unsigned_int_to_long(z)) ^ (sum + unsigned_int_to_long(k[(int)(sum & 3)]))));
// System.err.printf("encipher_block: y = %d\n", y);
sum += delta;
// System.err.printf("encipher_block: sum = %d\n", sum);
z += ((y << 4 ^ y >>> 5) + y) ^ (sum + unsigned_int_to_long(k[(int)(sum >>> 11 & 3)]));
// System.err.printf("encipher_block: z = %d\n", z);
}
int_to_bytes(data, 0, (int)y);
int_to_bytes(data, 4, (int)z);
}
protected int get_symmetric_key_bytes() {
return 16;
}
protected void ctr_crypt(byte[] data, int len, final byte[] key) {
System.err.printf("method: org.rivoreo.crypto.ECIES_XTEA::ctr_crypt(int[%d], %d, final byte[%d])\n", data.length, len, key.length);
int[] k = new int[4];
int ctr = 0;
int blen, i, di = 0;
byte[] buf = new byte[8];
init_key(k, key);
while(len > 0) {
int_to_bytes(buf, 0, 0);
int_to_bytes(buf, 4, ctr++);
encipher_block(buf, k);
blen = Math.min(8, len);
for(i = 0; i < blen; i++) {
//*data++ ^= buf[i];
data[di++] ^= buf[i];
}
len -= blen;
}
}
protected void cbc_mac(byte[] mac, final byte[] data, int len, final byte[] key) {
int[] k = new int[4];
int blen, i, di = 0;
init_key(k, key);
int_to_bytes(mac, 0, 0);
int_to_bytes(mac, 4, len);
encipher_block(mac, k);
while(len > 0) {
blen = Math.min(ECIES_CHUNK_OVERHEAD, len);
for(i = 0; i < blen; i++) {
//mac[i] ^= *data++;
mac[i] ^= data[di++];
}
encipher_block(mac, k);
len -= blen;
}
}
protected void davies_meyer(byte[] out, final byte[] in, int ilen) {
System.err.printf("method: org.rivoreo.crypto.ECIES_XTEA::davies_meyer(byte[%d], final byte[%d], %d)\n", out.length, in.length, ilen);
int[] k = new int[4];
byte[] buf = new byte[8];
int i, offset = 0;
//memset(out, 0, 8);
for(i = 0; i < 8; i++) out[i] = 0;
while(ilen-- > 0) {
//System.err.printf("davies_meyer: ilen = %d\n", ilen);
//init_key(k, in, offset);
init_key(k, sub_byte_array(in, offset));
//debug_print_integers(k, 4);
//System.err.println();
//memcpy(buf, out, 8);
for(i = 0; i < 8; i++) buf[i] = out[i];
encipher_block(buf, k);
//debug_print_bytes(buf, 8);
for(i = 0; i < 8; i++) out[i] ^= buf[i];
offset += 16;
}
}
}