aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/DigestingMessageSigner.java
blob: b58a527890868f145ebf0539149a5b575c33d875 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package org.spongycastle.pqc.crypto;

import org.spongycastle.crypto.CipherParameters;
import org.spongycastle.crypto.Digest;
import org.spongycastle.crypto.Signer;
import org.spongycastle.crypto.params.AsymmetricKeyParameter;
import org.spongycastle.crypto.params.ParametersWithRandom;


/**
 * Implements the sign and verify functions for a Signature Scheme which can use a hash function.
 */
public class DigestingMessageSigner
    implements Signer
{
    private final Digest messDigest;
    private final MessageSigner messSigner;
    private boolean forSigning;

    public DigestingMessageSigner(MessageSigner messSigner, Digest messDigest)
    {
        this.messSigner = messSigner;
        this.messDigest = messDigest;
    }

    public void init(boolean forSigning,
                     CipherParameters param)
    {

        this.forSigning = forSigning;
        AsymmetricKeyParameter k;

        if (param instanceof ParametersWithRandom)
        {
            k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters();
        }
        else
        {
            k = (AsymmetricKeyParameter)param;
        }

        if (forSigning && !k.isPrivate())
        {
            throw new IllegalArgumentException("Signing Requires Private Key.");
        }

        if (!forSigning && k.isPrivate())
        {
            throw new IllegalArgumentException("Verification Requires Public Key.");
        }

        reset();

        messSigner.init(forSigning, param);
    }


    /**
     * This function signs the message that has been updated, making use of the
     * private key.
     *
     * @return the signature of the message.
     */
    public byte[] generateSignature()
    {
        if (!forSigning)
        {
            throw new IllegalStateException("RainbowDigestSigner not initialised for signature generation.");
        }

        byte[] hash = new byte[messDigest.getDigestSize()];
        messDigest.doFinal(hash, 0);

        return messSigner.generateSignature(hash);
    }

    /**
     * This function verifies the signature of the message that has been
     * updated, with the aid of the public key.
     *
     * @param signature the signature of the message is given as a byte array.
     * @return true if the signature has been verified, false otherwise.
     */
    public boolean verify(byte[] signature)
    {
        if (forSigning)
        {
            throw new IllegalStateException("RainbowDigestSigner not initialised for verification");
        }

        byte[] hash = new byte[messDigest.getDigestSize()];
        messDigest.doFinal(hash, 0);

        return messSigner.verifySignature(hash, signature);

    }

    public void update(byte b)
    {
        messDigest.update(b);
    }

    public void update(byte[] in, int off, int len)
    {
        messDigest.update(in, off, len);
    }

    public void reset()
    {
        messDigest.reset();
    }

    public boolean verifySignature(byte[] signature)
    {
        return this.verify(signature);
    }
}