diff --git a/crypto/src/crypto/generators/Poly1305KeyGenerator.cs b/crypto/src/crypto/generators/Poly1305KeyGenerator.cs
index d7827fea9..a84807a76 100644
--- a/crypto/src/crypto/generators/Poly1305KeyGenerator.cs
+++ b/crypto/src/crypto/generators/Poly1305KeyGenerator.cs
@@ -50,18 +50,32 @@ namespace Org.BouncyCastle.Crypto.Generators
return key;
}
- /// <summary>
- /// Modifies an existing 32 byte key value to comply with the requirements of the Poly1305 key by
- /// clearing required bits in the <code>r</code> (second 16 bytes) portion of the key.<br/>
- /// Specifically:
- /// <ul>
- /// <li>r[3], r[7], r[11], r[15] have top four bits clear (i.e., are {0, 1, . . . , 15})</li>
- /// <li>r[4], r[8], r[12] have bottom two bits clear (i.e., are in {0, 4, 8, . . . , 252})</li>
- /// </ul>
- /// </summary>
- /// <param name="key">a 32 byte key value <code>k[0] ... k[15], r[0] ... r[15]</code></param>
- public static void Clamp(byte[] key)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ protected override KeyParameter EngineGenerateKeyParameter()
+ {
+ return KeyParameter.Create(strength, random, (bytes, random) =>
+ {
+ random.NextBytes(bytes);
+ Clamp(bytes);
+ });
+ }
+#endif
+
+ /// <summary>
+ /// Modifies an existing 32 byte key value to comply with the requirements of the Poly1305 key by
+ /// clearing required bits in the <code>r</code> (second 16 bytes) portion of the key.<br/>
+ /// Specifically:
+ /// <ul>
+ /// <li>r[3], r[7], r[11], r[15] have top four bits clear (i.e., are {0, 1, . . . , 15})</li>
+ /// <li>r[4], r[8], r[12] have bottom two bits clear (i.e., are in {0, 4, 8, . . . , 252})</li>
+ /// </ul>
+ /// </summary>
+ /// <param name="key">a 32 byte key value <code>k[0] ... k[15], r[0] ... r[15]</code></param>
+ public static void Clamp(byte[] key)
{
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Clamp(key.AsSpan());
+#else
/*
* Key is k[0] ... k[15], r[0] ... r[15] as per poly1305_aes_clamp in ref impl.
*/
@@ -82,9 +96,36 @@ namespace Org.BouncyCastle.Crypto.Generators
key[4] &= R_MASK_LOW_2;
key[8] &= R_MASK_LOW_2;
key[12] &= R_MASK_LOW_2;
+#endif
}
- /// <summary>
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public static void Clamp(Span<byte> key)
+ {
+ /*
+ * Key is k[0] ... k[15], r[0] ... r[15] as per poly1305_aes_clamp in ref impl.
+ */
+ if (key.Length != 32)
+ throw new ArgumentException("Poly1305 key must be 256 bits.");
+
+ /*
+ * r[3], r[7], r[11], r[15] have top four bits clear (i.e., are {0, 1, . . . , 15})
+ */
+ key[3] &= R_MASK_HIGH_4;
+ key[7] &= R_MASK_HIGH_4;
+ key[11] &= R_MASK_HIGH_4;
+ key[15] &= R_MASK_HIGH_4;
+
+ /*
+ * r[4], r[8], r[12] have bottom two bits clear (i.e., are in {0, 4, 8, . . . , 252}).
+ */
+ key[4] &= R_MASK_LOW_2;
+ key[8] &= R_MASK_LOW_2;
+ key[12] &= R_MASK_LOW_2;
+ }
+#endif
+
+ /// <summary>
/// Checks a 32 byte key for compliance with the Poly1305 key requirements, e.g.
/// <code>k[0] ... k[15], r[0] ... r[15]</code> with the required bits in <code>r</code> cleared
/// as per <see cref="Clamp(byte[])"/>.
|