Skip to content

Commit a1544a8

Browse files
author
gefeili
committed
Remove PublicKey class from Snova
1 parent 26783d5 commit a1544a8

File tree

6 files changed

+108
-88
lines changed

6 files changed

+108
-88
lines changed

core/src/main/java/org/bouncycastle/pqc/crypto/snova/MapGroup1.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,23 @@ public MapGroup1(SnovaParameters params)
2828
qAlpha2 = new byte[m][alpha][lsq];
2929
}
3030

31-
public void decode(byte[] input, SnovaParameters params, int len)
31+
public void decode(byte[] input, int len)
3232
{
3333
// int m = params.getM();
3434
// int v = params.getV();
3535
// int o = params.getO();
3636
// int alpha = params.getAlpha();
37-
int lsq = params.getLsq();
38-
if ((lsq & 1) == 0)
39-
{
40-
int inOff = decodeP(input, 0, p11, len);
41-
inOff += decodeP(input, inOff, p12, len - inOff);
42-
inOff += decodeP(input, inOff, p21, len - inOff);
43-
inOff += decodeAlpha(input, inOff, aAlpha, len - inOff);
44-
inOff += decodeAlpha(input, inOff, bAlpha, len - inOff);
45-
inOff += decodeAlpha(input, inOff, qAlpha1, len - inOff);
46-
decodeAlpha(input, inOff, qAlpha2, len - inOff);
47-
}
37+
// int lsq = params.getLsq();
38+
// if ((lsq & 1) == 0)
39+
// {
40+
int inOff = decodeP(input, 0, p11, len);
41+
inOff += decodeP(input, inOff, p12, len - inOff);
42+
inOff += decodeP(input, inOff, p21, len - inOff);
43+
inOff += decodeAlpha(input, inOff, aAlpha, len - inOff);
44+
inOff += decodeAlpha(input, inOff, bAlpha, len - inOff);
45+
inOff += decodeAlpha(input, inOff, qAlpha1, len - inOff);
46+
decodeAlpha(input, inOff, qAlpha2, len - inOff);
47+
// }
4848
// else
4949
// {
5050
//
@@ -76,7 +76,7 @@ public void decode(byte[] input, SnovaParameters params, int len)
7676
// }
7777
// }
7878

79-
private int decodeP(byte[] input, int inOff, byte[][][][] p, int len)
79+
static int decodeP(byte[] input, int inOff, byte[][][][] p, int len)
8080
{
8181
int rlt = 0;
8282
for (int i = 0; i < p.length; ++i)

core/src/main/java/org/bouncycastle/pqc/crypto/snova/PublicKey.java

Lines changed: 0 additions & 14 deletions
This file was deleted.

core/src/main/java/org/bouncycastle/pqc/crypto/snova/SnovaEngine.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ void genABQP(MapGroup1 map1, byte[] pkSeed, byte[] fixedAbq)
468468
}
469469
if ((lsq & 1) == 0)
470470
{
471-
map1.decode(prngOutput, params, (gf16sPrngPublic - qTemp.length) >> 1);
471+
map1.decode(prngOutput, (gf16sPrngPublic - qTemp.length) >> 1);
472472
}
473473
else
474474
{

core/src/main/java/org/bouncycastle/pqc/crypto/snova/SnovaKeyElements.java

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
package org.bouncycastle.pqc.crypto.snova;
22

3-
import org.bouncycastle.crypto.digests.SHAKEDigest;
4-
import org.bouncycastle.util.GF16;
5-
63
class SnovaKeyElements
74
{
85
public final MapGroup1 map1;
96
public final byte[][][] T12; // [v][o]
107
public final MapGroup2 map2;
11-
public final PublicKey publicKey;
128
public byte[] ptPrivateKeySeed;
13-
private final int length;
9+
1410
byte[] fixedAbq;
1511

1612
public SnovaKeyElements(SnovaParameters params)
@@ -22,48 +18,47 @@ public SnovaKeyElements(SnovaParameters params)
2218
map1 = new MapGroup1(params);
2319
T12 = new byte[v][o][lsq];
2420
map2 = new MapGroup2(params);
25-
publicKey = new PublicKey(params);
26-
length = o * params.getAlpha() * lsq * 4 + v * o * lsq + (o * v * v + o * v * o + o * o * v) * lsq;
21+
2722
if (l < 4)
2823
{
2924
fixedAbq = SnovaParameters.fixedAbqSet.get(o);
3025
}
3126
}
3227

33-
public void encodeMergerInHalf(byte[] output)
34-
{
35-
byte[] input = new byte[length];
36-
int inOff = 0;
37-
inOff = copy3d(map1.aAlpha, input, inOff);
38-
inOff = copy3d(map1.bAlpha, input, inOff);
39-
inOff = copy3d(map1.qAlpha1, input, inOff);
40-
inOff = copy3d(map1.qAlpha2, input, inOff);
41-
inOff = copy3d(T12, input, inOff);
42-
inOff = copy4d(map2.f11, input, inOff);
43-
inOff = copy4d(map2.f12, input, inOff);
44-
copy4d(map2.f21, input, inOff);
45-
GF16Utils.encodeMergeInHalf(input, length, output);
46-
}
28+
// public void encodeMergerInHalf(byte[] output)
29+
// {
30+
// byte[] input = new byte[length];
31+
// int inOff = 0;
32+
// inOff = copy3d(map1.aAlpha, input, inOff);
33+
// inOff = copy3d(map1.bAlpha, input, inOff);
34+
// inOff = copy3d(map1.qAlpha1, input, inOff);
35+
// inOff = copy3d(map1.qAlpha2, input, inOff);
36+
// inOff = copy3d(T12, input, inOff);
37+
// inOff = copy4d(map2.f11, input, inOff);
38+
// inOff = copy4d(map2.f12, input, inOff);
39+
// copy4d(map2.f21, input, inOff);
40+
// GF16Utils.encodeMergeInHalf(input, length, output);
41+
// }
4742

48-
public void skUnpack(byte[] input)
49-
{
50-
byte[] tmp = new byte[(input.length - SnovaKeyPairGenerator.publicSeedLength - SnovaKeyPairGenerator.privateSeedLength) << 1];
51-
GF16Utils.decodeMergeInHalf(input, tmp, tmp.length);
52-
int inOff = 0;
53-
inOff = copy3d(tmp, inOff, map1.aAlpha);
54-
inOff = copy3d(tmp, inOff, map1.bAlpha);
55-
inOff = copy3d(tmp, inOff, map1.qAlpha1);
56-
inOff = copy3d(tmp, inOff, map1.qAlpha2);
57-
inOff = copy3d(tmp, inOff, T12);
58-
inOff = copy4d(tmp, inOff, map2.f11);
59-
inOff = copy4d(tmp, inOff, map2.f12);
60-
copy4d(tmp, inOff, map2.f21);
61-
System.arraycopy(input, input.length - SnovaKeyPairGenerator.publicSeedLength - SnovaKeyPairGenerator.privateSeedLength, publicKey.publicKeySeed, 0, publicKey.publicKeySeed.length);
62-
ptPrivateKeySeed = new byte[SnovaKeyPairGenerator.privateSeedLength];
63-
System.arraycopy(input, input.length - SnovaKeyPairGenerator.privateSeedLength, ptPrivateKeySeed, 0, ptPrivateKeySeed.length);
64-
}
43+
// public void skUnpack(byte[] input)
44+
// {
45+
// byte[] tmp = new byte[(input.length - SnovaKeyPairGenerator.publicSeedLength - SnovaKeyPairGenerator.privateSeedLength) << 1];
46+
// GF16Utils.decodeMergeInHalf(input, tmp, tmp.length);
47+
// int inOff = 0;
48+
// inOff = copy3d(tmp, inOff, map1.aAlpha);
49+
// inOff = copy3d(tmp, inOff, map1.bAlpha);
50+
// inOff = copy3d(tmp, inOff, map1.qAlpha1);
51+
// inOff = copy3d(tmp, inOff, map1.qAlpha2);
52+
// inOff = copy3d(tmp, inOff, T12);
53+
// inOff = copy4d(tmp, inOff, map2.f11);
54+
// inOff = copy4d(tmp, inOff, map2.f12);
55+
// copy4d(tmp, inOff, map2.f21);
56+
// System.arraycopy(input, input.length - SnovaKeyPairGenerator.publicSeedLength - SnovaKeyPairGenerator.privateSeedLength, publicKey.publicKeySeed, 0, publicKey.publicKeySeed.length);
57+
// ptPrivateKeySeed = new byte[SnovaKeyPairGenerator.privateSeedLength];
58+
// System.arraycopy(input, input.length - SnovaKeyPairGenerator.privateSeedLength, ptPrivateKeySeed, 0, ptPrivateKeySeed.length);
59+
// }
6560

66-
private int copy3d(byte[][][] alpha, byte[] output, int outOff)
61+
static int copy3d(byte[][][] alpha, byte[] output, int outOff)
6762
{
6863
for (int i = 0; i < alpha.length; ++i)
6964
{
@@ -76,7 +71,7 @@ private int copy3d(byte[][][] alpha, byte[] output, int outOff)
7671
return outOff;
7772
}
7873

79-
private int copy4d(byte[][][][] alpha, byte[] output, int outOff)
74+
static int copy4d(byte[][][][] alpha, byte[] output, int outOff)
8075
{
8176
for (int i = 0; i < alpha.length; ++i)
8277
{
@@ -85,7 +80,7 @@ private int copy4d(byte[][][][] alpha, byte[] output, int outOff)
8580
return outOff;
8681
}
8782

88-
private int copy3d(byte[] input, int inOff, byte[][][] alpha)
83+
static int copy3d(byte[] input, int inOff, byte[][][] alpha)
8984
{
9085
for (int i = 0; i < alpha.length; ++i)
9186
{
@@ -98,7 +93,7 @@ private int copy3d(byte[] input, int inOff, byte[][][] alpha)
9893
return inOff;
9994
}
10095

101-
private int copy4d(byte[] input, int inOff, byte[][][][] alpha)
96+
static int copy4d(byte[] input, int inOff, byte[][][][] alpha)
10297
{
10398
for (int i = 0; i < alpha.length; ++i)
10499
{

core/src/main/java/org/bouncycastle/pqc/crypto/snova/SnovaKeyPairGenerator.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,35 @@ public AsymmetricCipherKeyPair generateKeyPair()
4747
byte[] ptPrivateKeySeed = Arrays.copyOfRange(seedPair, publicSeedLength, seedPair.length);
4848

4949
SnovaKeyElements keyElements = new SnovaKeyElements(params);
50-
generateKeysCore(keyElements, ptPublicKeySeed, ptPrivateKeySeed);
50+
byte[] p22 = new byte[(params.getM() * params.getO() * params.getO() * params.getL() * params.getL() + 1) >> 1];
51+
generateKeysCore(keyElements, ptPublicKeySeed, ptPrivateKeySeed, p22);
5152

5253
// Pack public key components
5354
System.arraycopy(ptPublicKeySeed, 0, pk, 0, ptPublicKeySeed.length);
54-
System.arraycopy(keyElements.publicKey.P22, 0, pk, ptPublicKeySeed.length, keyElements.publicKey.P22.length);
55+
System.arraycopy(p22, 0, pk, ptPublicKeySeed.length, p22.length);
5556

5657
if (params.isSkIsSeed())
5758
{
5859
sk = seedPair;
5960
}
6061
else
6162
{
62-
keyElements.encodeMergerInHalf(sk);
63+
int o = params.getO();
64+
int lsq = params.getLsq();
65+
int v = params.getV();
66+
int length = o * params.getAlpha() * lsq * 4 + v * o * lsq + (o * v * v + o * v * o + o * o * v) * lsq;
67+
//keyElements.encodeMergerInHalf(sk);
68+
byte[] input = new byte[length];
69+
int inOff = 0;
70+
inOff = SnovaKeyElements.copy3d(keyElements.map1.aAlpha, input, inOff);
71+
inOff = SnovaKeyElements.copy3d(keyElements.map1.bAlpha, input, inOff);
72+
inOff = SnovaKeyElements.copy3d(keyElements.map1.qAlpha1, input, inOff);
73+
inOff = SnovaKeyElements.copy3d(keyElements.map1.qAlpha2, input, inOff);
74+
inOff = SnovaKeyElements.copy3d(keyElements.T12, input, inOff);
75+
inOff = SnovaKeyElements.copy4d(keyElements.map2.f11, input, inOff);
76+
inOff = SnovaKeyElements.copy4d(keyElements.map2.f12, input, inOff);
77+
SnovaKeyElements.copy4d(keyElements.map2.f21, input, inOff);
78+
GF16Utils.encodeMergeInHalf(input, length, sk);
6379
System.arraycopy(seedPair, 0, sk, sk.length - seedLength, seedLength);
6480
}
6581

@@ -69,7 +85,7 @@ public AsymmetricCipherKeyPair generateKeyPair()
6985
);
7086
}
7187

72-
private void generateKeysCore(SnovaKeyElements keyElements, byte[] pkSeed, byte[] skSeed)
88+
private void generateKeysCore(SnovaKeyElements keyElements, byte[] pkSeed, byte[] skSeed, byte[] p22)
7389
{
7490
// Generate T12 matrix
7591
engine.genSeedsAndT12(keyElements.T12, skSeed);
@@ -81,6 +97,6 @@ private void generateKeysCore(SnovaKeyElements keyElements, byte[] pkSeed, byte[
8197
engine.genF(keyElements.map2, keyElements.map1, keyElements.T12);
8298

8399
// Generate P22 matrix
84-
engine.genP22(keyElements.publicKey.P22, keyElements.T12, keyElements.map1.p21, keyElements.map2.f12);
100+
engine.genP22(p22, keyElements.T12, keyElements.map1.p21, keyElements.map2.f12);
85101
}
86102
}

core/src/main/java/org/bouncycastle/pqc/crypto/snova/SnovaSigner.java

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,25 +60,40 @@ public byte[] generateSignature(byte[] message)
6060
random.nextBytes(salt);
6161
byte[] signature = new byte[((params.getN() * params.getLsq() + 1) >>> 1) + params.getSaltLength()];
6262
SnovaKeyElements keyElements = new SnovaKeyElements(params);
63+
byte[] publicKeySeed;
6364
if (params.isSkIsSeed())
6465
{
6566
byte[] seedPair = privKey.getPrivateKey();
66-
keyElements.publicKey.publicKeySeed = Arrays.copyOfRange(seedPair, 0, SnovaKeyPairGenerator.publicSeedLength);
67+
publicKeySeed = Arrays.copyOfRange(seedPair, 0, SnovaKeyPairGenerator.publicSeedLength);
6768
keyElements.ptPrivateKeySeed = Arrays.copyOfRange(seedPair, SnovaKeyPairGenerator.publicSeedLength, seedPair.length);
6869
engine.genSeedsAndT12(keyElements.T12, keyElements.ptPrivateKeySeed);
6970

7071
// Generate map components
71-
engine.genABQP(keyElements.map1, keyElements.publicKey.publicKeySeed, keyElements.fixedAbq);
72+
engine.genABQP(keyElements.map1, publicKeySeed, keyElements.fixedAbq);
7273

7374
// Generate F matrices
7475
engine.genF(keyElements.map2, keyElements.map1, keyElements.T12);
7576
}
7677
else
7778
{
78-
keyElements.skUnpack(privKey.getPrivateKey());
79+
byte[] input = privKey.getPrivateKey();
80+
byte[] tmp = new byte[(input.length - SnovaKeyPairGenerator.publicSeedLength - SnovaKeyPairGenerator.privateSeedLength) << 1];
81+
GF16Utils.decodeMergeInHalf(input, tmp, tmp.length);
82+
int inOff = 0;
83+
inOff = SnovaKeyElements.copy3d(tmp, inOff, keyElements.map1.aAlpha);
84+
inOff = SnovaKeyElements.copy3d(tmp, inOff, keyElements.map1.bAlpha);
85+
inOff = SnovaKeyElements.copy3d(tmp, inOff, keyElements.map1.qAlpha1);
86+
inOff = SnovaKeyElements.copy3d(tmp, inOff, keyElements.map1.qAlpha2);
87+
inOff = SnovaKeyElements.copy3d(tmp, inOff, keyElements.T12);
88+
inOff = SnovaKeyElements.copy4d(tmp, inOff, keyElements.map2.f11);
89+
inOff = SnovaKeyElements.copy4d(tmp, inOff, keyElements.map2.f12);
90+
SnovaKeyElements.copy4d(tmp, inOff, keyElements.map2.f21);
91+
publicKeySeed = Arrays.copyOfRange(input, input.length - SnovaKeyPairGenerator.publicSeedLength - SnovaKeyPairGenerator.privateSeedLength, input.length - SnovaKeyPairGenerator.privateSeedLength);
92+
keyElements.ptPrivateKeySeed = new byte[SnovaKeyPairGenerator.privateSeedLength];
93+
System.arraycopy(input, input.length - SnovaKeyPairGenerator.privateSeedLength, keyElements.ptPrivateKeySeed, 0, keyElements.ptPrivateKeySeed.length);
7994
}
8095
signDigestCore(signature, hash, salt, keyElements.map1.aAlpha, keyElements.map1.bAlpha, keyElements.map1.qAlpha1, keyElements.map1.qAlpha2,
81-
keyElements.T12, keyElements.map2.f11, keyElements.map2.f12, keyElements.map2.f21, keyElements.publicKey.publicKeySeed, keyElements.ptPrivateKeySeed);
96+
keyElements.T12, keyElements.map2.f11, keyElements.map2.f12, keyElements.map2.f21, publicKeySeed, keyElements.ptPrivateKeySeed);
8297
return Arrays.concatenate(signature, message);
8398
}
8499

@@ -90,14 +105,22 @@ public boolean verifySignature(byte[] message, byte[] signature)
90105
shake.doFinal(hash, 0);
91106
SnovaKeyElements keyElements = new SnovaKeyElements(params);
92107
byte[] pk = pubKey.getEncoded();
93-
System.arraycopy(pk, 0, keyElements.publicKey.publicKeySeed, 0, SnovaKeyPairGenerator.publicSeedLength);
94-
System.arraycopy(pk, SnovaKeyPairGenerator.publicSeedLength, keyElements.publicKey.P22, 0, keyElements.publicKey.P22.length);
95-
engine.genABQP(keyElements.map1, keyElements.publicKey.publicKeySeed, keyElements.fixedAbq);
96-
byte[] p22_gf16s = new byte[keyElements.publicKey.P22.length << 1];
97-
GF16.decode(keyElements.publicKey.P22, p22_gf16s, p22_gf16s.length);
108+
byte[] publicKeySeed = Arrays.copyOf(pk, SnovaKeyPairGenerator.publicSeedLength);
109+
byte[] p22_source = Arrays.copyOfRange(pk, SnovaKeyPairGenerator.publicSeedLength, pk.length);
110+
engine.genABQP(keyElements.map1, publicKeySeed, keyElements.fixedAbq);
98111
byte[][][][] p22 = new byte[params.getM()][params.getO()][params.getO()][params.getLsq()];
99-
MapGroup1.fillP(p22_gf16s, 0, p22, p22_gf16s.length);
100-
return verifySignatureCore(hash, signature, keyElements.publicKey, keyElements.map1, p22);
112+
if ((params.getLsq() & 1) == 0)
113+
{
114+
MapGroup1.decodeP(p22_source, 0, p22, p22_source.length << 1);
115+
}
116+
else
117+
{
118+
byte[] p22_gf16s = new byte[p22_source.length << 1];
119+
GF16.decode(p22_source, p22_gf16s, p22_gf16s.length);
120+
MapGroup1.fillP(p22_gf16s, 0, p22, p22_gf16s.length);
121+
}
122+
123+
return verifySignatureCore(hash, signature, publicKeySeed, keyElements.map1, p22);
101124
}
102125

103126
public void createSignedHash(
@@ -326,7 +349,7 @@ public void signDigestCore(byte[] ptSignature, byte[] digest, byte[] arraySalt,
326349
System.arraycopy(arraySalt, 0, ptSignature, ptSignature.length - bytesSalt, bytesSalt);
327350
}
328351

329-
public boolean verifySignatureCore(byte[] digest, byte[] signature, PublicKey pkx, MapGroup1 map1, byte[][][][] p22)
352+
public boolean verifySignatureCore(byte[] digest, byte[] signature, byte[] publicKeySeed, MapGroup1 map1, byte[][][][] p22)
330353
{
331354
final int bytesHash = (params.getO() * params.getLsq() + 1) >>> 1;
332355
final int bytesSalt = params.getSaltLength();
@@ -339,7 +362,7 @@ public boolean verifySignatureCore(byte[] digest, byte[] signature, PublicKey pk
339362
// Step 1: Regenerate signed hash using public key seed, digest and salt
340363
byte[] signedHash = new byte[bytesHash];
341364

342-
shake.update(pkx.publicKeySeed, 0, pkx.publicKeySeed.length);
365+
shake.update(publicKeySeed, 0, publicKeySeed.length);
343366
shake.update(digest, 0, digest.length);
344367
shake.update(signature, bytesSignature, bytesSalt);
345368
shake.doFinal(signedHash, 0, bytesHash);

0 commit comments

Comments
 (0)