| /* |
| * 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; |
| } |
| } |
| } |