9
9
10
10
namespace Libplanet . Crypto
11
11
{
12
- public class BlsPrivateKey : IEquatable < BlsPrivateKey > , IECPrivateKey
12
+ /// <summary>
13
+ /// A secret key pair of
14
+ /// <a href="https://datatracker.ietf.org/doc/draft-irtf-cfrg-bls-signature/">BLS Signature</a>
15
+ /// used in consensus for signing signature.
16
+ /// It can create <see cref="BlsSignature"/>, which can be verified corresponding
17
+ /// <see cref="Libplanet.Crypto.BlsPublicKey"/> with message. Also <see cref="BlsSignature"/>
18
+ /// can be aggregated with another signatures, and can be verified with multiple corresponding
19
+ /// <see cref="Libplanet.Crypto.BlsPublicKey"/> by <see cref="BlsSignature.AggregateVerify"/>,
20
+ /// <see cref="BlsSignature.FastAggregateVerify"/> or <see cref="BlsSignature.MultiVerify"/>
21
+ /// for its use-case. The implementation uses the BLS12_381 curve type with minimal public key
22
+ /// size setting, which is the same configuration with Ethereum 2.0 Phase 0.
23
+ /// </summary>
24
+ /// <remarks>
25
+ /// These (and any derived representations, e.g., <see cref="ByteArray"/>)
26
+ /// must be kept secret, if they are exposed, an attacker will be able to
27
+ /// forge signatures.
28
+ /// <para>Every <see cref="PrivateKey"/> object is immutable.</para>
29
+ /// </remarks>
30
+ /// <seealso cref="Libplanet.Crypto.BlsPublicKey"/>
31
+ public sealed class BlsPrivateKey : IEquatable < BlsPrivateKey > , IECPrivateKey
13
32
{
14
33
private const int KeyByteSize = BLS . SECRETKEY_SERIALIZE_SIZE ;
15
34
private readonly IReadOnlyList < byte > _privateKey ;
16
35
private BlsPublicKey ? _publicKey ;
17
36
18
37
/// <summary>
19
- /// Instantiates a new random <see cref="BlsPrivateKey"/>.
38
+ /// Instantiates a new random <see cref="BlsPrivateKey"/> with CSPRNG (Cryptographically
39
+ /// Secure Random Number Generator).
20
40
/// </summary>
21
41
public BlsPrivateKey ( )
22
42
{
@@ -28,6 +48,8 @@ public BlsPrivateKey()
28
48
/// </summary>
29
49
/// <param name="privateKey">A <see cref="byte"/> array representation of private key.
30
50
/// </param>
51
+ /// <exception cref="ArgumentNullException">Thrown if given value is
52
+ /// <see cref="ImmutableArray{T}"/> and empty.</exception>
31
53
/// <exception cref="ArgumentOutOfRangeException">Thrown if given private key is not
32
54
/// <see cref="KeyByteSize"/>.
33
55
/// </exception>
@@ -64,7 +86,7 @@ public BlsPrivateKey(string hex)
64
86
}
65
87
66
88
/// <summary>
67
- /// A pair public key of this private key.
89
+ /// A pair public key of private key.
68
90
/// </summary>
69
91
public BlsPublicKey PublicKey
70
92
{
@@ -83,9 +105,29 @@ public BlsPublicKey PublicKey
83
105
84
106
IReadOnlyList < byte > IECPrivateKey . KeyBytes => ByteArray ;
85
107
108
+ /// <summary>
109
+ /// The parameter for BLS private key signature. This is not supported.
110
+ /// </summary>
111
+ /// <exception cref="NotSupportedException">This is not supported.</exception>
86
112
public ECPrivateKeyParameters KeyParam => throw new NotSupportedException (
87
113
"Currently setting key with BLS key parameter is not supported." ) ;
88
114
115
+ /// <summary>
116
+ /// An encoded <see cref="byte"/> array representation.
117
+ /// </summary>
118
+ /// <remarks>
119
+ /// An encoded <see cref="byte"/> array representation can be recovered to a <see
120
+ /// cref="BlsPrivateKey"/> instance again using
121
+ /// <see cref="BlsPrivateKey(IReadOnlyList{byte})"/> constructor.
122
+ /// <para>As like <see cref="BlsPrivateKey"/> instances, it also must be kept secret.
123
+ /// In practice, this must not be sent over the network, and be securely stored in the file
124
+ /// system.
125
+ /// </para>
126
+ /// <para>To get a mutable array instead of immutable one, use <see cref="ToByteArray()"/>
127
+ /// method instead.</para>
128
+ /// </remarks>
129
+ /// <seealso cref="ToByteArray()"/>
130
+ /// <seealso cref="PrivateKey(IReadOnlyList{byte})"/>
89
131
[ Pure ]
90
132
public ImmutableArray < byte > ByteArray => _privateKey . ToImmutableArray ( ) ;
91
133
@@ -95,10 +137,37 @@ public BlsPublicKey PublicKey
95
137
public static bool operator != ( BlsPrivateKey left , BlsPrivateKey right ) =>
96
138
! left . Equals ( right ) ;
97
139
140
+ /// <summary>
141
+ /// Creates a <see cref="BlsPrivateKey"/> instance from hexadecimal string of bytes.
142
+ /// </summary>
143
+ /// <param name="hex">A hexadecimal string of a private key's
144
+ /// <see cref="ByteArray"/>.</param>
145
+ /// <returns>A created <see cref="BlsPrivateKey"/> instance.</returns>
146
+ /// <exception cref="ArgumentNullException">Thrown when the given <paramref name="hex"/>
147
+ /// string is <c>null</c>.</exception>
148
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when the length of the given
149
+ /// <paramref name="hex"/> string is too short or too long.</exception>
150
+ /// <exception cref="FormatException">Thrown when the given <paramref name="hex"/> string is
151
+ /// not a valid hexadecimal string.</exception>
152
+ /// <exception cref="CryptographicException">Thrown if deserialization has been failed
153
+ /// in library.
154
+ /// </exception>
98
155
[ Pure ]
99
156
public static BlsPrivateKey FromString ( string hex ) =>
100
157
new BlsPrivateKey ( GenerateBytesFromHexString ( hex ) ) ;
101
158
159
+ /// <summary>
160
+ /// Returns the corresponding Proof of Possession. Public key can be aggregated, therefore
161
+ /// some public key are not the true public key from a private key.
162
+ /// <para>The Proof of Possession
163
+ /// is used for validate whether the public key is derived from a private key.
164
+ /// </para>
165
+ /// </summary>
166
+ /// <returns>Returns the proof of possession of <see cref="BlsPrivateKey"/>.</returns>
167
+ /// <remarks>The infinite public key (e.g., derived from zero private key) cannot be
168
+ /// validated with Proof of possession of its infinite signature and considered invalid.
169
+ /// Therefore, the infinite public key also can be filtered with proof of possession.
170
+ /// </remarks>
102
171
[ Pure ]
103
172
public BlsSignature GetProofOfPossession ( ) => PublicKey . ProofOfPossession ;
104
173
@@ -109,14 +178,74 @@ public bool Equals(BlsPrivateKey? other) =>
109
178
110
179
public override int GetHashCode ( ) => ByteUtil . CalculateHashCode ( ToByteArray ( ) ) ;
111
180
181
+ /// <summary>
182
+ /// Creates a signature from the given <paramref name="message"/>.
183
+ /// <para>A created signature can be verified by the corresponding
184
+ /// <see cref="BlsPublicKey"/>.
185
+ /// </para>
186
+ /// <para>Signatures can be created by only the <see cref="BlsPrivateKey"/> which
187
+ /// corresponds a <see cref="BlsPublicKey"/> to verify these signatures.</para>
188
+ /// <para>To sum up, a signature is used to guarantee:</para>
189
+ /// <list type="bullet">
190
+ /// <item><description>that the <paramref name="message"/> was created by someone possessing
191
+ /// the corresponding <see cref="BlsPrivateKey"/>,</description></item>
192
+ /// <item><description>that the possessor cannot deny having sent the
193
+ /// <paramref name="message"/>, and</description></item>
194
+ /// <item><description>that the <paramref name="message"/> was not forged in the middle of
195
+ /// transit.</description></item>
196
+ /// </list>
197
+ /// <see cref="BlsSignature"/> can be aggregated, and can verify multiple signature in
198
+ /// batch.
199
+ /// <list type="bullet">
200
+ /// <item><description>If the messages are all different, use
201
+ /// <see cref="BlsSignature.AggregateVerify"/> or,</description></item>
202
+ /// <item><description>all the messages are same, use
203
+ /// <see cref="BlsSignature.FastAggregateVerify"/></description></item>
204
+ /// <item><description>if
205
+ /// above all cases are not true, then use <see cref="BlsSignature.MultiVerify"/> without a
206
+ /// signature aggregation.</description></item>
207
+ /// </list>
208
+ /// </summary>
209
+ /// <param name="message">A message <see cref="byte"/>s to sign.</param>
210
+ /// <returns>A signature that proves the authenticity of the <paramref name="message"/>.
211
+ /// It can be verified using <see cref="Libplanet.Crypto.BlsPublicKey.Verify"/>,
212
+ /// <see cref="BlsSignature.AggregateVerify"/>,
213
+ /// <see cref="BlsSignature.FastAggregateVerify"/>, or
214
+ /// <see cref="BlsSignature.MultiVerify"/> method with requiring use-case.
215
+ /// </returns>
216
+ /// <seealso cref="Libplanet.Crypto.BlsPublicKey.Verify"/>
217
+ /// <seealso cref="BlsSignature.AggregateVerify"/>
218
+ /// <seealso cref="BlsSignature.FastAggregateVerify"/>
219
+ /// <seealso cref="BlsSignature.MultiVerify"/>
112
220
public byte [ ] Sign ( byte [ ] message )
113
221
{
114
222
HashDigest < SHA256 > hashed = HashDigest < SHA256 > . DeriveFrom ( message ) ;
115
223
return CryptoConfig . ConsensusCryptoBackend . Sign ( hashed , this ) ;
116
224
}
117
225
226
+ /// <inheritdoc cref="Sign(byte[])"/>
118
227
public byte [ ] Sign ( ImmutableArray < byte > message ) => Sign ( message . ToArray ( ) ) ;
119
228
229
+ /// <summary>
230
+ /// Encodes the private key into a corresponding mutable <see cref="byte"/> array
231
+ /// representation.
232
+ /// </summary>
233
+ /// <returns>An encoded <see cref="byte"/> array representation. It guarantees that
234
+ /// returned arrays are never reused, and mutating on them does not affect
235
+ /// <see cref="BlsPrivateKey"/> instance's internal states.</returns>
236
+ /// <remarks>
237
+ /// An encoded <see cref="byte"/> array representation can be recovered to a <see
238
+ /// cref="BlsPrivateKey"/> instance again using
239
+ /// <see cref="BlsPrivateKey(IReadOnlyList{byte})"/> constructor.
240
+ /// <para>As like <see cref="BlsPrivateKey"/> instances, it also must be kept secret.
241
+ /// In practice, this must not be sent over the network, and be securely stored in the file
242
+ /// system.
243
+ /// </para>
244
+ /// <para>To get an immutable array instead of mutable one, use <see cref="ByteArray"/>
245
+ /// property.</para>
246
+ /// </remarks>
247
+ /// <seealso cref="ByteArray"/>
248
+ /// <seealso cref="BlsPrivateKey(IReadOnlyList{byte})"/>
120
249
[ Pure ]
121
250
public byte [ ] ToByteArray ( ) => _privateKey . ToArray ( ) ;
122
251
0 commit comments