summary refs log tree commit diff
path: root/crypto/src/crypto/generators/Poly1305KeyGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/crypto/generators/Poly1305KeyGenerator.cs')
-rw-r--r--crypto/src/crypto/generators/Poly1305KeyGenerator.cs65
1 files changed, 53 insertions, 12 deletions
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[])"/>.