Skip to content

Commit b05a7b5

Browse files
gefeilidghgit
authored andcommitted
Add ECCSI key generator process
1 parent 3b6cab0 commit b05a7b5

File tree

5 files changed

+274
-0
lines changed

5 files changed

+274
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.bouncycastle.crypto.generators;
2+
3+
import java.math.BigInteger;
4+
import java.security.SecureRandom;
5+
6+
import org.bouncycastle.asn1.x9.X9ECParameters;
7+
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
8+
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
9+
import org.bouncycastle.crypto.CryptoServicePurpose;
10+
import org.bouncycastle.crypto.CryptoServicesRegistrar;
11+
import org.bouncycastle.crypto.Digest;
12+
import org.bouncycastle.crypto.KeyGenerationParameters;
13+
import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
14+
import org.bouncycastle.crypto.digests.SHA256Digest;
15+
import org.bouncycastle.crypto.ec.CustomNamedCurves;
16+
import org.bouncycastle.crypto.params.ECCSIKeyGenerationParameters;
17+
import org.bouncycastle.crypto.params.ECCSIPrivateKeyParameters;
18+
import org.bouncycastle.crypto.params.ECCSIPublicKeyParameters;
19+
import org.bouncycastle.math.ec.ECCurve;
20+
import org.bouncycastle.math.ec.ECPoint;
21+
22+
public class ECCSIKeyPairGenerator
23+
implements AsymmetricCipherKeyPairGenerator
24+
{
25+
// Initialize NIST P-256 curve
26+
private static final X9ECParameters params = CustomNamedCurves.getByName("secP256r1");
27+
private static final ECCurve curve = params.getCurve();
28+
29+
private static final BigInteger q = ((ECCurve.Fp)curve).getQ();
30+
31+
//BigInteger p = ((ECCurve.Fp)curve).getOrder();
32+
33+
// The subgroup order is available as:
34+
//BigInteger n = params.getN();
35+
36+
// And the base point (generator) is:
37+
private static final ECPoint G = params.getG();
38+
//int N = 32; // 256 bits
39+
40+
private ECCSIKeyGenerationParameters parameters;
41+
42+
@Override
43+
public void init(KeyGenerationParameters parameters)
44+
{
45+
this.parameters = (ECCSIKeyGenerationParameters)parameters;
46+
47+
CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("ECCSI", 256, null, CryptoServicePurpose.KEYGEN));
48+
}
49+
50+
@Override
51+
public AsymmetricCipherKeyPair generateKeyPair()
52+
{
53+
SecureRandom random = parameters.getRandom();
54+
byte[] id = parameters.getId();
55+
ECPoint kpak = parameters.getKPAK();
56+
// 1) Choose v, a random (ephemeral) non-zero element of F_q;
57+
BigInteger v = new BigInteger(256, random).mod(q);
58+
// 2) Compute PVT = [v]G
59+
ECPoint pvt = G.multiply(v).normalize();
60+
61+
// 3) Compute a hash value HS = hash( G || KPAK || ID || PVT ), an N-octet integer;
62+
Digest digest = new SHA256Digest();
63+
byte[] tmp = G.getEncoded(false);
64+
digest.update(tmp, 0, tmp.length);
65+
tmp = kpak.getEncoded(false);
66+
digest.update(tmp, 0, tmp.length);
67+
digest.update(id, 0, id.length);
68+
tmp = pvt.getEncoded(false);
69+
digest.update(tmp, 0, tmp.length);
70+
tmp = new byte[digest.getDigestSize()];
71+
digest.doFinal(tmp, 0);
72+
BigInteger HS = new BigInteger(1, tmp).mod(q);
73+
74+
// 4) Compute SSK = ( KSAK + HS * v ) modulo q;
75+
BigInteger ssk = parameters.computeSSK(HS.multiply(v));
76+
return new AsymmetricCipherKeyPair(new ECCSIPublicKeyParameters(pvt), new ECCSIPrivateKeyParameters(ssk));
77+
}
78+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.bouncycastle.crypto.params;
2+
3+
import java.math.BigInteger;
4+
import java.security.SecureRandom;
5+
6+
import org.bouncycastle.asn1.x9.X9ECParameters;
7+
import org.bouncycastle.crypto.KeyGenerationParameters;
8+
import org.bouncycastle.crypto.ec.CustomNamedCurves;
9+
import org.bouncycastle.math.ec.ECCurve;
10+
import org.bouncycastle.math.ec.ECPoint;
11+
import org.bouncycastle.util.Arrays;
12+
13+
public class ECCSIKeyGenerationParameters
14+
extends KeyGenerationParameters
15+
{
16+
private static final X9ECParameters params = CustomNamedCurves.getByName("secP256r1");
17+
private static final ECCurve curve = params.getCurve();
18+
19+
private static final BigInteger q = ((ECCurve.Fp)curve).getQ();
20+
21+
//BigInteger p = ((ECCurve.Fp)curve).getOrder();
22+
23+
// The subgroup order is available as:
24+
//BigInteger n = params.getN();
25+
26+
// And the base point (generator) is:
27+
private static final ECPoint G = params.getG();
28+
private final byte[] id;
29+
private final BigInteger ksak;
30+
private final ECPoint kpak;
31+
32+
/**
33+
* initialise the generator with a source of randomness
34+
* and a strength (in bits).
35+
*
36+
* @param random the random byte source.
37+
*/
38+
public ECCSIKeyGenerationParameters(SecureRandom random, byte[] id)
39+
{
40+
super(random, 256);
41+
this.id = Arrays.clone(id);
42+
this.ksak = new BigInteger(256, random).mod(q);
43+
this.kpak = G.multiply(ksak).normalize();
44+
}
45+
46+
public byte[] getId()
47+
{
48+
return id;
49+
}
50+
51+
public ECPoint getKPAK()
52+
{
53+
return kpak;
54+
}
55+
56+
public BigInteger computeSSK(BigInteger hs_v)
57+
{
58+
return ksak.add(hs_v).mod(q);
59+
}
60+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.bouncycastle.crypto.params;
2+
3+
import java.math.BigInteger;
4+
5+
public class ECCSIPrivateKeyParameters
6+
extends AsymmetricKeyParameter
7+
{
8+
private final BigInteger ssk;
9+
public ECCSIPrivateKeyParameters(BigInteger ssk)
10+
{
11+
super(true);
12+
this.ssk = ssk;
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.bouncycastle.crypto.params;
2+
3+
import org.bouncycastle.math.ec.ECPoint;
4+
5+
public class ECCSIPublicKeyParameters
6+
extends AsymmetricKeyParameter
7+
{
8+
private final ECPoint pvt;
9+
public ECCSIPublicKeyParameters(ECPoint pvt)
10+
{
11+
super(false);
12+
this.pvt = pvt;
13+
}
14+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package org.bouncycastle.crypto.signers;
2+
3+
import java.math.BigInteger;
4+
import java.security.SecureRandom;
5+
6+
import org.bouncycastle.asn1.x9.X9ECParameters;
7+
import org.bouncycastle.crypto.CipherParameters;
8+
import org.bouncycastle.crypto.CryptoException;
9+
import org.bouncycastle.crypto.DataLengthException;
10+
import org.bouncycastle.crypto.Digest;
11+
import org.bouncycastle.crypto.Signer;
12+
import org.bouncycastle.crypto.digests.SHA256Digest;
13+
import org.bouncycastle.crypto.ec.CustomNamedCurves;
14+
import org.bouncycastle.crypto.params.ECCSIPrivateKeyParameters;
15+
import org.bouncycastle.crypto.params.ParametersWithRandom;
16+
import org.bouncycastle.math.ec.ECCurve;
17+
import org.bouncycastle.math.ec.ECPoint;
18+
import org.bouncycastle.util.BigIntegers;
19+
20+
public class ECCSISigner
21+
implements Signer
22+
{
23+
private static final X9ECParameters params = CustomNamedCurves.getByName("secP256r1");
24+
private static final ECCurve curve = params.getCurve();
25+
26+
private static final BigInteger q = ((ECCurve.Fp)curve).getQ();
27+
28+
//BigInteger p = ((ECCurve.Fp)curve).getOrder();
29+
30+
// The subgroup order is available as:
31+
//BigInteger n = params.getN();
32+
33+
// And the base point (generator) is:
34+
private static final ECPoint G = params.getG();
35+
private final Digest digest = new SHA256Digest();
36+
BigInteger j;
37+
ECPoint J;
38+
BigInteger r;
39+
40+
public ECCSISigner()
41+
{
42+
43+
}
44+
45+
@Override
46+
public void init(boolean forSigning, CipherParameters param)
47+
{
48+
SecureRandom random = null;
49+
if (param instanceof ParametersWithRandom)
50+
{
51+
random = ((ParametersWithRandom)param).getRandom();
52+
param = ((ParametersWithRandom)param).getParameters();
53+
}
54+
55+
if (forSigning)
56+
{
57+
ECCSIPrivateKeyParameters parameters = (ECCSIPrivateKeyParameters)param;
58+
59+
j = new BigInteger(256, random).mod(q);
60+
J = G.multiply(j).normalize();
61+
r = J.getAffineXCoord().toBigInteger();
62+
byte[] rBytes = BigIntegers.asUnsignedByteArray(256, r);
63+
// BigInteger kpak = parameters
64+
byte[] tmp = G.getEncoded(false);
65+
digest.update(tmp, 0, tmp.length);
66+
// tmp = kpak.getEncoded(false);
67+
// digest.update(tmp, 0, tmp.length);
68+
// digest.update(id, 0, id.length);
69+
// tmp = pvt.getEncoded(false);
70+
// digest.update(tmp, 0, tmp.length);
71+
tmp = new byte[digest.getDigestSize()];
72+
digest.doFinal(tmp, 0);
73+
BigInteger HS = new BigInteger(1, tmp).mod(q);
74+
}
75+
76+
}
77+
78+
@Override
79+
public void update(byte b)
80+
{
81+
82+
}
83+
84+
@Override
85+
public void update(byte[] in, int off, int len)
86+
{
87+
88+
}
89+
90+
@Override
91+
public byte[] generateSignature()
92+
throws CryptoException, DataLengthException
93+
{
94+
return new byte[0];
95+
}
96+
97+
@Override
98+
public boolean verifySignature(byte[] signature)
99+
{
100+
return false;
101+
}
102+
103+
@Override
104+
public void reset()
105+
{
106+
107+
}
108+
}

0 commit comments

Comments
 (0)