diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-10-04 19:17:38 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-10-04 19:17:38 +0700 |
commit | 83bc4307036193383a96e3002fb9696d66ce0f48 (patch) | |
tree | 714134b7872ece753180ceefe4de04851236e6de /crypto/src/bcpg/MPInteger.cs | |
parent | Fix warnings (diff) | |
download | BouncyCastle.NET-ed25519-83bc4307036193383a96e3002fb9696d66ce0f48.tar.xz |
Avoid some allocations around MPInteger
Diffstat (limited to 'crypto/src/bcpg/MPInteger.cs')
-rw-r--r-- | crypto/src/bcpg/MPInteger.cs | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/crypto/src/bcpg/MPInteger.cs b/crypto/src/bcpg/MPInteger.cs index 441407244..2f564b00c 100644 --- a/crypto/src/bcpg/MPInteger.cs +++ b/crypto/src/bcpg/MPInteger.cs @@ -1,59 +1,66 @@ using System; -using System.IO; using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; namespace Org.BouncyCastle.Bcpg { /// <remarks>A multiple precision integer</remarks> - public class MPInteger + public sealed class MPInteger : BcpgObject { - private readonly BigInteger val; + private readonly BigInteger m_val; - public MPInteger( - BcpgInputStream bcpgIn) + public MPInteger(BcpgInputStream bcpgIn) { if (bcpgIn == null) - throw new ArgumentNullException("bcpgIn"); + throw new ArgumentNullException(nameof(bcpgIn)); - int length = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte(); - byte[] bytes = new byte[(length + 7) / 8]; + int lengthInBits = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte(); + int lengthInBytes = (lengthInBits + 7) / 8; - bcpgIn.ReadFully(bytes); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + if (lengthInBytes <= 512) + { + Span<byte> span = stackalloc byte[lengthInBytes]; + bcpgIn.ReadFully(span); + m_val = new BigInteger(1, span); + return; + } +#endif - this.val = new BigInteger(1, bytes); + byte[] bytes = new byte[lengthInBytes]; + bcpgIn.ReadFully(bytes); + m_val = new BigInteger(1, bytes); } - public MPInteger( - BigInteger val) + public MPInteger(BigInteger val) { if (val == null) - throw new ArgumentNullException("val"); + throw new ArgumentNullException(nameof(val)); if (val.SignValue < 0) - throw new ArgumentException("Values must be positive", "val"); + throw new ArgumentException("Values must be positive", nameof(val)); - this.val = val; + m_val = val; } - public BigInteger Value + public BigInteger Value => m_val; + + public override void Encode(BcpgOutputStream bcpgOut) { - get { return val; } + bcpgOut.WriteShort((short)m_val.BitLength); + bcpgOut.Write(m_val.ToByteArrayUnsigned()); } - public override void Encode( - BcpgOutputStream bcpgOut) + internal static BigInteger ToMpiBigInteger(ECPoint point) { - bcpgOut.WriteShort((short) val.BitLength); - bcpgOut.Write(val.ToByteArrayUnsigned()); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Span<byte> encoding = stackalloc byte[point.GetEncodedLength(false)]; + point.EncodeTo(false, encoding); + return new BigInteger(1, encoding); +#else + return new BigInteger(1, point.GetEncoded(false)); +#endif } - - internal static void Encode( - BcpgOutputStream bcpgOut, - BigInteger val) - { - bcpgOut.WriteShort((short) val.BitLength); - bcpgOut.Write(val.ToByteArrayUnsigned()); - } } } |