diff options
-rw-r--r-- | crypto/src/crypto/signers/IDsaEncoding.cs | 6 | ||||
-rw-r--r-- | crypto/src/crypto/signers/PlainDsaEncoding.cs | 29 | ||||
-rw-r--r-- | crypto/src/crypto/signers/StandardDsaEncoding.cs | 17 |
3 files changed, 52 insertions, 0 deletions
diff --git a/crypto/src/crypto/signers/IDsaEncoding.cs b/crypto/src/crypto/signers/IDsaEncoding.cs index cccc4f937..8960445cf 100644 --- a/crypto/src/crypto/signers/IDsaEncoding.cs +++ b/crypto/src/crypto/signers/IDsaEncoding.cs @@ -21,5 +21,11 @@ namespace Org.BouncyCastle.Crypto.Signers /// <param name="s">The s value of a DSA signature.</param> /// <returns>An encoding of the DSA signature given by the provided (r, s) pair.</returns> byte[] Encode(BigInteger n, BigInteger r, BigInteger s); + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + int Encode(BigInteger n, BigInteger r, BigInteger s, Span<byte> output); +#endif + + int GetMaxEncodingSize(BigInteger n); } } diff --git a/crypto/src/crypto/signers/PlainDsaEncoding.cs b/crypto/src/crypto/signers/PlainDsaEncoding.cs index 2e1f65a1f..1563800ef 100644 --- a/crypto/src/crypto/signers/PlainDsaEncoding.cs +++ b/crypto/src/crypto/signers/PlainDsaEncoding.cs @@ -31,6 +31,22 @@ namespace Org.BouncyCastle.Crypto.Signers return result; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public virtual int Encode(BigInteger n, BigInteger r, BigInteger s, Span<byte> output) + { + int valueLength = BigIntegers.GetUnsignedByteLength(n); + int resultLength = valueLength * 2; + EncodeValue(n, r, output[..valueLength]); + EncodeValue(n, s, output[valueLength..resultLength]); + return resultLength; + } +#endif + + public virtual int GetMaxEncodingSize(BigInteger n) + { + return BigIntegers.GetUnsignedByteLength(n) * 2; + } + protected virtual BigInteger CheckValue(BigInteger n, BigInteger x) { if (x.SignValue < 0 || x.CompareTo(n) >= 0) @@ -54,5 +70,18 @@ namespace Org.BouncyCastle.Crypto.Signers Arrays.Fill(buf, off, off + pos, 0); Array.Copy(bs, bsOff, buf, off + pos, bsLen); } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + protected virtual void EncodeValue(BigInteger n, BigInteger x, Span<byte> buffer) + { + byte[] bs = CheckValue(n, x).ToByteArrayUnsigned(); + int bsOff = System.Math.Max(0, bs.Length - buffer.Length); + int bsLen = bs.Length - bsOff; + + int pos = buffer.Length - bsLen; + buffer[..pos].Fill(0x00); + bs.AsSpan(bsOff, bsLen).CopyTo(buffer[pos..]); + } +#endif } } diff --git a/crypto/src/crypto/signers/StandardDsaEncoding.cs b/crypto/src/crypto/signers/StandardDsaEncoding.cs index 75ac08411..77cd6124d 100644 --- a/crypto/src/crypto/signers/StandardDsaEncoding.cs +++ b/crypto/src/crypto/signers/StandardDsaEncoding.cs @@ -35,6 +35,23 @@ namespace Org.BouncyCastle.Crypto.Signers ).GetEncoded(Asn1Encodable.Der); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public virtual int Encode(BigInteger n, BigInteger r, BigInteger s, Span<byte> output) + { + byte[] encoding = Encode(n, r, s); + encoding.CopyTo(output); + return encoding.Length; + } +#endif + + public virtual int GetMaxEncodingSize(BigInteger n) + { + int encodingLength = BigIntegers.GetByteLength(n); + int derIntegerLength = Asn1OutputStream.GetLengthOfDL(encodingLength) + encodingLength; + int seqContentsLength = 2 * derIntegerLength; + return Asn1OutputStream.GetLengthOfDL(seqContentsLength) + seqContentsLength; + } + protected virtual BigInteger CheckValue(BigInteger n, BigInteger x) { if (x.SignValue < 0 || (null != n && x.CompareTo(n) >= 0)) |