Skip to content

Commit 50c84da

Browse files
gefeilidghgit
authored andcommitted
TODO: SAKKEKEMSGenerator and parameter settings
1 parent cc77eaf commit 50c84da

File tree

3 files changed

+75
-568
lines changed

3 files changed

+75
-568
lines changed
Lines changed: 45 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package org.bouncycastle.crypto.kems;
22

33
import java.math.BigInteger;
4-
import java.security.SecureRandom;
54

6-
import org.bouncycastle.crypto.Digest;
75
import org.bouncycastle.crypto.EncapsulatedSecretExtractor;
8-
import org.bouncycastle.crypto.digests.SHA256Digest;
96
import org.bouncycastle.crypto.params.SAKKEPrivateKeyParameters;
107
import org.bouncycastle.crypto.params.SAKKEPublicKeyParameters;
118
import org.bouncycastle.math.ec.ECCurve;
@@ -15,7 +12,6 @@
1512
import org.bouncycastle.util.BigIntegers;
1613
import org.bouncycastle.util.encoders.Hex;
1714

18-
import static org.bouncycastle.crypto.kems.SAKKEKEMSGenerator.pairing;
1915

2016
public class SAKKEKEMExtractor
2117
implements EncapsulatedSecretExtractor
@@ -51,31 +47,26 @@ public byte[] extractSecret(byte[] encapsulation)
5147
ECPoint R_bS = curve.decodePoint(Arrays.copyOfRange(encapsulation, 0, 257));
5248
BigInteger H = new BigInteger(Arrays.copyOfRange(encapsulation, 257, 274));
5349

54-
//ECCurveWithTatePairing pairing = new ECCurveWithTatePairing(q, BigInteger.ONE, BigInteger.ZERO, p);
55-
//BigInteger w = pairing.TatePairing(R_bS, K_bS).toBigInteger();
5650
// Step 2: Compute w = <R_bS, K_bS> using pairing
57-
// BigInteger w = computeTLPairing(new BigInteger[] {R_bS.getXCoord().toBigInteger(), R_bS.getYCoord().toBigInteger()},
58-
// new BigInteger[] {K_bS.getXCoord().toBigInteger(), K_bS.getYCoord().toBigInteger()}, this.p, this.q);
5951
BigInteger w = computePairing(R_bS, K_bS, p, q);
6052
System.out.println(new String(Hex.encode(w.toByteArray())));
6153
//BigInteger w = tatePairing(R_bS.getXCoord().toBigInteger(), R_bS.getYCoord().toBigInteger(), K_bS.getXCoord().toBigInteger(), K_bS.getYCoord().toBigInteger(), q, p);
6254
// Step 3: Compute SSV = H XOR HashToIntegerRange(w, 2^n)
63-
BigInteger ssv = computeSSV(H, w);
55+
BigInteger twoToN = BigInteger.ONE.shiftLeft(n);
56+
BigInteger mask = SAKKEUtils.hashToIntegerRange(w.toByteArray(), twoToN);
57+
BigInteger ssv = H.xor(mask);
6458

6559
// Step 4: Compute r = HashToIntegerRange(SSV || b)
6660
BigInteger b = privateKey.getB();
6761
BigInteger r = SAKKEUtils.hashToIntegerRange(Arrays.concatenate(ssv.toByteArray(), b.toByteArray()), q);
68-
//
69-
// // Step 5: Validate R_bS
62+
63+
// Step 5: Validate R_bS
7064
ECPoint bP = P.multiply(b).normalize();
7165
ECPoint Test = bP.add(Z_S).multiply(r).normalize();
72-
if(!R_bS.equals(Test))
66+
if (!R_bS.equals(Test))
7367
{
7468
throw new IllegalStateException("Validation of R_bS failed");
7569
}
76-
// if (!validateR_bS(r, privateKey.getPrivatePoint(), R_bS)) {
77-
// throw new IllegalStateException("Validation of R_bS failed");
78-
// }
7970

8071
return BigIntegers.asUnsignedByteArray(n / 8, ssv);
8172
}
@@ -92,109 +83,75 @@ public int getEncapsulationLength()
9283
}
9384

9485

95-
private BigInteger computeSSV(BigInteger H, BigInteger w)
96-
{
97-
BigInteger twoToN = BigInteger.ONE.shiftLeft(n);
98-
BigInteger mask = SAKKEUtils.hashToIntegerRange(w.toByteArray(), twoToN);
99-
return H.xor(mask);
100-
}
101-
10286
public static BigInteger computePairing(ECPoint R, ECPoint Q, BigInteger p, BigInteger q)
10387
{
104-
BigInteger c = p.add(BigInteger.ONE).divide(q); // Compute c = (p+1)/q
105-
BigInteger[] v = new BigInteger[]{BigInteger.ONE, BigInteger.ZERO}; // v = (1,0) in F_p^2
106-
//BigInteger v = BigInteger.ONE;
88+
// v = (1,0) in F_p^2
89+
BigInteger[] v = new BigInteger[]{BigInteger.ONE, BigInteger.ZERO};
10790
ECPoint C = R;
10891

10992
BigInteger qMinusOne = q.subtract(BigInteger.ONE);
11093
int numBits = qMinusOne.bitLength();
94+
BigInteger Qx = Q.getAffineXCoord().toBigInteger();
95+
BigInteger Qy = Q.getAffineYCoord().toBigInteger();
96+
BigInteger Rx = R.getAffineXCoord().toBigInteger();
97+
BigInteger Ry = R.getAffineYCoord().toBigInteger();
98+
BigInteger l, Cx, Cy;
99+
final BigInteger three = BigInteger.valueOf(3);
100+
final BigInteger two = BigInteger.valueOf(2);
111101

112102
// Miller loop
113103
for (int i = numBits - 2; i >= 0; i--)
114104
{
115-
v = fp2SquareAndAccumulate(v, C, Q, p);
105+
Cx = C.getAffineXCoord().toBigInteger();
106+
Cy = C.getAffineYCoord().toBigInteger();
107+
108+
// Compute l = (3 * (Cx^2 - 1)) / (2 * Cy) mod p
109+
l = three.multiply(Cx.multiply(Cx).subtract(BigInteger.ONE))
110+
.multiply(Cy.multiply(two).modInverse(p)).mod(p);
111+
112+
// Compute v = v^2 * ( l*( Q_x + C_x ) + ( i*Q_y - C_y ) )
113+
v = fp2PointSquare(v[0], v[1], p);
114+
v = fp2Multiply(v[0], v[1], l.multiply(Qx.add(Cx)).subtract(Cy), Qy, p);
116115

117116
C = C.twice().normalize(); // C = [2]C
118117

119118
if (qMinusOne.testBit(i))
120119
{
121-
v = fp2MultiplyAndAccumulate(v, C, R, Q, p);
120+
Cx = C.getAffineXCoord().toBigInteger();
121+
Cy = C.getAffineYCoord().toBigInteger();
122+
123+
// Compute l = (Cy - Ry) / (Cx - Rx) mod p
124+
l = Cy.subtract(Ry).multiply(Cx.subtract(Rx).modInverse(p)).mod(p);
125+
126+
// Compute v = v * ( l*( Q_x + C_x ) + ( i*Q_y - C_y ) )
127+
v = fp2Multiply(v[0], v[1], l.multiply(Qx.add(Cx)).subtract(Cy), Qy, p);
128+
122129
C = C.add(R).normalize();
123130
}
124131
}
125132

126133
// Final exponentiation: t = v^c
127-
return fp2FinalExponentiation(v, p, c);
128-
}
129-
130-
private static BigInteger[] fp2SquareAndAccumulate(BigInteger[] v, ECPoint C, ECPoint Q, BigInteger p)
131-
{
132-
BigInteger Cx = C.getAffineXCoord().toBigInteger();
133-
BigInteger Cy = C.getAffineYCoord().toBigInteger();
134-
BigInteger Qx = Q.getAffineXCoord().toBigInteger();
135-
BigInteger Qy = Q.getAffineYCoord().toBigInteger();
136-
137-
// Compute l = (3 * (Cx^2 - 1)) / (2 * Cy) mod p
138-
BigInteger l = BigInteger.valueOf(3).multiply(Cx.multiply(Cx).subtract(BigInteger.ONE))
139-
.multiply(Cy.multiply(BigInteger.valueOf(2)).modInverse(p)).mod(p);
140-
141-
// Compute v = v^2 * ( l*( Q_x + C_x ) + ( i*Q_y - C_y ) )
142-
v = fp2Multiply(v[0], v[1], v[0], v[1], p);
143-
// v[0] = v[0].multiply(v[0]);
144-
// v[1] = v[1].multiply(v[1]);
145-
return accumulateLine(v[0], v[1], Cx, Cy, Qx, Qy, l, p);
146-
// BigInteger t_x1_bn = Cx.multiply(Cx).subtract(BigInteger.ONE).multiply(BigInteger.valueOf(3)).multiply(Qx.add(Cx)).mod(p)
147-
// .subtract(Cy.multiply(Cy).multiply(BigInteger.valueOf(2))).mod(p);
148-
// BigInteger t_x2_bn = Cy.multiply(Qy).multiply(BigInteger.valueOf(2)).mod(p);
149-
// v = fp2Multiply(v[0], v[1], v[0], v[1], p);
150-
// return fp2Multiply(v[0], v[1], t_x1_bn, t_x2_bn, p);
151-
}
152-
153-
private static BigInteger[] accumulateLine(BigInteger v0, BigInteger v1, BigInteger Cx, BigInteger Cy, BigInteger Qx, BigInteger Qy, BigInteger l, BigInteger p)
154-
{
155-
return fp2Multiply(v0, v1, l.multiply(Qx.add(Cx)).subtract(Cy), Qy, p);
156-
}
157-
158-
private static BigInteger[] fp2MultiplyAndAccumulate(BigInteger[] v, ECPoint C, ECPoint R, ECPoint Q, BigInteger p)
159-
{
160-
BigInteger Cx = C.getAffineXCoord().toBigInteger();
161-
BigInteger Cy = C.getAffineYCoord().toBigInteger();
162-
BigInteger Rx = R.getAffineXCoord().toBigInteger();
163-
BigInteger Ry = R.getAffineYCoord().toBigInteger();
164-
BigInteger Qx = Q.getAffineXCoord().toBigInteger();
165-
BigInteger Qy = Q.getAffineYCoord().toBigInteger();
166-
167-
// Compute l = (Cy - Ry) / (Cx - Rx) mod p
168-
BigInteger l = Cy.subtract(Ry)
169-
.multiply(Cx.subtract(Rx).modInverse(p))
170-
.mod(p);
171-
172-
// Compute v = v * ( l*( Q_x + C_x ) + ( i*Q_y - C_y ) )
173-
return accumulateLine(v[0], v[1], Cx, Cy, Qx, Qy, l, p);
174-
// BigInteger t_x1_bn = Qx.add(Rx).multiply(Cy).subtract(Qx.add(Cx).multiply(Ry)).mod(p);
175-
// BigInteger t_x2_bn = Cx.subtract(Rx).multiply(Qy).mod(p);
176-
// return fp2Multiply(v[0], v[1], t_x1_bn, t_x2_bn, p);
177-
134+
v = fp2PointSquare(v[0], v[1], p);
135+
v = fp2PointSquare(v[0], v[1], p);
136+
return v[1].multiply(v[0].modInverse(p)).mod(p);
178137
}
179138

180-
181139
static BigInteger[] fp2Multiply(BigInteger x_real, BigInteger x_imag, BigInteger y_real, BigInteger y_imag, BigInteger p)
182140
{
183-
// Multiply v = (a + i*b) * scalar
184141
return new BigInteger[]{
185142
x_real.multiply(y_real).subtract(x_imag.multiply(y_imag)).mod(p),
186143
x_real.multiply(y_imag).add(x_imag.multiply(y_real)).mod(p)
187144
};
188145
}
189146

190-
private static BigInteger fp2FinalExponentiation(BigInteger[] v, BigInteger p, BigInteger c)
147+
static BigInteger[] fp2PointSquare(BigInteger currentX, BigInteger currentY, BigInteger p)
191148
{
192-
// Compute representative in F_p: return b/a (mod p)
193-
// BigInteger v0 = v[0].modPow(c, p);
194-
// BigInteger v1 = v[1].modPow(c, p);
195-
// return v1.multiply(v0.modInverse(p)).mod(p);
196-
v = fp2Multiply(v[0], v[1], v[0], v[1], p);
197-
v = fp2Multiply(v[0], v[1], v[0], v[1], p);
198-
return v[1].multiply(v[0].modInverse(p)).mod(p);
149+
BigInteger xPlusY = currentX.add(currentY).mod(p);
150+
BigInteger xMinusY = currentX.subtract(currentY).mod(p);
151+
BigInteger newX = xPlusY.multiply(xMinusY).mod(p);
152+
153+
// Compute newY = 2xy mod p
154+
BigInteger newY = currentX.multiply(currentY).multiply(BigInteger.valueOf(2)).mod(p);
155+
return new BigInteger[]{newX, newY};
199156
}
200157
}

0 commit comments

Comments
 (0)