diff --git a/crypto/src/crmf/PKMacBuilder.cs b/crypto/src/crmf/PKMacBuilder.cs
index 156936eac..9b483fbfb 100644
--- a/crypto/src/crmf/PKMacBuilder.cs
+++ b/crypto/src/crmf/PKMacBuilder.cs
@@ -83,6 +83,15 @@ namespace Org.BouncyCastle.Crmf
signature.CopyTo(sig, sigOff);
return signature.Length;
}
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public int Collect(Span<byte> destination)
+ {
+ byte[] result = Collect();
+ result.CopyTo(destination);
+ return result.Length;
+ }
+#endif
}
public class PKMacBuilder
diff --git a/crypto/src/crypto/Check.cs b/crypto/src/crypto/Check.cs
index 81d07e23c..36263dc24 100644
--- a/crypto/src/crypto/Check.cs
+++ b/crypto/src/crypto/Check.cs
@@ -23,7 +23,7 @@ namespace Org.BouncyCastle.Crypto
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- internal static void DataLength(Span<byte> input, int len, string msg)
+ internal static void DataLength(ReadOnlySpan<byte> input, int len, string msg)
{
if (input.Length < len)
throw new DataLengthException(msg);
diff --git a/crypto/src/crypto/IBlockResult.cs b/crypto/src/crypto/IBlockResult.cs
index 0f054fedc..3ed96a7c1 100644
--- a/crypto/src/crypto/IBlockResult.cs
+++ b/crypto/src/crypto/IBlockResult.cs
@@ -1,4 +1,5 @@
-
+using System;
+
namespace Org.BouncyCastle.Crypto
{
/// <summary>
@@ -20,5 +21,14 @@ namespace Org.BouncyCastle.Crypto
/// <param name="destination">The byte array to copy the result into.</param>
/// <param name="offset">The offset into destination to start copying the result at.</param>
int Collect(byte[] destination, int offset);
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ /// <summary>
+ /// Store the final result of the operation by copying it into the destination span.
+ /// </summary>
+ /// <returns>The number of bytes copied into destination.</returns>
+ /// <param name="destination">The span to copy the result into.</param>
+ int Collect(Span<byte> destination);
+#endif
}
}
diff --git a/crypto/src/crypto/SimpleBlockResult.cs b/crypto/src/crypto/SimpleBlockResult.cs
index 6cacda63f..35432c2b3 100644
--- a/crypto/src/crypto/SimpleBlockResult.cs
+++ b/crypto/src/crypto/SimpleBlockResult.cs
@@ -49,5 +49,14 @@ namespace Org.BouncyCastle.Crypto
return result.Length;
}
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public int Collect(Span<byte> destination)
+ {
+ result.CopyTo(destination);
+
+ return result.Length;
+ }
+#endif
}
}
diff --git a/crypto/src/crypto/digests/RipeMD128Digest.cs b/crypto/src/crypto/digests/RipeMD128Digest.cs
index e8a0331ca..cba2c65d3 100644
--- a/crypto/src/crypto/digests/RipeMD128Digest.cs
+++ b/crypto/src/crypto/digests/RipeMD128Digest.cs
@@ -1,5 +1,6 @@
using System;
+using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Digests
@@ -57,12 +58,9 @@ namespace Org.BouncyCastle.Crypto.Digests
return DigestLength;
}
- internal override void ProcessWord(
- byte[] input,
- int inOff)
+ internal override void ProcessWord(byte[] input, int inOff)
{
- X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8)
- | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24);
+ X[xOff++] = (int)Pack.LE_To_UInt32(input, inOff);
if (xOff == 16)
{
@@ -82,27 +80,14 @@ namespace Org.BouncyCastle.Crypto.Digests
X[15] = (int)((ulong) bitLength >> 32);
}
- private void UnpackWord(
- int word,
- byte[] outBytes,
- int outOff)
- {
- outBytes[outOff] = (byte)word;
- outBytes[outOff + 1] = (byte)((uint) word >> 8);
- outBytes[outOff + 2] = (byte)((uint) word >> 16);
- outBytes[outOff + 3] = (byte)((uint) word >> 24);
- }
-
- public override int DoFinal(
- byte[] output,
- int outOff)
+ public override int DoFinal(byte[] output, int outOff)
{
Finish();
- UnpackWord(H0, output, outOff);
- UnpackWord(H1, output, outOff + 4);
- UnpackWord(H2, output, outOff + 8);
- UnpackWord(H3, output, outOff + 12);
+ Pack.UInt32_To_LE((uint)H0, output, outOff);
+ Pack.UInt32_To_LE((uint)H1, output, outOff + 4);
+ Pack.UInt32_To_LE((uint)H2, output, outOff + 8);
+ Pack.UInt32_To_LE((uint)H3, output, outOff + 12);
Reset();
@@ -478,7 +463,5 @@ namespace Org.BouncyCastle.Crypto.Digests
CopyIn(d);
}
-
}
-
}
diff --git a/crypto/src/crypto/digests/RipeMD160Digest.cs b/crypto/src/crypto/digests/RipeMD160Digest.cs
index af4aa44bb..0fc2a4a1c 100644
--- a/crypto/src/crypto/digests/RipeMD160Digest.cs
+++ b/crypto/src/crypto/digests/RipeMD160Digest.cs
@@ -1,5 +1,6 @@
using System;
+using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Digests
@@ -59,12 +60,9 @@ namespace Org.BouncyCastle.Crypto.Digests
return DigestLength;
}
- internal override void ProcessWord(
- byte[] input,
- int inOff)
+ internal override void ProcessWord(byte[] input, int inOff)
{
- X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8)
- | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24);
+ X[xOff++] = (int)Pack.LE_To_UInt32(input, inOff);
if (xOff == 16)
{
@@ -72,7 +70,7 @@ namespace Org.BouncyCastle.Crypto.Digests
}
}
- internal override void ProcessLength(
+ internal override void ProcessLength(
long bitLength)
{
if (xOff > 14)
@@ -84,28 +82,15 @@ namespace Org.BouncyCastle.Crypto.Digests
X[15] = (int)((ulong) bitLength >> 32);
}
- private void UnpackWord(
- int word,
- byte[] outBytes,
- int outOff)
- {
- outBytes[outOff] = (byte)word;
- outBytes[outOff + 1] = (byte)((uint) word >> 8);
- outBytes[outOff + 2] = (byte)((uint) word >> 16);
- outBytes[outOff + 3] = (byte)((uint) word >> 24);
- }
-
- public override int DoFinal(
- byte[] output,
- int outOff)
+ public override int DoFinal(byte[] output, int outOff)
{
Finish();
- UnpackWord(H0, output, outOff);
- UnpackWord(H1, output, outOff + 4);
- UnpackWord(H2, output, outOff + 8);
- UnpackWord(H3, output, outOff + 12);
- UnpackWord(H4, output, outOff + 16);
+ Pack.UInt32_To_LE((uint)H0, output, outOff);
+ Pack.UInt32_To_LE((uint)H1, output, outOff + 4);
+ Pack.UInt32_To_LE((uint)H2, output, outOff + 8);
+ Pack.UInt32_To_LE((uint)H3, output, outOff + 12);
+ Pack.UInt32_To_LE((uint)H4, output, outOff + 16);
Reset();
@@ -439,7 +424,5 @@ namespace Org.BouncyCastle.Crypto.Digests
CopyIn(d);
}
-
}
-
}
diff --git a/crypto/src/crypto/digests/RipeMD256Digest.cs b/crypto/src/crypto/digests/RipeMD256Digest.cs
index 306275767..621162a6f 100644
--- a/crypto/src/crypto/digests/RipeMD256Digest.cs
+++ b/crypto/src/crypto/digests/RipeMD256Digest.cs
@@ -1,5 +1,6 @@
using System;
+using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Digests
@@ -59,12 +60,9 @@ namespace Org.BouncyCastle.Crypto.Digests
xOff = t.xOff;
}
- internal override void ProcessWord(
- byte[] input,
- int inOff)
+ internal override void ProcessWord(byte[] input, int inOff)
{
- X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8)
- | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24);
+ X[xOff++] = (int)Pack.LE_To_UInt32(input, inOff);
if (xOff == 16)
{
@@ -84,29 +82,18 @@ namespace Org.BouncyCastle.Crypto.Digests
X[15] = (int)((ulong)bitLength >> 32);
}
- private void UnpackWord(
- int word,
- byte[] outBytes,
- int outOff)
- {
- outBytes[outOff] = (byte)(uint)word;
- outBytes[outOff + 1] = (byte)((uint)word >> 8);
- outBytes[outOff + 2] = (byte)((uint)word >> 16);
- outBytes[outOff + 3] = (byte)((uint)word >> 24);
- }
-
public override int DoFinal(byte[] output, int outOff)
{
Finish();
- UnpackWord(H0, output, outOff);
- UnpackWord(H1, output, outOff + 4);
- UnpackWord(H2, output, outOff + 8);
- UnpackWord(H3, output, outOff + 12);
- UnpackWord(H4, output, outOff + 16);
- UnpackWord(H5, output, outOff + 20);
- UnpackWord(H6, output, outOff + 24);
- UnpackWord(H7, output, outOff + 28);
+ Pack.UInt32_To_LE((uint)H0, output, outOff);
+ Pack.UInt32_To_LE((uint)H1, output, outOff + 4);
+ Pack.UInt32_To_LE((uint)H2, output, outOff + 8);
+ Pack.UInt32_To_LE((uint)H3, output, outOff + 12);
+ Pack.UInt32_To_LE((uint)H4, output, outOff + 16);
+ Pack.UInt32_To_LE((uint)H5, output, outOff + 20);
+ Pack.UInt32_To_LE((uint)H6, output, outOff + 24);
+ Pack.UInt32_To_LE((uint)H7, output, outOff + 28);
Reset();
@@ -425,6 +412,5 @@ namespace Org.BouncyCastle.Crypto.Digests
CopyIn(d);
}
-
}
}
diff --git a/crypto/src/crypto/digests/RipeMD320Digest.cs b/crypto/src/crypto/digests/RipeMD320Digest.cs
index 767d74dba..c46bc4fea 100644
--- a/crypto/src/crypto/digests/RipeMD320Digest.cs
+++ b/crypto/src/crypto/digests/RipeMD320Digest.cs
@@ -1,5 +1,6 @@
using System;
+using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Digests
@@ -62,12 +63,9 @@ namespace Org.BouncyCastle.Crypto.Digests
xOff = t.xOff;
}
- internal override void ProcessWord(
- byte[] input,
- int inOff)
+ internal override void ProcessWord(byte[] input, int inOff)
{
- X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8)
- | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24);
+ X[xOff++] = (int)Pack.LE_To_UInt32(input, inOff);
if (xOff == 16)
{
@@ -87,31 +85,20 @@ namespace Org.BouncyCastle.Crypto.Digests
X[15] = (int)((ulong)bitLength >> 32);
}
- private void UnpackWord(
- int word,
- byte[] outBytes,
- int outOff)
- {
- outBytes[outOff] = (byte)word;
- outBytes[outOff + 1] = (byte)((uint)word >> 8);
- outBytes[outOff + 2] = (byte)((uint)word >> 16);
- outBytes[outOff + 3] = (byte)((uint)word >> 24);
- }
-
public override int DoFinal(byte[] output, int outOff)
{
Finish();
- UnpackWord(H0, output, outOff);
- UnpackWord(H1, output, outOff + 4);
- UnpackWord(H2, output, outOff + 8);
- UnpackWord(H3, output, outOff + 12);
- UnpackWord(H4, output, outOff + 16);
- UnpackWord(H5, output, outOff + 20);
- UnpackWord(H6, output, outOff + 24);
- UnpackWord(H7, output, outOff + 28);
- UnpackWord(H8, output, outOff + 32);
- UnpackWord(H9, output, outOff + 36);
+ Pack.UInt32_To_LE((uint)H0, output, outOff);
+ Pack.UInt32_To_LE((uint)H1, output, outOff + 4);
+ Pack.UInt32_To_LE((uint)H2, output, outOff + 8);
+ Pack.UInt32_To_LE((uint)H3, output, outOff + 12);
+ Pack.UInt32_To_LE((uint)H4, output, outOff + 16);
+ Pack.UInt32_To_LE((uint)H5, output, outOff + 20);
+ Pack.UInt32_To_LE((uint)H6, output, outOff + 24);
+ Pack.UInt32_To_LE((uint)H7, output, outOff + 28);
+ Pack.UInt32_To_LE((uint)H8, output, outOff + 32);
+ Pack.UInt32_To_LE((uint)H9, output, outOff + 36);
Reset();
@@ -454,6 +441,5 @@ namespace Org.BouncyCastle.Crypto.Digests
CopyIn(d);
}
-
}
}
diff --git a/crypto/src/crypto/digests/SkeinEngine.cs b/crypto/src/crypto/digests/SkeinEngine.cs
index 2f38115d2..a36ac8fe7 100644
--- a/crypto/src/crypto/digests/SkeinEngine.cs
+++ b/crypto/src/crypto/digests/SkeinEngine.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
@@ -75,7 +76,7 @@ namespace Org.BouncyCastle.Crypto.Digests
bytes[5] = 0;
// 8..15 = output length
- ThreefishEngine.WordToBytes((ulong)outputSizeBits, bytes, 8);
+ Pack.UInt64_To_LE((ulong)outputSizeBits, bytes, 8);
}
public byte[] Bytes
@@ -441,10 +442,7 @@ namespace Org.BouncyCastle.Crypto.Digests
private void ProcessBlock(ulong[] output)
{
engine.threefish.Init(true, engine.chain, tweak.GetWords());
- for (int i = 0; i < message.Length; i++)
- {
- message[i] = ThreefishEngine.BytesToWord(currentBlock, i * 8);
- }
+ Pack.LE_To_UInt64(currentBlock, 0, message);
engine.threefish.ProcessBlock(message, output);
@@ -465,7 +463,6 @@ namespace Org.BouncyCastle.Crypto.Digests
tweak.Final = true;
ProcessBlock(output);
}
-
}
/**
@@ -776,31 +773,28 @@ namespace Org.BouncyCastle.Crypto.Digests
private void Output(ulong outputSequence, byte[] outBytes, int outOff, int outputBytes)
{
byte[] currentBytes = new byte[8];
- ThreefishEngine.WordToBytes(outputSequence, currentBytes, 0);
+ Pack.UInt64_To_LE(outputSequence, currentBytes, 0);
- // Output is a sequence of UBI invocations all of which use and preserve the pre-output
- // state
+ // Output is a sequence of UBI invocations all of which use and preserve the pre-output state
ulong[] outputWords = new ulong[chain.Length];
UbiInit(PARAM_TYPE_OUTPUT);
this.ubi.Update(currentBytes, 0, currentBytes.Length, outputWords);
ubi.DoFinal(outputWords);
- int wordsRequired = ((outputBytes + 8 - 1) / 8);
+ int wordsRequired = (outputBytes + 8 - 1) / 8;
for (int i = 0; i < wordsRequired; i++)
{
int toWrite = System.Math.Min(8, outputBytes - (i * 8));
if (toWrite == 8)
{
- ThreefishEngine.WordToBytes(outputWords[i], outBytes, outOff + (i * 8));
+ Pack.UInt64_To_LE(outputWords[i], outBytes, outOff + (i * 8));
}
else
{
- ThreefishEngine.WordToBytes(outputWords[i], currentBytes, 0);
+ Pack.UInt64_To_LE(outputWords[i], currentBytes, 0);
Array.Copy(currentBytes, 0, outBytes, outOff + (i * 8), toWrite);
}
}
}
-
}
}
-
diff --git a/crypto/src/crypto/digests/TigerDigest.cs b/crypto/src/crypto/digests/TigerDigest.cs
index ce9efdbed..a452d3f0b 100644
--- a/crypto/src/crypto/digests/TigerDigest.cs
+++ b/crypto/src/crypto/digests/TigerDigest.cs
@@ -1,6 +1,6 @@
using System;
-using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Digests
@@ -553,7 +553,7 @@ namespace Org.BouncyCastle.Crypto.Digests
//
// buffers
//
- private byte[] Buffer = new byte[8];
+ private byte[] m_buffer = new byte[8];
private int bOff;
private long[] x = new long[8];
@@ -591,18 +591,9 @@ namespace Org.BouncyCastle.Crypto.Digests
return MyByteLength;
}
- private void ProcessWord(
- byte[] b,
- int off)
+ private void ProcessWord(byte[] b, int off)
{
- x[xOff++] = ((long)(b[off + 7] & 0xff) << 56)
- | ((long)(b[off + 6] & 0xff) << 48)
- | ((long)(b[off + 5] & 0xff) << 40)
- | ((long)(b[off + 4] & 0xff) << 32)
- | ((long)(b[off + 3] & 0xff) << 24)
- | ((long)(b[off + 2] & 0xff) << 16)
- | ((long)(b[off + 1] & 0xff) << 8)
- | ((uint)(b[off + 0] & 0xff));
+ x[xOff++] = (long)Pack.LE_To_UInt64(b, off);
if (xOff == x.Length)
{
@@ -615,11 +606,11 @@ namespace Org.BouncyCastle.Crypto.Digests
public void Update(
byte input)
{
- Buffer[bOff++] = input;
+ m_buffer[bOff++] = input;
- if (bOff == Buffer.Length)
+ if (bOff == m_buffer.Length)
{
- ProcessWord(Buffer, 0);
+ ProcessWord(m_buffer, 0);
}
byteCount++;
@@ -781,21 +772,6 @@ namespace Org.BouncyCastle.Crypto.Digests
}
}
- private void UnpackWord(
- long r,
- byte[] output,
- int outOff)
- {
- output[outOff + 7] = (byte)(r >> 56);
- output[outOff + 6] = (byte)(r >> 48);
- output[outOff + 5] = (byte)(r >> 40);
- output[outOff + 4] = (byte)(r >> 32);
- output[outOff + 3] = (byte)(r >> 24);
- output[outOff + 2] = (byte)(r >> 16);
- output[outOff + 1] = (byte)(r >> 8);
- output[outOff] = (byte)r;
- }
-
private void ProcessLength(
long bitLength)
{
@@ -824,9 +800,9 @@ namespace Org.BouncyCastle.Crypto.Digests
{
Finish();
- UnpackWord(a, output, outOff);
- UnpackWord(b, output, outOff + 8);
- UnpackWord(c, output, outOff + 16);
+ Pack.UInt64_To_LE((ulong)a, output, outOff);
+ Pack.UInt64_To_LE((ulong)b, output, outOff + 8);
+ Pack.UInt64_To_LE((ulong)c, output, outOff + 16);
Reset();
@@ -849,9 +825,9 @@ namespace Org.BouncyCastle.Crypto.Digests
}
bOff = 0;
- for (int i = 0; i != Buffer.Length; i++)
+ for (int i = 0; i != m_buffer.Length; i++)
{
- Buffer[i] = 0;
+ m_buffer[i] = 0;
}
byteCount = 0;
@@ -873,11 +849,10 @@ namespace Org.BouncyCastle.Crypto.Digests
Array.Copy(t.x, 0, x, 0, t.x.Length);
xOff = t.xOff;
- Array.Copy(t.Buffer, 0, Buffer, 0, t.Buffer.Length);
+ Array.Copy(t.m_buffer, 0, m_buffer, 0, t.m_buffer.Length);
bOff = t.bOff;
byteCount = t.byteCount;
}
-
}
}
diff --git a/crypto/src/crypto/engines/AesX86Engine.cs b/crypto/src/crypto/engines/AesX86Engine.cs
index a7dcfc686..a270c2ad2 100644
--- a/crypto/src/crypto/engines/AesX86Engine.cs
+++ b/crypto/src/crypto/engines/AesX86Engine.cs
@@ -190,7 +190,7 @@ namespace Org.BouncyCastle.Crypto.Engines
return 16;
}
- public int ProcessBlock(Span<byte> input, Span<byte> output)
+ public int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
Check.DataLength(input, 16, "input buffer too short");
Check.OutputLength(output, 16, "output buffer too short");
@@ -329,13 +329,13 @@ namespace Org.BouncyCastle.Crypto.Engines
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static Vector128<byte> Load128(Span<byte> t)
+ private static Vector128<byte> Load128(ReadOnlySpan<byte> t)
{
#if NET7_0_OR_GREATER
return Vector128.Create<byte>(t);
#else
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
- return Unsafe.ReadUnaligned<Vector128<byte>>(ref t[0]);
+ return Unsafe.ReadUnaligned<Vector128<byte>>(ref Unsafe.AsRef(t[0]));
return Vector128.Create(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10], t[11], t[12],
t[13], t[14], t[15]);
@@ -343,13 +343,13 @@ namespace Org.BouncyCastle.Crypto.Engines
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static Vector64<byte> Load64(Span<byte> t)
+ private static Vector64<byte> Load64(ReadOnlySpan<byte> t)
{
#if NET7_0_OR_GREATER
return Vector64.Create<byte>(t);
#else
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector64<byte>>() == 8)
- return Unsafe.ReadUnaligned<Vector64<byte>>(ref t[0]);
+ return Unsafe.ReadUnaligned<Vector64<byte>>(ref Unsafe.AsRef(t[0]));
return Vector64.Create(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]);
#endif
@@ -369,7 +369,7 @@ namespace Org.BouncyCastle.Crypto.Engines
var u = s.AsUInt64();
Utilities.Pack.UInt64_To_LE(u.GetElement(0), t);
- Utilities.Pack.UInt64_To_LE(u.GetElement(1), t.Slice(8));
+ Utilities.Pack.UInt64_To_LE(u.GetElement(1), t[8..]);
#endif
}
}
diff --git a/crypto/src/crypto/engines/ChaCha7539Engine.cs b/crypto/src/crypto/engines/ChaCha7539Engine.cs
index 81e97478b..d1dd9755b 100644
--- a/crypto/src/crypto/engines/ChaCha7539Engine.cs
+++ b/crypto/src/crypto/engines/ChaCha7539Engine.cs
@@ -168,7 +168,8 @@ namespace Org.BouncyCastle.Crypto.Engines
#if NETCOREAPP3_0_OR_GREATER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void ImplProcessBlocks2_X86_Avx2(int rounds, uint[] state, Span<byte> input, Span<byte> output)
+ internal static void ImplProcessBlocks2_X86_Avx2(int rounds, uint[] state, ReadOnlySpan<byte> input,
+ Span<byte> output)
{
if (!Avx2.IsSupported)
throw new PlatformNotSupportedException();
@@ -244,18 +245,19 @@ namespace Org.BouncyCastle.Crypto.Engines
var n3 = Avx2.Permute2x128(v2, v3, 0x31).AsByte();
n0 = Avx2.Xor(n0, Load256_Byte(input));
- n1 = Avx2.Xor(n1, Load256_Byte(input.Slice(0x20)));
- n2 = Avx2.Xor(n2, Load256_Byte(input.Slice(0x40)));
- n3 = Avx2.Xor(n3, Load256_Byte(input.Slice(0x60)));
+ n1 = Avx2.Xor(n1, Load256_Byte(input[0x20..]));
+ n2 = Avx2.Xor(n2, Load256_Byte(input[0x40..]));
+ n3 = Avx2.Xor(n3, Load256_Byte(input[0x60..]));
Store256_Byte(ref n0, output);
- Store256_Byte(ref n1, output.Slice(0x20));
- Store256_Byte(ref n2, output.Slice(0x40));
- Store256_Byte(ref n3, output.Slice(0x60));
+ Store256_Byte(ref n1, output[0x20..]);
+ Store256_Byte(ref n2, output[0x40..]);
+ Store256_Byte(ref n3, output[0x60..]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void ImplProcessBlocks2_X86_Sse2(int rounds, uint[] state, Span<byte> input, Span<byte> output)
+ internal static void ImplProcessBlocks2_X86_Sse2(int rounds, uint[] state, ReadOnlySpan<byte> input,
+ Span<byte> output)
{
if (!Sse2.IsSupported)
throw new PlatformNotSupportedException();
@@ -319,9 +321,9 @@ namespace Org.BouncyCastle.Crypto.Engines
v3 = Sse2.Add(v3, x3);
var n0 = Load128_Byte(input);
- var n1 = Load128_Byte(input.Slice(0x10));
- var n2 = Load128_Byte(input.Slice(0x20));
- var n3 = Load128_Byte(input.Slice(0x30));
+ var n1 = Load128_Byte(input[0x10..]);
+ var n2 = Load128_Byte(input[0x20..]);
+ var n3 = Load128_Byte(input[0x30..]);
n0 = Sse2.Xor(n0, v0.AsByte());
n1 = Sse2.Xor(n1, v1.AsByte());
@@ -329,9 +331,9 @@ namespace Org.BouncyCastle.Crypto.Engines
n3 = Sse2.Xor(n3, v3.AsByte());
Store128_Byte(ref n0, output);
- Store128_Byte(ref n1, output.Slice(0x10));
- Store128_Byte(ref n2, output.Slice(0x20));
- Store128_Byte(ref n3, output.Slice(0x30));
+ Store128_Byte(ref n1, output[0x10..]);
+ Store128_Byte(ref n2, output[0x20..]);
+ Store128_Byte(ref n3, output[0x30..]);
x3 = Load128_UInt32(state.AsSpan(12));
++state[12];
@@ -383,46 +385,46 @@ namespace Org.BouncyCastle.Crypto.Engines
v2 = Sse2.Add(v2, x2);
v3 = Sse2.Add(v3, x3);
- n0 = Load128_Byte(input.Slice(0x40));
- n1 = Load128_Byte(input.Slice(0x50));
- n2 = Load128_Byte(input.Slice(0x60));
- n3 = Load128_Byte(input.Slice(0x70));
+ n0 = Load128_Byte(input[0x40..]);
+ n1 = Load128_Byte(input[0x50..]);
+ n2 = Load128_Byte(input[0x60..]);
+ n3 = Load128_Byte(input[0x70..]);
n0 = Sse2.Xor(n0, v0.AsByte());
n1 = Sse2.Xor(n1, v1.AsByte());
n2 = Sse2.Xor(n2, v2.AsByte());
n3 = Sse2.Xor(n3, v3.AsByte());
- Store128_Byte(ref n0, output.Slice(0x40));
- Store128_Byte(ref n1, output.Slice(0x50));
- Store128_Byte(ref n2, output.Slice(0x60));
- Store128_Byte(ref n3, output.Slice(0x70));
+ Store128_Byte(ref n0, output[0x40..]);
+ Store128_Byte(ref n1, output[0x50..]);
+ Store128_Byte(ref n2, output[0x60..]);
+ Store128_Byte(ref n3, output[0x70..]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static Vector128<byte> Load128_Byte(Span<byte> t)
+ private static Vector128<byte> Load128_Byte(ReadOnlySpan<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
- return Unsafe.ReadUnaligned<Vector128<byte>>(ref t[0]);
+ return Unsafe.ReadUnaligned<Vector128<byte>>(ref Unsafe.AsRef(t[0]));
return Vector128.Create(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10], t[11], t[12],
t[13], t[14], t[15]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static Vector128<uint> Load128_UInt32(Span<uint> t)
+ private static Vector128<uint> Load128_UInt32(ReadOnlySpan<uint> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<uint>>() == 16)
- return Unsafe.ReadUnaligned<Vector128<uint>>(ref Unsafe.As<uint, byte>(ref t[0]));
+ return Unsafe.ReadUnaligned<Vector128<uint>>(ref Unsafe.As<uint, byte>(ref Unsafe.AsRef(t[0])));
return Vector128.Create(t[0], t[1], t[2], t[3]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static Vector256<byte> Load256_Byte(Span<byte> t)
+ private static Vector256<byte> Load256_Byte(ReadOnlySpan<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector256<byte>>() == 32)
- return Unsafe.ReadUnaligned<Vector256<byte>>(ref t[0]);
+ return Unsafe.ReadUnaligned<Vector256<byte>>(ref Unsafe.AsRef(t[0]));
return Vector256.Create(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10], t[11], t[12],
t[13], t[14], t[15], t[16], t[17], t[18], t[19], t[20], t[21], t[22], t[23], t[24], t[25], t[26], t[27],
@@ -440,7 +442,7 @@ namespace Org.BouncyCastle.Crypto.Engines
var u = s.AsUInt64();
Pack.UInt64_To_LE(u.GetElement(0), t);
- Pack.UInt64_To_LE(u.GetElement(1), t.Slice(8));
+ Pack.UInt64_To_LE(u.GetElement(1), t[8..]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -454,9 +456,9 @@ namespace Org.BouncyCastle.Crypto.Engines
var u = s.AsUInt64();
Pack.UInt64_To_LE(u.GetElement(0), t);
- Pack.UInt64_To_LE(u.GetElement(1), t.Slice(8));
- Pack.UInt64_To_LE(u.GetElement(2), t.Slice(16));
- Pack.UInt64_To_LE(u.GetElement(3), t.Slice(24));
+ Pack.UInt64_To_LE(u.GetElement(1), t[8..]);
+ Pack.UInt64_To_LE(u.GetElement(2), t[16..]);
+ Pack.UInt64_To_LE(u.GetElement(3), t[24..]);
}
#endif
}
diff --git a/crypto/src/crypto/engines/ChaChaEngine.cs b/crypto/src/crypto/engines/ChaChaEngine.cs
index a16491ba0..646a6976c 100644
--- a/crypto/src/crypto/engines/ChaChaEngine.cs
+++ b/crypto/src/crypto/engines/ChaChaEngine.cs
@@ -213,10 +213,10 @@ namespace Org.BouncyCastle.Crypto.Engines
#if NETCOREAPP3_0_OR_GREATER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static Vector128<uint> Load128_UInt32(Span<uint> t)
+ private static Vector128<uint> Load128_UInt32(ReadOnlySpan<uint> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<uint>>() == 16)
- return Unsafe.ReadUnaligned<Vector128<uint>>(ref Unsafe.As<uint, byte>(ref t[0]));
+ return Unsafe.ReadUnaligned<Vector128<uint>>(ref Unsafe.As<uint, byte>(ref Unsafe.AsRef(t[0])));
return Vector128.Create(t[0], t[1], t[2], t[3]);
}
@@ -232,7 +232,7 @@ namespace Org.BouncyCastle.Crypto.Engines
var u = s.AsUInt64();
Pack.UInt64_To_LE(u.GetElement(0), t);
- Pack.UInt64_To_LE(u.GetElement(1), t.Slice(8));
+ Pack.UInt64_To_LE(u.GetElement(1), t[8..]);
}
#endif
}
diff --git a/crypto/src/crypto/engines/ThreefishEngine.cs b/crypto/src/crypto/engines/ThreefishEngine.cs
index eade3cc72..c5aee5395 100644
--- a/crypto/src/crypto/engines/ThreefishEngine.cs
+++ b/crypto/src/crypto/engines/ThreefishEngine.cs
@@ -135,18 +135,17 @@ namespace Org.BouncyCastle.Crypto.Engines
switch (blocksizeBits)
{
- case BLOCKSIZE_256:
+ case BLOCKSIZE_256:
cipher = new Threefish256Cipher(kw, t);
break;
- case BLOCKSIZE_512:
+ case BLOCKSIZE_512:
cipher = new Threefish512Cipher(kw, t);
break;
- case BLOCKSIZE_1024:
+ case BLOCKSIZE_1024:
cipher = new Threefish1024Cipher(kw, t);
break;
- default:
- throw new ArgumentException(
- "Invalid blocksize - Threefish is defined with block size of 256, 512, or 1024 bits");
+ default:
+ throw new ArgumentException("Invalid blocksize - Threefish is defined with block size of 256, 512, or 1024 bits");
}
}
@@ -189,10 +188,7 @@ namespace Org.BouncyCastle.Crypto.Engines
+ " bytes)");
}
keyWords = new ulong[blocksizeWords];
- for (int i = 0; i < keyWords.Length; i++)
- {
- keyWords[i] = BytesToWord(keyBytes, i * 8);
- }
+ Pack.LE_To_UInt64(keyBytes, 0, keyWords);
}
if (tweakBytes != null)
{
@@ -200,7 +196,8 @@ namespace Org.BouncyCastle.Crypto.Engines
{
throw new ArgumentException("Threefish tweak must be " + TWEAK_SIZE_BYTES + " bytes");
}
- tweakWords = new ulong[]{BytesToWord(tweakBytes, 0), BytesToWord(tweakBytes, 8)};
+ tweakWords = new ulong[2];
+ Pack.LE_To_UInt64(tweakBytes, 0, tweakWords);
}
Init(forEncryption, keyWords, tweakWords);
}
@@ -298,16 +295,9 @@ namespace Org.BouncyCastle.Crypto.Engines
throw new DataLengthException("Input buffer too short");
}
- for (int i = 0; i < blocksizeBytes; i += 8)
- {
- currentBlock[i >> 3] = BytesToWord(inBytes, inOff + i);
- }
+ Pack.LE_To_UInt64(inBytes, inOff, currentBlock);
ProcessBlock(this.currentBlock, this.currentBlock);
- for (int i = 0; i < blocksizeBytes; i += 8)
- {
- WordToBytes(this.currentBlock[i >> 3], outBytes, outOff + i);
- }
-
+ Pack.UInt64_To_LE(currentBlock, outBytes, outOff);
return blocksizeBytes;
}
@@ -347,54 +337,6 @@ namespace Org.BouncyCastle.Crypto.Engines
return blocksizeWords;
}
- /// <summary>
- /// Read a single 64 bit word from input in LSB first order.
- /// </summary>
- internal static ulong BytesToWord(byte[] bytes, int off)
- {
- if ((off + 8) > bytes.Length)
- {
- // Help the JIT avoid index checks
- throw new ArgumentException();
- }
-
- ulong word = 0;
- int index = off;
-
- word = (bytes[index++] & 0xffUL);
- word |= (bytes[index++] & 0xffUL) << 8;
- word |= (bytes[index++] & 0xffUL) << 16;
- word |= (bytes[index++] & 0xffUL) << 24;
- word |= (bytes[index++] & 0xffUL) << 32;
- word |= (bytes[index++] & 0xffUL) << 40;
- word |= (bytes[index++] & 0xffUL) << 48;
- word |= (bytes[index++] & 0xffUL) << 56;
-
- return word;
- }
-
- /// <summary>
- /// Write a 64 bit word to output in LSB first order.
- /// </summary>
- internal static void WordToBytes(ulong word, byte[] bytes, int off)
- {
- if ((off + 8) > bytes.Length)
- {
- // Help the JIT avoid index checks
- throw new ArgumentException();
- }
- int index = off;
-
- bytes[index++] = (byte)word;
- bytes[index++] = (byte)(word >> 8);
- bytes[index++] = (byte)(word >> 16);
- bytes[index++] = (byte)(word >> 24);
- bytes[index++] = (byte)(word >> 32);
- bytes[index++] = (byte)(word >> 40);
- bytes[index++] = (byte)(word >> 48);
- bytes[index++] = (byte)(word >> 56);
- }
-
/**
* Rotate left + xor part of the mix operation.
*/
diff --git a/crypto/src/crypto/operators/DefaultSignatureResult.cs b/crypto/src/crypto/operators/DefaultSignatureResult.cs
index 615f67dcb..a236838d6 100644
--- a/crypto/src/crypto/operators/DefaultSignatureResult.cs
+++ b/crypto/src/crypto/operators/DefaultSignatureResult.cs
@@ -23,5 +23,14 @@ namespace Org.BouncyCastle.Crypto.Operators
signature.CopyTo(sig, sigOff);
return signature.Length;
}
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public int Collect(Span<byte> destination)
+ {
+ byte[] result = Collect();
+ result.CopyTo(destination);
+ return result.Length;
+ }
+#endif
}
}
diff --git a/crypto/src/math/ec/custom/sec/SecT113Field.cs b/crypto/src/math/ec/custom/sec/SecT113Field.cs
index c41d9f7d7..65249562a 100644
--- a/crypto/src/math/ec/custom/sec/SecT113Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecT113Field.cs
@@ -1,5 +1,9 @@
using System;
using System.Diagnostics;
+#if NETCOREAPP3_0_OR_GREATER
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+#endif
using Org.BouncyCastle.Math.Raw;
@@ -166,6 +170,25 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
+#if NETCOREAPP3_0_OR_GREATER
+ if (Pclmulqdq.IsSupported)
+ {
+ var X01 = Vector128.Create(x[0], x[1]);
+ var Y01 = Vector128.Create(y[0], y[1]);
+
+ var Z01 = Pclmulqdq.CarrylessMultiply(X01, Y01, 0x00);
+ var Z12 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x01),
+ Pclmulqdq.CarrylessMultiply(X01, Y01, 0x10));
+ var Z23 = Pclmulqdq.CarrylessMultiply(X01, Y01, 0x11);
+
+ zz[0] = Z01.GetElement(0);
+ zz[1] = Z01.GetElement(1) ^ Z12.GetElement(0);
+ zz[2] = Z23.GetElement(0) ^ Z12.GetElement(1);
+ zz[3] = Z23.GetElement(1);
+ return;
+ }
+#endif
+
/*
* "Three-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
*/
diff --git a/crypto/src/math/ec/custom/sec/SecT131Field.cs b/crypto/src/math/ec/custom/sec/SecT131Field.cs
index 4ff5999a4..6088b264c 100644
--- a/crypto/src/math/ec/custom/sec/SecT131Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecT131Field.cs
@@ -1,5 +1,9 @@
using System;
using System.Diagnostics;
+#if NETCOREAPP3_0_OR_GREATER
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+#endif
using Org.BouncyCastle.Math.Raw;
@@ -194,6 +198,33 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
+#if NETCOREAPP3_0_OR_GREATER
+ if (Pclmulqdq.IsSupported)
+ {
+ var X01 = Vector128.Create(x[0], x[1]);
+ var X2_ = Vector128.CreateScalar(x[2]);
+ var Y01 = Vector128.Create(y[0], y[1]);
+ var Y2_ = Vector128.CreateScalar(y[2]);
+
+ var Z01 = Pclmulqdq.CarrylessMultiply(X01, Y01, 0x00);
+ var Z12 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x01),
+ Pclmulqdq.CarrylessMultiply(X01, Y01, 0x10));
+ var Z23 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y2_, 0x00),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x11),
+ Pclmulqdq.CarrylessMultiply(X2_, Y01, 0x00)));
+ var Z34 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y2_, 0x01),
+ Pclmulqdq.CarrylessMultiply(X2_, Y01, 0x10));
+ var Z4_ = Pclmulqdq.CarrylessMultiply(X2_, Y2_, 0x00);
+
+ zz[0] = Z01.GetElement(0);
+ zz[1] = Z01.GetElement(1) ^ Z12.GetElement(0);
+ zz[2] = Z23.GetElement(0) ^ Z12.GetElement(1);
+ zz[3] = Z23.GetElement(1) ^ Z34.GetElement(0);
+ zz[4] = Z4_.GetElement(0) ^ Z34.GetElement(1);
+ return;
+ }
+#endif
+
/*
* "Five-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
*/
diff --git a/crypto/src/math/ec/custom/sec/SecT163Field.cs b/crypto/src/math/ec/custom/sec/SecT163Field.cs
index 44105039d..0c616600a 100644
--- a/crypto/src/math/ec/custom/sec/SecT163Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecT163Field.cs
@@ -1,5 +1,9 @@
using System;
using System.Diagnostics;
+#if NETCOREAPP3_0_OR_GREATER
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+#endif
using Org.BouncyCastle.Math.Raw;
@@ -205,6 +209,34 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
+#if NETCOREAPP3_0_OR_GREATER
+ if (Pclmulqdq.IsSupported)
+ {
+ var X01 = Vector128.Create(x[0], x[1]);
+ var X2_ = Vector128.CreateScalar(x[2]);
+ var Y01 = Vector128.Create(y[0], y[1]);
+ var Y2_ = Vector128.CreateScalar(y[2]);
+
+ var Z01 = Pclmulqdq.CarrylessMultiply(X01, Y01, 0x00);
+ var Z12 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x01),
+ Pclmulqdq.CarrylessMultiply(X01, Y01, 0x10));
+ var Z23 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y2_, 0x00),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x11),
+ Pclmulqdq.CarrylessMultiply(X2_, Y01, 0x00)));
+ var Z34 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y2_, 0x01),
+ Pclmulqdq.CarrylessMultiply(X2_, Y01, 0x10));
+ var Z45 = Pclmulqdq.CarrylessMultiply(X2_, Y2_, 0x00);
+
+ zz[0] = Z01.GetElement(0);
+ zz[1] = Z01.GetElement(1) ^ Z12.GetElement(0);
+ zz[2] = Z23.GetElement(0) ^ Z12.GetElement(1);
+ zz[3] = Z23.GetElement(1) ^ Z34.GetElement(0);
+ zz[4] = Z45.GetElement(0) ^ Z34.GetElement(1);
+ zz[5] = Z45.GetElement(1);
+ return;
+ }
+#endif
+
/*
* "Five-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
*/
diff --git a/crypto/src/math/ec/custom/sec/SecT193Field.cs b/crypto/src/math/ec/custom/sec/SecT193Field.cs
index 59da8b000..4aa3ad5c2 100644
--- a/crypto/src/math/ec/custom/sec/SecT193Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecT193Field.cs
@@ -1,5 +1,9 @@
using System;
using System.Diagnostics;
+#if NETCOREAPP3_0_OR_GREATER
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+#endif
using Org.BouncyCastle.Math.Raw;
@@ -226,6 +230,38 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
+#if NETCOREAPP3_0_OR_GREATER
+ if (Pclmulqdq.IsSupported)
+ {
+ var X01 = Vector128.Create(x[0], x[1]);
+ var X2_ = Vector128.CreateScalar(x[2]);
+ var Y01 = Vector128.Create(y[0], y[1]);
+ var Y2_ = Vector128.CreateScalar(y[2]);
+
+ var Z01 = Pclmulqdq.CarrylessMultiply(X01, Y01, 0x00);
+ var Z12 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x01),
+ Pclmulqdq.CarrylessMultiply(X01, Y01, 0x10));
+ var Z23 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y2_, 0x00),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x11),
+ Pclmulqdq.CarrylessMultiply(X2_, Y01, 0x00)));
+ var Z34 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y2_, 0x01),
+ Pclmulqdq.CarrylessMultiply(X2_, Y01, 0x10));
+ var Z45 = Pclmulqdq.CarrylessMultiply(X2_, Y2_, 0x00);
+
+ ulong X3M = 0UL - x[3];
+ ulong Y3M = 0UL - y[3];
+
+ zz[0] = Z01.GetElement(0);
+ zz[1] = Z01.GetElement(1) ^ Z12.GetElement(0);
+ zz[2] = Z23.GetElement(0) ^ Z12.GetElement(1);
+ zz[3] = Z23.GetElement(1) ^ Z34.GetElement(0) ^ (X3M & y[0]) ^ (x[0] & Y3M);
+ zz[4] = Z45.GetElement(0) ^ Z34.GetElement(1) ^ (X3M & y[1]) ^ (x[1] & Y3M);
+ zz[5] = Z45.GetElement(1) ^ (X3M & y[2]) ^ (x[2] & Y3M);
+ zz[6] = X3M & y[3];
+ return;
+ }
+#endif
+
/*
* "Two-level seven-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
*/
diff --git a/crypto/src/math/ec/custom/sec/SecT233Field.cs b/crypto/src/math/ec/custom/sec/SecT233Field.cs
index c16a3d612..e4e291154 100644
--- a/crypto/src/math/ec/custom/sec/SecT233Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecT233Field.cs
@@ -1,5 +1,9 @@
using System;
using System.Diagnostics;
+#if NETCOREAPP3_0_OR_GREATER
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+#endif
using Org.BouncyCastle.Math.Raw;
@@ -237,6 +241,54 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
+#if NETCOREAPP3_0_OR_GREATER
+ if (Pclmulqdq.IsSupported)
+ {
+ var X01 = Vector128.Create(x[0], x[1]);
+ var X23 = Vector128.Create(x[2], x[3]);
+ var Y01 = Vector128.Create(y[0], y[1]);
+ var Y23 = Vector128.Create(y[2], y[3]);
+ var X03 = Sse2.Xor(X01, X23);
+ var Y03 = Sse2.Xor(Y01, Y23);
+
+ var Z01 = Pclmulqdq.CarrylessMultiply(X01, Y01, 0x00);
+ var Z12 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x01),
+ Pclmulqdq.CarrylessMultiply(X01, Y01, 0x10));
+ var Z23 = Pclmulqdq.CarrylessMultiply(X01, Y01, 0x11);
+
+ var Z45 = Pclmulqdq.CarrylessMultiply(X23, Y23, 0x00);
+ var Z56 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X23, Y23, 0x01),
+ Pclmulqdq.CarrylessMultiply(X23, Y23, 0x10));
+ var Z67 = Pclmulqdq.CarrylessMultiply(X23, Y23, 0x11);
+
+ var K01 = Pclmulqdq.CarrylessMultiply(X03, Y03, 0x00);
+ var K12 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X03, Y03, 0x01),
+ Pclmulqdq.CarrylessMultiply(X03, Y03, 0x10));
+ var K23 = Pclmulqdq.CarrylessMultiply(X03, Y03, 0x11);
+
+ K01 = Sse2.Xor(K01, Z01);
+ K12 = Sse2.Xor(K12, Z12);
+ K23 = Sse2.Xor(K23, Z23);
+
+ K01 = Sse2.Xor(K01, Z45);
+ K12 = Sse2.Xor(K12, Z56);
+ K23 = Sse2.Xor(K23, Z67);
+
+ Z23 = Sse2.Xor(Z23, K01);
+ Z45 = Sse2.Xor(Z45, K23);
+
+ zz[0] = Z01.GetElement(0);
+ zz[1] = Z01.GetElement(1) ^ Z12.GetElement(0);
+ zz[2] = Z23.GetElement(0) ^ Z12.GetElement(1);
+ zz[3] = Z23.GetElement(1) ^ K12.GetElement(0);
+ zz[4] = Z45.GetElement(0) ^ K12.GetElement(1);
+ zz[5] = Z45.GetElement(1) ^ Z56.GetElement(0);
+ zz[6] = Z67.GetElement(0) ^ Z56.GetElement(1);
+ zz[7] = Z67.GetElement(1);
+ return;
+ }
+#endif
+
/*
* "Two-level seven-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
*/
diff --git a/crypto/src/math/ec/custom/sec/SecT239Field.cs b/crypto/src/math/ec/custom/sec/SecT239Field.cs
index de87b18a2..a3851de16 100644
--- a/crypto/src/math/ec/custom/sec/SecT239Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecT239Field.cs
@@ -1,5 +1,9 @@
using System;
using System.Diagnostics;
+#if NETCOREAPP3_0_OR_GREATER
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+#endif
using Org.BouncyCastle.Math.Raw;
@@ -246,6 +250,54 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
+#if NETCOREAPP3_0_OR_GREATER
+ if (Pclmulqdq.IsSupported)
+ {
+ var X01 = Vector128.Create(x[0], x[1]);
+ var X23 = Vector128.Create(x[2], x[3]);
+ var Y01 = Vector128.Create(y[0], y[1]);
+ var Y23 = Vector128.Create(y[2], y[3]);
+ var X03 = Sse2.Xor(X01, X23);
+ var Y03 = Sse2.Xor(Y01, Y23);
+
+ var Z01 = Pclmulqdq.CarrylessMultiply(X01, Y01, 0x00);
+ var Z12 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x01),
+ Pclmulqdq.CarrylessMultiply(X01, Y01, 0x10));
+ var Z23 = Pclmulqdq.CarrylessMultiply(X01, Y01, 0x11);
+
+ var Z45 = Pclmulqdq.CarrylessMultiply(X23, Y23, 0x00);
+ var Z56 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X23, Y23, 0x01),
+ Pclmulqdq.CarrylessMultiply(X23, Y23, 0x10));
+ var Z67 = Pclmulqdq.CarrylessMultiply(X23, Y23, 0x11);
+
+ var K01 = Pclmulqdq.CarrylessMultiply(X03, Y03, 0x00);
+ var K12 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X03, Y03, 0x01),
+ Pclmulqdq.CarrylessMultiply(X03, Y03, 0x10));
+ var K23 = Pclmulqdq.CarrylessMultiply(X03, Y03, 0x11);
+
+ K01 = Sse2.Xor(K01, Z01);
+ K12 = Sse2.Xor(K12, Z12);
+ K23 = Sse2.Xor(K23, Z23);
+
+ K01 = Sse2.Xor(K01, Z45);
+ K12 = Sse2.Xor(K12, Z56);
+ K23 = Sse2.Xor(K23, Z67);
+
+ Z23 = Sse2.Xor(Z23, K01);
+ Z45 = Sse2.Xor(Z45, K23);
+
+ zz[0] = Z01.GetElement(0);
+ zz[1] = Z01.GetElement(1) ^ Z12.GetElement(0);
+ zz[2] = Z23.GetElement(0) ^ Z12.GetElement(1);
+ zz[3] = Z23.GetElement(1) ^ K12.GetElement(0);
+ zz[4] = Z45.GetElement(0) ^ K12.GetElement(1);
+ zz[5] = Z45.GetElement(1) ^ Z56.GetElement(0);
+ zz[6] = Z67.GetElement(0) ^ Z56.GetElement(1);
+ zz[7] = Z67.GetElement(1);
+ return;
+ }
+#endif
+
/*
* "Two-level seven-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein.
*/
diff --git a/crypto/src/math/ec/custom/sec/SecT283Field.cs b/crypto/src/math/ec/custom/sec/SecT283Field.cs
index ee5ad89c5..334986452 100644
--- a/crypto/src/math/ec/custom/sec/SecT283Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecT283Field.cs
@@ -1,5 +1,9 @@
using System;
using System.Diagnostics;
+#if NETCOREAPP3_0_OR_GREATER
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+#endif
using Org.BouncyCastle.Math.Raw;
@@ -245,6 +249,56 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
+#if NETCOREAPP3_0_OR_GREATER
+ if (Pclmulqdq.IsSupported)
+ {
+ var X01 = Vector128.Create(x[0], x[1]);
+ var X23 = Vector128.Create(x[2], x[3]);
+ var X4_ = Vector128.CreateScalar(x[4]);
+ var Y01 = Vector128.Create(y[0], y[1]);
+ var Y23 = Vector128.Create(y[2], y[3]);
+ var Y4_ = Vector128.CreateScalar(y[4]);
+
+ var Z01 = Pclmulqdq.CarrylessMultiply(X01, Y01, 0x00);
+ var Z12 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x01),
+ Pclmulqdq.CarrylessMultiply(X01, Y01, 0x10));
+ var Z23 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y23, 0x00),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y01, 0x11),
+ Pclmulqdq.CarrylessMultiply(X23, Y01, 0x00)));
+ var Z34 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y23, 0x01),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y23, 0x10),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X23, Y01, 0x01),
+ Pclmulqdq.CarrylessMultiply(X23, Y01, 0x10))));
+ var Z45 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y4_, 0x00),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y23, 0x11),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X23, Y23, 0x00),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X23, Y01, 0x11),
+ Pclmulqdq.CarrylessMultiply(X4_, Y01, 0x00)))));
+ var Z56 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X01, Y4_, 0x01),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X23, Y23, 0x01),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X23, Y23, 0x10),
+ Pclmulqdq.CarrylessMultiply(X4_, Y01, 0x10))));
+ var Z67 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X23, Y4_, 0x00),
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(X23, Y23, 0x11),
+ Pclmulqdq.CarrylessMultiply(X4_, Y23, 0x00)));
+ var Z78 = Sse2.Xor(Pclmulqdq.CarrylessMultiply(X23, Y4_, 0x01),
+ Pclmulqdq.CarrylessMultiply(X4_, Y23, 0x10));
+ var Z89 = Pclmulqdq.CarrylessMultiply(X4_, Y4_, 0x00);
+
+ zz[0] = Z01.GetElement(0);
+ zz[1] = Z01.GetElement(1) ^ Z12.GetElement(0);
+ zz[2] = Z23.GetElement(0) ^ Z12.GetElement(1);
+ zz[3] = Z23.GetElement(1) ^ Z34.GetElement(0);
+ zz[4] = Z45.GetElement(0) ^ Z34.GetElement(1);
+ zz[5] = Z45.GetElement(1) ^ Z56.GetElement(0);
+ zz[6] = Z67.GetElement(0) ^ Z56.GetElement(1);
+ zz[7] = Z67.GetElement(1) ^ Z78.GetElement(0);
+ zz[8] = Z89.GetElement(0) ^ Z78.GetElement(1);
+ zz[9] = Z89.GetElement(1);
+ return;
+ }
+#endif
+
/*
* Formula (17) from "Some New Results on Binary Polynomial Multiplication",
* Murat Cenk and M. Anwar Hasan.
diff --git a/crypto/src/math/ec/custom/sec/SecT409Field.cs b/crypto/src/math/ec/custom/sec/SecT409Field.cs
index 0fb7377f6..414a094a8 100644
--- a/crypto/src/math/ec/custom/sec/SecT409Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecT409Field.cs
@@ -1,5 +1,9 @@
using System;
using System.Diagnostics;
+#if NETCOREAPP3_0_OR_GREATER
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+#endif
using Org.BouncyCastle.Math.Raw;
@@ -344,6 +348,20 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
Debug.Assert(x >> 59 == 0);
Debug.Assert(y >> 59 == 0);
+#if NETCOREAPP3_0_OR_GREATER
+ if (Pclmulqdq.IsSupported)
+ {
+ var X = Vector128.CreateScalar(x);
+ var Y = Vector128.CreateScalar(y);
+ var Z = Pclmulqdq.CarrylessMultiply(X, Y, 0x00);
+ ulong z0 = Z.GetElement(0);
+ ulong z1 = Z.GetElement(1);
+ z[zOff ] ^= z0 & M59;
+ z[zOff + 1] ^= (z0 >> 59) ^ (z1 << 5);
+ return;
+ }
+#endif
+
//u[0] = 0;
u[1] = y;
u[2] = u[1] << 1;
diff --git a/crypto/src/math/ec/custom/sec/SecT571Field.cs b/crypto/src/math/ec/custom/sec/SecT571Field.cs
index 91a3fde9d..5a393409a 100644
--- a/crypto/src/math/ec/custom/sec/SecT571Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecT571Field.cs
@@ -175,6 +175,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
public static ulong[] PrecompMultiplicand(ulong[] x)
{
+#if NETCOREAPP3_0_OR_GREATER
+ ulong[] z = Nat576.Create64();
+ Nat576.Copy64(x, z);
+ return z;
+#else
/*
* Precompute table of all 4-bit products of x (first section)
*/
@@ -197,6 +202,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
Nat.ShiftUpBits64(len, t, 0, 4, 0UL, t, len);
return t;
+#endif
}
public static void Reduce(ulong[] xx, ulong[] z)
@@ -367,6 +373,9 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected static void ImplMultiplyPrecomp(ulong[] x, ulong[] precomp, ulong[] zz)
{
+#if NETCOREAPP3_0_OR_GREATER
+ ImplMultiply(x, precomp, zz);
+#else
uint MASK = 0xF;
/*
@@ -399,6 +408,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
Nat.ShiftUpBits64(18, zz, 0, 8, 0UL);
}
}
+#endif
}
protected static void ImplMulwAcc(ulong[] u, ulong x, ulong y, ulong[] z, int zOff)
diff --git a/crypto/src/ocsp/BasicOCSPRespGenerator.cs b/crypto/src/ocsp/BasicOCSPRespGenerator.cs
index d4ec3df80..63d577404 100644
--- a/crypto/src/ocsp/BasicOCSPRespGenerator.cs
+++ b/crypto/src/ocsp/BasicOCSPRespGenerator.cs
@@ -32,30 +32,11 @@ namespace Org.BouncyCastle.Ocsp
internal DerGeneralizedTime nextUpdate;
internal X509Extensions extensions;
- public ResponseObject(
+ internal ResponseObject(
CertificateID certId,
CertificateStatus certStatus,
DateTime thisUpdate,
- X509Extensions extensions)
- : this(certId, certStatus, new DerGeneralizedTime(thisUpdate), null, extensions)
- {
- }
-
- public ResponseObject(
- CertificateID certId,
- CertificateStatus certStatus,
- DateTime thisUpdate,
- DateTime nextUpdate,
- X509Extensions extensions)
- : this(certId, certStatus, new DerGeneralizedTime(thisUpdate), new DerGeneralizedTime(nextUpdate), extensions)
- {
- }
-
- private ResponseObject(
- CertificateID certId,
- CertificateStatus certStatus,
- DerGeneralizedTime thisUpdate,
- DerGeneralizedTime nextUpdate,
+ DateTime? nextUpdate,
X509Extensions extensions)
{
this.certId = certId;
@@ -79,8 +60,8 @@ namespace Org.BouncyCastle.Ocsp
new RevokedInfo(new DerGeneralizedTime(rs.RevocationTime), revocationReason));
}
- this.thisUpdate = thisUpdate;
- this.nextUpdate = nextUpdate;
+ this.thisUpdate = new DerGeneralizedTime(thisUpdate);
+ this.nextUpdate = nextUpdate.HasValue ? new DerGeneralizedTime(nextUpdate.Value) : null;
this.extensions = extensions;
}
@@ -119,7 +100,7 @@ namespace Org.BouncyCastle.Ocsp
CertificateID certID,
CertificateStatus certStatus)
{
- list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, null));
+ list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, null, null));
}
/**
@@ -134,7 +115,7 @@ namespace Org.BouncyCastle.Ocsp
CertificateStatus certStatus,
X509Extensions singleExtensions)
{
- list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, singleExtensions));
+ list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, null, singleExtensions));
}
/**
@@ -148,7 +129,7 @@ namespace Org.BouncyCastle.Ocsp
public void AddResponse(
CertificateID certID,
CertificateStatus certStatus,
- DateTime nextUpdate,
+ DateTime? nextUpdate,
X509Extensions singleExtensions)
{
list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, nextUpdate, singleExtensions));
@@ -167,7 +148,7 @@ namespace Org.BouncyCastle.Ocsp
CertificateID certID,
CertificateStatus certStatus,
DateTime thisUpdate,
- DateTime nextUpdate,
+ DateTime? nextUpdate,
X509Extensions singleExtensions)
{
list.Add(new ResponseObject(certID, certStatus, thisUpdate, nextUpdate, singleExtensions));
@@ -230,7 +211,7 @@ namespace Org.BouncyCastle.Ocsp
DerSequence chainSeq = null;
if (chain != null && chain.Length > 0)
{
- Asn1EncodableVector v = new Asn1EncodableVector();
+ Asn1EncodableVector v = new Asn1EncodableVector(chain.Length);
try
{
for (int i = 0; i != chain.Length; i++)
diff --git a/crypto/src/tls/AbstractTlsContext.cs b/crypto/src/tls/AbstractTlsContext.cs
index be7a67dfc..a5ac85962 100644
--- a/crypto/src/tls/AbstractTlsContext.cs
+++ b/crypto/src/tls/AbstractTlsContext.cs
@@ -170,6 +170,9 @@ namespace Org.BouncyCastle.Tls
SecurityParameters securityParameters = SecurityParameters;
+ if (ChannelBinding.tls_exporter == channelBinding)
+ return ExportKeyingMaterial("EXPORTER-Channel-Binding", TlsUtilities.EmptyBytes, 32);
+
if (TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion))
return null;
diff --git a/crypto/src/tls/ChannelBinding.cs b/crypto/src/tls/ChannelBinding.cs
index 84f8bc4df..d6e0cbe27 100644
--- a/crypto/src/tls/ChannelBinding.cs
+++ b/crypto/src/tls/ChannelBinding.cs
@@ -15,5 +15,10 @@ namespace Org.BouncyCastle.Tls
public const int tls_server_end_point = 0;
public const int tls_unique = 1;
public const int tls_unique_for_telnet = 2;
+
+ /*
+ * RFC 9266
+ */
+ public const int tls_exporter = 3;
}
}
diff --git a/crypto/test/src/tls/test/MockTlsClient.cs b/crypto/test/src/tls/test/MockTlsClient.cs
index 98898dd30..731504757 100644
--- a/crypto/test/src/tls/test/MockTlsClient.cs
+++ b/crypto/test/src/tls/test/MockTlsClient.cs
@@ -127,6 +127,9 @@ namespace Org.BouncyCastle.Tls.Tests
byte[] tlsUnique = m_context.ExportChannelBinding(ChannelBinding.tls_unique);
Console.WriteLine("Client 'tls-unique': " + ToHexString(tlsUnique));
+
+ byte[] tlsExporter = m_context.ExportChannelBinding(ChannelBinding.tls_exporter);
+ Console.WriteLine("Client 'tls-exporter': " + ToHexString(tlsExporter));
}
}
diff --git a/crypto/test/src/tls/test/MockTlsServer.cs b/crypto/test/src/tls/test/MockTlsServer.cs
index d4e885117..c4aa2c74d 100644
--- a/crypto/test/src/tls/test/MockTlsServer.cs
+++ b/crypto/test/src/tls/test/MockTlsServer.cs
@@ -155,6 +155,9 @@ namespace Org.BouncyCastle.Tls.Tests
byte[] tlsUnique = m_context.ExportChannelBinding(ChannelBinding.tls_unique);
Console.WriteLine("Server 'tls-unique': " + ToHexString(tlsUnique));
+
+ byte[] tlsExporter = m_context.ExportChannelBinding(ChannelBinding.tls_exporter);
+ Console.WriteLine("Server 'tls-exporter': " + ToHexString(tlsExporter));
}
public override void ProcessClientExtensions(IDictionary<int, byte[]> clientExtensions)
|