1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package io.github.tonywasher.joceanus.gordianknot.impl.bc.sign;
19
20 import io.github.tonywasher.joceanus.gordianknot.api.base.GordianException;
21 import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianKeyPair;
22 import io.github.tonywasher.joceanus.gordianknot.api.sign.GordianNewSignParams;
23 import io.github.tonywasher.joceanus.gordianknot.api.sign.spec.GordianSignatureSpec;
24 import io.github.tonywasher.joceanus.gordianknot.impl.bc.keypair.BouncyKeyPair;
25 import io.github.tonywasher.joceanus.gordianknot.impl.bc.keypair.BouncyMLDSAKeyPair.BouncyMLDSAPrivateKey;
26 import io.github.tonywasher.joceanus.gordianknot.impl.bc.keypair.BouncyMLDSAKeyPair.BouncyMLDSAPublicKey;
27 import io.github.tonywasher.joceanus.gordianknot.impl.core.base.GordianBaseFactory;
28 import io.github.tonywasher.joceanus.gordianknot.impl.core.exc.GordianCryptoException;
29 import io.github.tonywasher.joceanus.gordianknot.impl.core.sign.GordianCoreSignature;
30 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.keypair.GordianCoreKeyPairSpec;
31 import org.bouncycastle.crypto.CipherParameters;
32 import org.bouncycastle.crypto.CryptoException;
33 import org.bouncycastle.crypto.Signer;
34 import org.bouncycastle.crypto.params.ParametersWithContext;
35 import org.bouncycastle.crypto.params.ParametersWithRandom;
36 import org.bouncycastle.crypto.signers.HashMLDSASigner;
37 import org.bouncycastle.crypto.signers.MLDSASigner;
38
39
40
41
42 public class BouncyMLDSASignature
43 extends GordianCoreSignature {
44
45
46
47 private Signer theSigner;
48
49
50
51
52
53
54
55 BouncyMLDSASignature(final GordianBaseFactory pFactory,
56 final GordianSignatureSpec pSpec) {
57
58 super(pFactory, pSpec);
59 }
60
61
62
63
64
65
66
67 private static Signer createSigner(final GordianKeyPair pKeyPair) {
68
69 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeyPair.getKeyPairSpec();
70 final boolean isHash = myKeySpec.getMLDSASpec().isHash();
71
72
73 return isHash
74 ? new HashMLDSASigner()
75 : new MLDSASigner();
76 }
77
78 @Override
79 public void initForSigning(final GordianNewSignParams pParams) throws GordianException {
80
81 super.initForSigning(pParams);
82 final BouncyKeyPair myPair = getKeyPair();
83 final byte[] myContext = getContext();
84 BouncyKeyPair.checkKeyPair(myPair);
85
86
87 theSigner = createSigner(myPair);
88 final BouncyMLDSAPrivateKey myPrivate = (BouncyMLDSAPrivateKey) myPair.getPrivateKey();
89 CipherParameters myParms = new ParametersWithRandom(myPrivate.getPrivateKey(), getRandom());
90 if (myContext != null) {
91 myParms = new ParametersWithContext(myParms, myContext);
92 }
93 theSigner.init(true, myParms);
94 }
95
96 @Override
97 public void initForVerify(final GordianNewSignParams pParams) throws GordianException {
98
99 super.initForVerify(pParams);
100 final BouncyKeyPair myPair = getKeyPair();
101 final byte[] myContext = getContext();
102 BouncyKeyPair.checkKeyPair(myPair);
103
104
105 theSigner = createSigner(myPair);
106 final BouncyMLDSAPublicKey myPublic = (BouncyMLDSAPublicKey) myPair.getPublicKey();
107 CipherParameters myParms = myPublic.getPublicKey();
108 if (myContext != null) {
109 myParms = new ParametersWithContext(myParms, myContext);
110 }
111 theSigner.init(false, myParms);
112 }
113
114 @Override
115 public void update(final byte[] pBytes,
116 final int pOffset,
117 final int pLength) {
118 theSigner.update(pBytes, pOffset, pLength);
119 }
120
121 @Override
122 public void update(final byte pByte) {
123 theSigner.update(pByte);
124 }
125
126 @Override
127 public void update(final byte[] pBytes) {
128 theSigner.update(pBytes, 0, pBytes.length);
129 }
130
131 @Override
132 public void reset() {
133 theSigner.reset();
134 }
135
136 @Override
137 protected BouncyKeyPair getKeyPair() {
138 return (BouncyKeyPair) super.getKeyPair();
139 }
140
141 @Override
142 public byte[] sign() throws GordianException {
143
144 checkMode(GordianSignatureMode.SIGN);
145
146
147 try {
148 return theSigner.generateSignature();
149 } catch (CryptoException e) {
150 throw new GordianCryptoException("Failed to sign message", e);
151 }
152 }
153
154 @Override
155 public boolean verify(final byte[] pSignature) throws GordianException {
156
157 checkMode(GordianSignatureMode.VERIFY);
158
159
160 return theSigner.verifySignature(pSignature);
161 }
162 }