package org.bouncycastle.crypto.modes.kgcm;

import org.bouncycastle.math.raw.Interleave;

Utilities for the GF(2^m) field with corresponding extension polynomial: GF (2^128) -> x^128 + x^7 + x^2 + x + 1 The representation is little-endian arrays of 64-bit words
/** * Utilities for the GF(2^m) field with corresponding extension polynomial: * * GF (2^128) -> x^128 + x^7 + x^2 + x + 1 * * The representation is little-endian arrays of 64-bit words */
public class KGCMUtil_128 { public static final int SIZE = 2; public static void add(long[] x, long[] y, long[] z) { z[0] = x[0] ^ y[0]; z[1] = x[1] ^ y[1]; } public static void copy(long[] x, long[] z) { z[0] = x[0]; z[1] = x[1]; } public static boolean equal(long[] x, long[] y) { long d = 0L; d |= x[0] ^ y[0]; d |= x[1] ^ y[1]; return d == 0L; } public static void multiply(long[] x, long[] y, long[] z) { long x0 = x[0], x1 = x[1]; long y0 = y[0], y1 = y[1]; long z0 = 0, z1 = 0, z2 = 0; for (int j = 0; j < 64; ++j) { long m0 = -(x0 & 1L); x0 >>>= 1; z0 ^= (y0 & m0); z1 ^= (y1 & m0); long m1 = -(x1 & 1L); x1 >>>= 1; z1 ^= (y0 & m1); z2 ^= (y1 & m1); long c = y1 >> 63; y1 = (y1 << 1) | (y0 >>> 63); y0 = (y0 << 1) ^ (c & 0x87L); } z0 ^= z2 ^ (z2 << 1) ^ (z2 << 2) ^ (z2 << 7); z1 ^= (z2 >>> 63) ^ (z2 >>> 62) ^ (z2 >>> 57); z[0] = z0; z[1] = z1; } public static void multiplyX(long[] x, long[] z) { long x0 = x[0], x1 = x[1]; long m = x1 >> 63; z[0] = (x0 << 1) ^ (m & 0x87L); z[1] = (x1 << 1) | (x0 >>> 63); } public static void multiplyX8(long[] x, long[] z) { long x0 = x[0], x1 = x[1]; long c = x1 >>> 56; z[0] = (x0 << 8) ^ c ^ (c << 1) ^ (c << 2) ^ (c << 7); z[1] = (x1 << 8) | (x0 >>> 56); } public static void one(long[] z) { z[0] = 1; z[1] = 0; } public static void square(long[] x, long[] z) { long[] t = new long[4]; Interleave.expand64To128(x[0], t, 0); Interleave.expand64To128(x[1], t, 2); long z0 = t[0], z1 = t[1], z2 = t[2], z3 = t[3]; z1 ^= z3 ^ (z3 << 1) ^ (z3 << 2) ^ (z3 << 7); z2 ^= (z3 >>> 63) ^ (z3 >>> 62) ^ (z3 >>> 57); z0 ^= z2 ^ (z2 << 1) ^ (z2 << 2) ^ (z2 << 7); z1 ^= (z2 >>> 63) ^ (z2 >>> 62) ^ (z2 >>> 57); z[0] = z0; z[1] = z1; } public static void x(long[] z) { z[0] = 2; z[1] = 0; } public static void zero(long[] z) { z[0] = 0; z[1] = 0; } }