Skip to content

Commit b69dd73

Browse files
gefeilidghgit
authored andcommitted
hashToIntegerRange is correct. TODO: fix the curve definition and pairing function
1 parent f4a2618 commit b69dd73

File tree

4 files changed

+228
-32
lines changed

4 files changed

+228
-32
lines changed

core/src/main/java/org/bouncycastle/crypto/kems/SAKKEKEMSGenerator.java

Lines changed: 126 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
import org.bouncycastle.math.ec.ECCurve;
88
import org.bouncycastle.math.ec.ECFieldElement;
99
import org.bouncycastle.math.ec.ECPoint;
10+
import org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
1011
import org.bouncycastle.util.Arrays;
1112
import org.bouncycastle.util.BigIntegers;
13+
import org.bouncycastle.util.encoders.Hex;
1214

1315
import java.math.BigInteger;
1416
import java.nio.ByteBuffer;
@@ -17,41 +19,150 @@
1719
public class SAKKEKEMSGenerator
1820
implements EncapsulatedSecretGenerator
1921
{
20-
private final SAKKEPublicKey publicParams;
22+
23+
// private static final BigInteger p = new BigInteger(Hex.decode("997ABB1F 0A563FDA 65C61198 DAD0657A\n" +
24+
// " 416C0CE1 9CB48261 BE9AE358 B3E01A2E\n" +
25+
// " F40AAB27 E2FC0F1B 228730D5 31A59CB0\n" +
26+
// " E791B39F F7C88A19 356D27F4 A666A6D0\n" +
27+
// " E26C6487 326B4CD4 512AC5CD 65681CE1\n" +
28+
// " B6AFF4A8 31852A82 A7CF3C52 1C3C09AA\n" +
29+
// " 9F94D6AF 56971F1F FCE3E823 89857DB0\n" +
30+
// " 80C5DF10 AC7ACE87 666D807A FEA85FEB"));
31+
private static final BigInteger p = new BigInteger(
32+
"997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2E" +
33+
"F40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0" +
34+
"E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA" +
35+
"9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB", 16
36+
);
37+
// private static final BigInteger q = new BigInteger(Hex.decode("265EAEC7 C2958FF6 99718466 36B4195E\n" +
38+
// " 905B0338 672D2098 6FA6B8D6 2CF8068B\n" +
39+
// " BD02AAC9 F8BF03C6 C8A1CC35 4C69672C\n" +
40+
// " 39E46CE7 FDF22286 4D5B49FD 2999A9B4\n" +
41+
// " 389B1921 CC9AD335 144AB173 595A0738\n" +
42+
// " 6DABFD2A 0C614AA0 A9F3CF14 870F026A\n" +
43+
// " A7E535AB D5A5C7C7 FF38FA08 E2615F6C\n" +
44+
// " 203177C4 2B1EB3A1 D99B601E BFAA17FB"));
45+
private static final BigInteger q = new BigInteger(
46+
"265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068B" +
47+
"BD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4" +
48+
"389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026A" +
49+
"A7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB", 16
50+
);
51+
// private static final BigInteger a = BigInteger.valueOf(-3).mod(p); // y² = x³ - 3x
52+
// private static final BigInteger b = BigInteger.ZERO;
53+
// private static final ECCurve.Fp curve = new ECCurve.Fp(
54+
// p, // Prime p
55+
// BigInteger.valueOf(-3).mod(p), // a = -3
56+
// BigInteger.ZERO, // b = 0
57+
// q, // Order of the subgroup (from RFC 6509)
58+
// BigInteger.ONE // Cofactor = 1
59+
// );
60+
61+
// Base point P = (Px, Py)
62+
private static final BigInteger Px = new BigInteger(
63+
"53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBF" +
64+
"B5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE890" +
65+
"9760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910D" +
66+
"D5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895", 16
67+
);
68+
69+
private static final BigInteger Py = new BigInteger(
70+
"0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178" +
71+
"F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B9" +
72+
"70DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F2" +
73+
"13515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7", 16
74+
);
75+
76+
77+
BigInteger g = new BigInteger(Hex.decode("66FC2A43 2B6EA392 148F1586 7D623068\n" +
78+
" C6A87BD1 FB94C41E 27FABE65 8E015A87\n" +
79+
" 371E9474 4C96FEDA 449AE956 3F8BC446\n" +
80+
" CBFDA85D 5D00EF57 7072DA8F 541721BE\n" +
81+
" EE0FAED1 828EAB90 B99DFB01 38C78433\n" +
82+
" 55DF0460 B4A9FD74 B4F1A32B CAFA1FFA\n" +
83+
" D682C033 A7942BCC E3720F20 B9B7B040\n" +
84+
" 3C8CAE87 B7A0042A CDE0FAB3 6461EA46"));
85+
private final int n = 128;
2186
private final SecureRandom random;
2287

23-
public SAKKEKEMSGenerator(SAKKEPublicKey params, SecureRandom random)
88+
public SAKKEKEMSGenerator(SecureRandom random)
2489
{
25-
this.publicParams = params;
2690
this.random = random;
2791
}
2892

2993
@Override
3094
public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey)
3195
{
3296
// 1. Generate random SSV in range [0, 2^n - 1]
33-
BigInteger ssv = new BigInteger(publicParams.getN(), random);
97+
BigInteger ssv = new BigInteger("123456789ABCDEF0123456789ABCDEF0", 16);//new BigInteger(n, random);
3498

3599
// 2. Compute r = HashToIntegerRange(SSV || b, q)
36-
BigInteger b = getRecipientId((SAKKEPublicKey)recipientKey);
37-
BigInteger r = SAKKEUtils.hashToIntegerRange(Arrays.concatenate(ssv.toByteArray(), b.toByteArray()), publicParams.getQ());
38-
100+
BigInteger b = new BigInteger("323031312D30320074656C3A2B34343737303039303031323300", 16); //getRecipientId((SAKKEPublicKey)recipientKey);
101+
BigInteger r = SAKKEUtils.hashToIntegerRange(Arrays.concatenate(ssv.toByteArray(), b.toByteArray()), q);
102+
System.out.println(new String(Hex.encode(r.toByteArray())));
103+
ECCurve.Fp curve = new ECCurve.Fp(
104+
p, // Prime p
105+
BigInteger.valueOf(-3).mod(p), // a = -3
106+
BigInteger.ZERO, // ,
107+
g, // Order of the subgroup (from RFC 6509)
108+
BigInteger.ONE // Cofactor = 1
109+
);
110+
ECPoint P = curve.createPoint(Px, Py);
111+
ECPoint G = curve.createPoint(
112+
new BigInteger(Hex.decode("53FC09EE 332C29AD 0A799005 3ED9B52A\n" +
113+
" 2B1A2FD6 0AEC69C6 98B2F204 B6FF7CBF\n" +
114+
" B5EDB6C0 F6CE2308 AB10DB90 30B09E10\n" +
115+
" 43D5F22C DB9DFA55 718BD9E7 406CE890\n" +
116+
" 9760AF76 5DD5BCCB 337C8654 8B72F2E1\n" +
117+
" A702C339 7A60DE74 A7C1514D BA66910D\n" +
118+
" D5CFB4CC 80728D87 EE9163A5 B63F73EC\n" +
119+
" 80EC46C4 967E0979 880DC8AB EAE63895")), // Px
120+
new BigInteger(Hex.decode("0A824906 3F6009F1 F9F1F053 3634A135\n" +
121+
" D3E82016 02990696 3D778D82 1E141178\n" +
122+
" F5EA69F4 654EC2B9 E7F7F5E5 F0DE55F6\n" +
123+
" 6B598CCF 9A140B2E 416CFF0C A9E032B9\n" +
124+
" 70DAE117 AD547C6C CAD696B5 B7652FE0\n" +
125+
" AC6F1E80 164AA989 492D979F C5A4D5F2\n" +
126+
" 13515AD7 E9CB99A9 80BDAD5A D5BB4636\n" +
127+
" ADB9B570 6A67DCDE 75573FD7 1BEF16D7")) // Py
128+
);
129+
ECPoint Z = curve.createPoint(
130+
new BigInteger("5958EF1B1679BF099B3A030DF255AA6A" +
131+
"23C1D8F143D4D23F753E69BD27A832F3" +
132+
"8CB4AD53DDEF4260B0FE8BB45C4C1FF5" +
133+
"10EFFE300367A37B61F701D914AEF097" +
134+
"24825FA0707D61A6DFF4FBD7273566CD" +
135+
"DE352A0B04B7C16A78309BE640697DE7" +
136+
"47613A5FC195E8B9F328852A579DB8F9" +
137+
"9B1D0034479EA9C5595F47C4B2F54FF2", 16), // Px
138+
new BigInteger("1508D37514DCF7A8E143A6058C09A6BF" +
139+
"2C9858CA37C258065AE6BF7532BC8B5B" +
140+
"63383866E0753C5AC0E72709F8445F2E" +
141+
"6178E065857E0EDA10F68206B63505ED" +
142+
"87E534FB2831FF957FB7DC619DAE6130" +
143+
"1EEACC2FDA3680EA4999258A833CEA8F" +
144+
"C67C6D19487FB449059F26CC8AAB655A" +
145+
"B58B7CC796E24E9A394095754F5F8BAE", 16) // Py
146+
);
39147
// 3. Compute R_(b,S) = [r]([b]P + Z_S)
40-
ECPoint bP = publicParams.getP().multiply(b); // [b]P
41-
ECPoint Z_S = publicParams.getZ(); // Z_S
148+
ECPoint bP = P.multiply(b).normalize();
149+
ECPoint Z_S = Z;// P.multiply(ssv).normalize();;//.multiply(new BigInteger("AFF429D35F84B110D094803B3595A6E2998BC99F", 16)); // Z_S
42150
ECPoint R_bS = bP.add(Z_S).multiply(r); // [r]([b]P + Z_S)
151+
System.out.println("R_Bs x:" + new String(Hex.encode(R_bS.getXCoord().toBigInteger().toByteArray())));
152+
System.out.println("R_Bs y:" + new String(Hex.encode(R_bS.getYCoord().toBigInteger().toByteArray())));
153+
43154

44155
// 4. Compute H = SSV XOR HashToIntegerRange( g^r, 2^n )
45-
BigInteger g_r = pairing(R_bS, publicParams.getP(), publicParams.getQ(), publicParams.getP().getCurve().getField().getCharacteristic());
46-
BigInteger mask = SAKKEUtils.hashToIntegerRange(g_r.toByteArray(), BigInteger.ONE.shiftLeft(publicParams.getN())); // 2^n
156+
BigInteger g_r = pairing(R_bS, G, p, q);
157+
BigInteger mask = SAKKEUtils.hashToIntegerRange(g_r.toByteArray(), BigInteger.ONE.shiftLeft(n)); // 2^n
47158

48159
BigInteger H = ssv.xor(mask);
49160

50161
// 5. Encode encapsulated data (R_bS, H)
51162
byte[] encapsulated = encodeData(R_bS, H);
52163

53164
return new SecretWithEncapsulationImpl(
54-
BigIntegers.asUnsignedByteArray(publicParams.getN() / 8, ssv), // Output SSV as key material
165+
BigIntegers.asUnsignedByteArray(n / 8, ssv), // Output SSV as key material
55166
encapsulated
56167
);
57168
}
@@ -123,7 +234,7 @@ public static BigInteger pairing(ECPoint R, ECPoint Q, BigInteger p, BigInteger
123234
private static BigInteger computeFpRepresentative(ECFieldElement t, ECCurve curve)
124235
{
125236
// Characteristic of F_p
126-
BigInteger p = ((ECCurve.Fp) curve).getQ();
237+
BigInteger p = ((ECCurve.Fp)curve).getQ();
127238

128239
// Assume t = a + i * b in F_p² → extract a, b
129240
ECFieldElement a = t; // In F_p², a is the real part
@@ -133,7 +244,8 @@ private static BigInteger computeFpRepresentative(ECFieldElement t, ECCurve curv
133244
return b.toBigInteger().multiply(a.toBigInteger().modInverse(p)).mod(p);
134245
}
135246

136-
public static byte[] encodeData(ECPoint R_bS, BigInteger H) {
247+
public static byte[] encodeData(ECPoint R_bS, BigInteger H)
248+
{
137249
// 1. Serialize EC Point (use compressed format for efficiency)
138250
byte[] R_bS_bytes = R_bS.getEncoded(true);
139251

core/src/main/java/org/bouncycastle/crypto/kems/SAKKEUtils.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import org.bouncycastle.crypto.Digest;
66
import org.bouncycastle.crypto.digests.SHA256Digest;
77
import org.bouncycastle.math.ec.ECPoint;
8-
import org.bouncycastle.util.Strings;
98
import org.bouncycastle.util.encoders.Hex;
109

1110
public class SAKKEUtils
@@ -30,22 +29,22 @@ public static BigInteger hashToIntegerRange(byte[] input, BigInteger q)
3029
BigInteger v = BigInteger.ZERO;
3130

3231
// Step 4: Compute h_i and v_i
33-
for (int i = 1; i <= l; i++)
32+
for (int i = 0; i <= l; i++)
3433
{
3534
// h_i = hashfn(h_{i-1})
3635
digest.update(h, 0, h.length);
3736
digest.doFinal(h, 0);
38-
System.out.println("h_"+i+":" +new String(Hex.encode(h)));
37+
//System.out.println("h_"+i+":" +new String(Hex.encode(h)));
3938
// v_i = hashfn(h_i || A)
4039
digest.update(h, 0, h.length);
4140
digest.update(A, 0, A.length);
4241
byte[] v_i = new byte[digest.getDigestSize()];
4342
digest.doFinal(v_i, 0);
44-
System.out.println("v_"+i+":" +new String(Hex.encode(v_i)));
43+
//System.out.println("v_"+i+":" +new String(Hex.encode(v_i)));
4544
// Append v_i to v'
4645
v = v.shiftLeft(v_i.length * 8).add(new BigInteger(1, v_i));
4746
}
48-
System.out.println("v:" +new String(Hex.encode(v.toByteArray())));
47+
//System.out.println("v:" +new String(Hex.encode(v.toByteArray())));
4948
// Step 6: v = v' mod n
5049
return v.mod(q);
5150
}

core/src/main/java/org/bouncycastle/crypto/params/SAKKEPublicKey.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44

55
import org.bouncycastle.math.ec.ECCurve;
66
import org.bouncycastle.math.ec.ECPoint;
7+
import org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
78

89
public class SAKKEPublicKey
910
extends AsymmetricKeyParameter
1011
{
11-
private final ECCurve curve;
12+
private final ECCurve curve = new SecP256R1Curve();
1213
private final ECPoint P; // Base point
1314
private final ECPoint Z; // KMS Public Key: Z = [z]P
1415
private final BigInteger q; // Subgroup order
1516
private final int n; // SSV bit length
1617

17-
public SAKKEPublicKey(ECCurve curve, ECPoint P, ECPoint Z, BigInteger q, int n)
18+
public SAKKEPublicKey(ECPoint P, ECPoint Z, BigInteger q, int n)
1819
{
1920
super(false);
20-
this.curve = curve;
2121
this.P = P;
2222
this.Z = Z;
2323
this.q = q;

0 commit comments

Comments
 (0)