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.BouncyKeyPair.BouncyPrivateKey;
26 import io.github.tonywasher.joceanus.gordianknot.impl.bc.keypair.BouncyKeyPair.BouncyPublicKey;
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.CryptoException;
32 import org.bouncycastle.crypto.Signer;
33 import org.bouncycastle.crypto.signers.Ed25519Signer;
34 import org.bouncycastle.crypto.signers.Ed448Signer;
35
36
37
38
39 public class BouncyEdDSASignature
40 extends GordianCoreSignature {
41
42
43
44 private Signer theSigner;
45
46
47
48
49
50
51
52 BouncyEdDSASignature(final GordianBaseFactory pFactory,
53 final GordianSignatureSpec pSpec) {
54
55 super(pFactory, pSpec);
56 }
57
58
59
60
61
62
63
64 private static Signer createSigner(final GordianKeyPair pKeyPair) {
65
66 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeyPair.getKeyPairSpec();
67 final boolean is25519 = myKeySpec.getEdwardsSpec().is25519();
68 final byte[] myContext = new byte[0];
69
70
71 return is25519
72 ? new Ed25519Signer()
73 : new Ed448Signer(myContext);
74 }
75
76 @Override
77 public void initForSigning(final GordianNewSignParams pParams) throws GordianException {
78
79 super.initForSigning(pParams);
80 final GordianKeyPair myPair = getKeyPair();
81 BouncyKeyPair.checkKeyPair(myPair);
82
83
84 theSigner = createSigner(myPair);
85 final BouncyPrivateKey<?> myPrivate = getKeyPair().getPrivateKey();
86 theSigner.init(true, myPrivate.getPrivateKey());
87 }
88
89 @Override
90 public void initForVerify(final GordianNewSignParams pParams) throws GordianException {
91
92 super.initForVerify(pParams);
93 final GordianKeyPair myPair = getKeyPair();
94 BouncyKeyPair.checkKeyPair(myPair);
95
96
97 theSigner = createSigner(myPair);
98 final BouncyPublicKey<?> myPublic = getKeyPair().getPublicKey();
99 theSigner.init(false, myPublic.getPublicKey());
100 }
101
102 @Override
103 public void update(final byte[] pBytes,
104 final int pOffset,
105 final int pLength) {
106 theSigner.update(pBytes, pOffset, pLength);
107 }
108
109 @Override
110 public void update(final byte pByte) {
111 theSigner.update(pByte);
112 }
113
114 @Override
115 public void update(final byte[] pBytes) {
116 theSigner.update(pBytes, 0, pBytes.length);
117 }
118
119 @Override
120 public void reset() {
121 theSigner.reset();
122 }
123
124 @Override
125 protected BouncyKeyPair getKeyPair() {
126 return (BouncyKeyPair) super.getKeyPair();
127 }
128
129 @Override
130 public byte[] sign() throws GordianException {
131
132 checkMode(GordianSignatureMode.SIGN);
133
134
135 try {
136 return theSigner.generateSignature();
137 } catch (CryptoException e) {
138 throw new GordianCryptoException(BouncySignature.ERROR_SIGGEN, e);
139 }
140 }
141
142 @Override
143 public boolean verify(final byte[] pSignature) throws GordianException {
144
145 checkMode(GordianSignatureMode.VERIFY);
146
147
148 return theSigner.verifySignature(pSignature);
149 }
150 }