org.bouncycastle.math.ec.rfc8032.Scalar448 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.saml.opensaml.integration Show documentation
Show all versions of com.liferay.saml.opensaml.integration Show documentation
Liferay SAML OpenSAML Integration
package org.bouncycastle.math.ec.rfc8032;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.raw.Nat448;
abstract class Scalar448
{
static final int SIZE = 14;
private static final int SCALAR_BYTES = SIZE * 4 + 1;
private static final long M26L = 0x03FFFFFFL;
private static final long M28L = 0x0FFFFFFFL;
private static final long M32L = 0xFFFFFFFFL;
private static final int TARGET_LENGTH = 447;
private static final int[] L = new int[]{ 0xAB5844F3, 0x2378C292, 0x8DC58F55, 0x216CC272, 0xAED63690, 0xC44EDB49,
0x7CCA23E9, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x3FFFFFFF };
private static final int[] LSq = new int[]{ 0x1BA1FEA9, 0xC1ADFBB8, 0x49E0A8B2, 0xB91BF537, 0xE764D815, 0x4525492B,
0xA2B8716D, 0x4AE17CF6, 0xBA3C47C4, 0xF1A9CC14, 0x7E4D070A, 0x92052BCB, 0x9F823B72, 0xC3402A93, 0x55AC2279,
0x91BC6149, 0x46E2C7AA, 0x10B66139, 0xD76B1B48, 0xE2276DA4, 0xBE6511F4, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF };
private static final int L_0 = 0x04A7BB0D; // L_0:26/24
private static final int L_1 = 0x0873D6D5; // L_1:27/23
private static final int L_2 = 0x0A70AADC; // L_2:27/26
private static final int L_3 = 0x03D8D723; // L_3:26/--
private static final int L_4 = 0x096FDE93; // L_4:27/25
private static final int L_5 = 0x0B65129C; // L_5:27/26
private static final int L_6 = 0x063BB124; // L_6:27/--
private static final int L_7 = 0x08335DC1; // L_7:27/22
private static final int L4_0 = 0x029EEC34; // L4_0:25/24
private static final int L4_1 = 0x01CF5B55; // L4_1:25/--
private static final int L4_2 = 0x09C2AB72; // L4_2:27/25
private static final int L4_3 = 0x0F635C8E; // L4_3:28/--
private static final int L4_4 = 0x05BF7A4C; // L4_4:26/25
private static final int L4_5 = 0x0D944A72; // L4_5:28/--
private static final int L4_6 = 0x08EEC492; // L4_6:27/24
private static final int L4_7 = 0x20CD7705; // L4_7:29/24
static boolean checkVar(byte[] s, int[] n)
{
if (s[SCALAR_BYTES - 1] != 0x00)
{
return false;
}
decode(s, n);
return !Nat.gte(SIZE, n, L);
}
static void decode(byte[] k, int[] n)
{
// assert k[SCALAR_BYTES - 1] == 0x00;
Codec.decode32(k, 0, n, 0, SIZE);
}
static void getOrderWnafVar(int width, byte[] ws)
{
Wnaf.getSignedVar(L, width, ws);
}
static void multiply225Var(int[] x, int[] y225, int[] z)
{
// assert y225[7] >> 31 == y225[7];
int[] tt = new int[22];
Nat.mul(y225, 0, 8, x, 0, SIZE, tt, 0);
if (y225[7] < 0)
{
Nat.addTo(SIZE, L, 0, tt, 8);
Nat.subFrom(SIZE, x, 0, tt, 8);
}
byte[] bytes = new byte[114];
Codec.encode32(tt, 0, 22, bytes, 0);
byte[] r = reduce(bytes);
decode(r, z);
}
static byte[] reduce(byte[] n)
{
long x00 = Codec.decode32(n, 0) & M32L; // x00:32/--
long x01 = (Codec.decode24(n, 4) << 4) & M32L; // x01:28/--
long x02 = Codec.decode32(n, 7) & M32L; // x02:32/--
long x03 = (Codec.decode24(n, 11) << 4) & M32L; // x03:28/--
long x04 = Codec.decode32(n, 14) & M32L; // x04:32/--
long x05 = (Codec.decode24(n, 18) << 4) & M32L; // x05:28/--
long x06 = Codec.decode32(n, 21) & M32L; // x06:32/--
long x07 = (Codec.decode24(n, 25) << 4) & M32L; // x07:28/--
long x08 = Codec.decode32(n, 28) & M32L; // x08:32/--
long x09 = (Codec.decode24(n, 32) << 4) & M32L; // x09:28/--
long x10 = Codec.decode32(n, 35) & M32L; // x10:32/--
long x11 = (Codec.decode24(n, 39) << 4) & M32L; // x11:28/--
long x12 = Codec.decode32(n, 42) & M32L; // x12:32/--
long x13 = (Codec.decode24(n, 46) << 4) & M32L; // x13:28/--
long x14 = Codec.decode32(n, 49) & M32L; // x14:32/--
long x15 = (Codec.decode24(n, 53) << 4) & M32L; // x15:28/--
long x16 = Codec.decode32(n, 56) & M32L; // x16:32/--
long x17 = (Codec.decode24(n, 60) << 4) & M32L; // x17:28/--
long x18 = Codec.decode32(n, 63) & M32L; // x18:32/--
long x19 = (Codec.decode24(n, 67) << 4) & M32L; // x19:28/--
long x20 = Codec.decode32(n, 70) & M32L; // x20:32/--
long x21 = (Codec.decode24(n, 74) << 4) & M32L; // x21:28/--
long x22 = Codec.decode32(n, 77) & M32L; // x22:32/--
long x23 = (Codec.decode24(n, 81) << 4) & M32L; // x23:28/--
long x24 = Codec.decode32(n, 84) & M32L; // x24:32/--
long x25 = (Codec.decode24(n, 88) << 4) & M32L; // x25:28/--
long x26 = Codec.decode32(n, 91) & M32L; // x26:32/--
long x27 = (Codec.decode24(n, 95) << 4) & M32L; // x27:28/--
long x28 = Codec.decode32(n, 98) & M32L; // x28:32/--
long x29 = (Codec.decode24(n, 102) << 4) & M32L; // x29:28/--
long x30 = Codec.decode32(n, 105) & M32L; // x30:32/--
long x31 = (Codec.decode24(n, 109) << 4) & M32L; // x31:28/--
long x32 = Codec.decode16(n, 112) & M32L; // x32:16/--
// x32 += (x31 >>> 28); x31 &= M28L;
x16 += x32 * L4_0; // x16:42/--
x17 += x32 * L4_1; // x17:41/28
x18 += x32 * L4_2; // x18:43/42
x19 += x32 * L4_3; // x19:44/28
x20 += x32 * L4_4; // x20:43/--
x21 += x32 * L4_5; // x21:44/28
x22 += x32 * L4_6; // x22:43/41
x23 += x32 * L4_7; // x23:45/41
x31 += (x30 >>> 28); x30 &= M28L; // x31:28/--, x30:28/--
x15 += x31 * L4_0; // x15:54/--
x16 += x31 * L4_1; // x16:53/42
x17 += x31 * L4_2; // x17:55/54
x18 += x31 * L4_3; // x18:56/44
x19 += x31 * L4_4; // x19:55/--
x20 += x31 * L4_5; // x20:56/43
x21 += x31 * L4_6; // x21:55/53
x22 += x31 * L4_7; // x22:57/53
// x30 += (x29 >>> 28); x29 &= M28L;
x14 += x30 * L4_0; // x14:54/--
x15 += x30 * L4_1; // x15:54/53
x16 += x30 * L4_2; // x16:56/--
x17 += x30 * L4_3; // x17:57/--
x18 += x30 * L4_4; // x18:56/55
x19 += x30 * L4_5; // x19:56/55
x20 += x30 * L4_6; // x20:57/--
x21 += x30 * L4_7; // x21:57/56
x29 += (x28 >>> 28); x28 &= M28L; // x29:28/--, x28:28/--
x13 += x29 * L4_0; // x13:54/--
x14 += x29 * L4_1; // x14:54/53
x15 += x29 * L4_2; // x15:56/--
x16 += x29 * L4_3; // x16:57/--
x17 += x29 * L4_4; // x17:57/55
x18 += x29 * L4_5; // x18:57/55
x19 += x29 * L4_6; // x19:57/52
x20 += x29 * L4_7; // x20:58/52
// x28 += (x27 >>> 28); x27 &= M28L;
x12 += x28 * L4_0; // x12:54/--
x13 += x28 * L4_1; // x13:54/53
x14 += x28 * L4_2; // x14:56/--
x15 += x28 * L4_3; // x15:57/--
x16 += x28 * L4_4; // x16:57/55
x17 += x28 * L4_5; // x17:58/--
x18 += x28 * L4_6; // x18:58/--
x19 += x28 * L4_7; // x19:58/53
x27 += (x26 >>> 28); x26 &= M28L; // x27:28/--, x26:28/--
x11 += x27 * L4_0; // x11:54/--
x12 += x27 * L4_1; // x12:54/53
x13 += x27 * L4_2; // x13:56/--
x14 += x27 * L4_3; // x14:57/--
x15 += x27 * L4_4; // x15:57/55
x16 += x27 * L4_5; // x16:58/--
x17 += x27 * L4_6; // x17:58/56
x18 += x27 * L4_7; // x18:59/--
// x26 += (x25 >>> 28); x25 &= M28L;
x10 += x26 * L4_0; // x10:54/--
x11 += x26 * L4_1; // x11:54/53
x12 += x26 * L4_2; // x12:56/--
x13 += x26 * L4_3; // x13:57/--
x14 += x26 * L4_4; // x14:57/55
x15 += x26 * L4_5; // x15:58/--
x16 += x26 * L4_6; // x16:58/56
x17 += x26 * L4_7; // x17:59/--
x25 += (x24 >>> 28); x24 &= M28L; // x25:28/--, x24:28/--
x09 += x25 * L4_0; // x09:54/--
x10 += x25 * L4_1; // x10:54/53
x11 += x25 * L4_2; // x11:56/--
x12 += x25 * L4_3; // x12:57/--
x13 += x25 * L4_4; // x13:57/55
x14 += x25 * L4_5; // x14:58/--
x15 += x25 * L4_6; // x15:58/56
x16 += x25 * L4_7; // x16:59/--
x21 += (x20 >>> 28); x20 &= M28L; // x21:58/--, x20:28/--
x22 += (x21 >>> 28); x21 &= M28L; // x22:57/54, x21:28/--
x23 += (x22 >>> 28); x22 &= M28L; // x23:45/42, x22:28/--
x24 += (x23 >>> 28); x23 &= M28L; // x24:28/18, x23:28/--
x08 += x24 * L4_0; // x08:54/--
x09 += x24 * L4_1; // x09:55/--
x10 += x24 * L4_2; // x10:56/46
x11 += x24 * L4_3; // x11:57/46
x12 += x24 * L4_4; // x12:57/55
x13 += x24 * L4_5; // x13:58/--
x14 += x24 * L4_6; // x14:58/56
x15 += x24 * L4_7; // x15:59/--
x07 += x23 * L4_0; // x07:54/--
x08 += x23 * L4_1; // x08:54/53
x09 += x23 * L4_2; // x09:56/53
x10 += x23 * L4_3; // x10:57/46
x11 += x23 * L4_4; // x11:57/55
x12 += x23 * L4_5; // x12:58/--
x13 += x23 * L4_6; // x13:58/56
x14 += x23 * L4_7; // x14:59/--
x06 += x22 * L4_0; // x06:54/--
x07 += x22 * L4_1; // x07:54/53
x08 += x22 * L4_2; // x08:56/--
x09 += x22 * L4_3; // x09:57/53
x10 += x22 * L4_4; // x10:57/55
x11 += x22 * L4_5; // x11:58/--
x12 += x22 * L4_6; // x12:58/56
x13 += x22 * L4_7; // x13:59/--
x18 += (x17 >>> 28); x17 &= M28L; // x18:59/31, x17:28/--
x19 += (x18 >>> 28); x18 &= M28L; // x19:58/54, x18:28/--
x20 += (x19 >>> 28); x19 &= M28L; // x20:30/29, x19:28/--
x21 += (x20 >>> 28); x20 &= M28L; // x21:28/03, x20:28/--
x05 += x21 * L4_0; // x05:54/--
x06 += x21 * L4_1; // x06:55/--
x07 += x21 * L4_2; // x07:56/31
x08 += x21 * L4_3; // x08:57/31
x09 += x21 * L4_4; // x09:57/56
x10 += x21 * L4_5; // x10:58/--
x11 += x21 * L4_6; // x11:58/56
x12 += x21 * L4_7; // x12:59/--
x04 += x20 * L4_0; // x04:54/--
x05 += x20 * L4_1; // x05:54/53
x06 += x20 * L4_2; // x06:56/53
x07 += x20 * L4_3; // x07:57/31
x08 += x20 * L4_4; // x08:57/55
x09 += x20 * L4_5; // x09:58/--
x10 += x20 * L4_6; // x10:58/56
x11 += x20 * L4_7; // x11:59/--
x03 += x19 * L4_0; // x03:54/--
x04 += x19 * L4_1; // x04:54/53
x05 += x19 * L4_2; // x05:56/--
x06 += x19 * L4_3; // x06:57/53
x07 += x19 * L4_4; // x07:57/55
x08 += x19 * L4_5; // x08:58/--
x09 += x19 * L4_6; // x09:58/56
x10 += x19 * L4_7; // x10:59/--
x15 += (x14 >>> 28); x14 &= M28L; // x15:59/31, x14:28/--
x16 += (x15 >>> 28); x15 &= M28L; // x16:59/32, x15:28/--
x17 += (x16 >>> 28); x16 &= M28L; // x17:31/29, x16:28/--
x18 += (x17 >>> 28); x17 &= M28L; // x18:28/04, x17:28/--
x02 += x18 * L4_0; // x02:54/--
x03 += x18 * L4_1; // x03:55/--
x04 += x18 * L4_2; // x04:56/32
x05 += x18 * L4_3; // x05:57/32
x06 += x18 * L4_4; // x06:57/56
x07 += x18 * L4_5; // x07:58/--
x08 += x18 * L4_6; // x08:58/56
x09 += x18 * L4_7; // x09:59/--
x01 += x17 * L4_0; // x01:54/--
x02 += x17 * L4_1; // x02:54/53
x03 += x17 * L4_2; // x03:56/53
x04 += x17 * L4_3; // x04:57/32
x05 += x17 * L4_4; // x05:57/55
x06 += x17 * L4_5; // x06:58/--
x07 += x17 * L4_6; // x07:58/56
x08 += x17 * L4_7; // x08:59/--
x16 *= 4;
x16 += (x15 >>> 26); x15 &= M26L;
x16 += 1; // x16:30/01
x00 += x16 * L_0;
x01 += x16 * L_1;
x02 += x16 * L_2;
x03 += x16 * L_3;
x04 += x16 * L_4;
x05 += x16 * L_5;
x06 += x16 * L_6;
x07 += x16 * L_7;
x01 += (x00 >>> 28); x00 &= M28L;
x02 += (x01 >>> 28); x01 &= M28L;
x03 += (x02 >>> 28); x02 &= M28L;
x04 += (x03 >>> 28); x03 &= M28L;
x05 += (x04 >>> 28); x04 &= M28L;
x06 += (x05 >>> 28); x05 &= M28L;
x07 += (x06 >>> 28); x06 &= M28L;
x08 += (x07 >>> 28); x07 &= M28L;
x09 += (x08 >>> 28); x08 &= M28L;
x10 += (x09 >>> 28); x09 &= M28L;
x11 += (x10 >>> 28); x10 &= M28L;
x12 += (x11 >>> 28); x11 &= M28L;
x13 += (x12 >>> 28); x12 &= M28L;
x14 += (x13 >>> 28); x13 &= M28L;
x15 += (x14 >>> 28); x14 &= M28L;
x16 = (x15 >>> 26); x15 &= M26L;
x16 -= 1;
// assert x16 == 0L || x16 == -1L;
x00 -= x16 & L_0;
x01 -= x16 & L_1;
x02 -= x16 & L_2;
x03 -= x16 & L_3;
x04 -= x16 & L_4;
x05 -= x16 & L_5;
x06 -= x16 & L_6;
x07 -= x16 & L_7;
x01 += (x00 >> 28); x00 &= M28L;
x02 += (x01 >> 28); x01 &= M28L;
x03 += (x02 >> 28); x02 &= M28L;
x04 += (x03 >> 28); x03 &= M28L;
x05 += (x04 >> 28); x04 &= M28L;
x06 += (x05 >> 28); x05 &= M28L;
x07 += (x06 >> 28); x06 &= M28L;
x08 += (x07 >> 28); x07 &= M28L;
x09 += (x08 >> 28); x08 &= M28L;
x10 += (x09 >> 28); x09 &= M28L;
x11 += (x10 >> 28); x10 &= M28L;
x12 += (x11 >> 28); x11 &= M28L;
x13 += (x12 >> 28); x12 &= M28L;
x14 += (x13 >> 28); x13 &= M28L;
x15 += (x14 >> 28); x14 &= M28L;
// assert x15 >>> 26 == 0L;
byte[] r = new byte[SCALAR_BYTES];
Codec.encode56(x00 | (x01 << 28), r, 0);
Codec.encode56(x02 | (x03 << 28), r, 7);
Codec.encode56(x04 | (x05 << 28), r, 14);
Codec.encode56(x06 | (x07 << 28), r, 21);
Codec.encode56(x08 | (x09 << 28), r, 28);
Codec.encode56(x10 | (x11 << 28), r, 35);
Codec.encode56(x12 | (x13 << 28), r, 42);
Codec.encode56(x14 | (x15 << 28), r, 49);
// r[SCALAR_BYTES - 1] = 0;
return r;
}
static void reduceBasisVar(int[] k, int[] z0, int[] z1)
{
/*
* Split scalar k into two half-size scalars z0 and z1, such that z1 * k == z0 mod L.
*
* See https://ia.cr/2020/454 (Pornin).
*/
int[] Nu = new int[28]; System.arraycopy(LSq, 0, Nu, 0, 28);
int[] Nv = new int[28]; Nat448.square(k, Nv); ++Nv[0];
int[] p = new int[28]; Nat448.mul(L, k, p);
int[] u0 = new int[8]; System.arraycopy(L, 0, u0, 0, 8);
int[] u1 = new int[8];
int[] v0 = new int[8]; System.arraycopy(k, 0, v0, 0, 8);
int[] v1 = new int[8]; v1[0] = 1;
int last = 27;
int len_Nv = ScalarUtil.getBitLengthPositive(last, Nv);
while (len_Nv > TARGET_LENGTH)
{
int len_p = ScalarUtil.getBitLength(last, p);
int s = len_p - len_Nv;
s &= ~(s >> 31);
if (p[last] < 0)
{
ScalarUtil.addShifted_NP(last, s, Nu, Nv, p);
ScalarUtil.addShifted_UV(7, s, u0, u1, v0, v1);
}
else
{
ScalarUtil.subShifted_NP(last, s, Nu, Nv, p);
ScalarUtil.subShifted_UV(7, s, u0, u1, v0, v1);
}
if (ScalarUtil.lessThan(last, Nu, Nv))
{
int[] t0 = u0; u0 = v0; v0 = t0;
int[] t1 = u1; u1 = v1; v1 = t1;
int[] tN = Nu; Nu = Nv; Nv = tN;
last = len_Nv >>> 5;
len_Nv = ScalarUtil.getBitLengthPositive(last, Nv);
}
}
// assert v0[7] >> 31 == v0[7];
// assert v1[7] >> 31 == v1[7];
// v1 * k == v0 mod L
System.arraycopy(v0, 0, z0, 0, 8);
System.arraycopy(v1, 0, z1, 0, 8);
}
static void toSignedDigits(int bits, int[] x, int[] z)
{
// assert 448 < bits && bits < 480;
// assert z.length > SIZE;
z[SIZE] = (1 << (bits - 448))
+ Nat.cadd(SIZE, ~x[0] & 1, x, L, z);
// int c =
Nat.shiftDownBit(SIZE + 1, z, 0);
// assert c == (1 << 31);
}
}