mirror of
https://github.com/FabInfra/S22.Sasl.git
synced 2025-03-12 14:51:43 +01:00
84 lines
2.6 KiB
C#
84 lines
2.6 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
|
|
namespace S22.Sasl.Mechanisms.Srp {
|
|
/// <summary>
|
|
/// Represents a "multi-precision integer" (MPI) as is described in the
|
|
/// SRP specification (3.2 Multi-Precision Integers, p.5).
|
|
/// </summary>
|
|
/// <remarks>Multi-Precision Integers, or MPIs, are positive integers used
|
|
/// to hold large integers used in cryptographic computations.</remarks>
|
|
internal class Mpi {
|
|
/// <summary>
|
|
/// The underlying BigInteger instance used to represent this
|
|
/// "multi-precision integer".
|
|
/// </summary>
|
|
public BigInteger Value {
|
|
get;
|
|
set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new "multi-precision integer" from the specified array
|
|
/// of bytes.
|
|
/// </summary>
|
|
/// <param name="data">A big-endian sequence of bytes forming the
|
|
/// integer value of the multi-precision integer.</param>
|
|
public Mpi(byte[] data) {
|
|
byte[] b = new byte[data.Length];
|
|
Array.Copy(data.Reverse().ToArray(), b, data.Length);
|
|
ByteBuilder builder = new ByteBuilder().Append(b);
|
|
// We append a null byte to the buffer which ensures the most
|
|
// significant bit will never be set and the big integer value
|
|
// always be positive.
|
|
if (b.Last() != 0)
|
|
builder.Append(0);
|
|
Value = new BigInteger(builder.ToArray());
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new "multi-precision integer" from the specified BigInteger
|
|
/// instance.
|
|
/// </summary>
|
|
/// <param name="value">The BigInteger instance to initialize the MPI
|
|
/// with.</param>
|
|
public Mpi(BigInteger value)
|
|
: this(value.ToByteArray().Reverse().ToArray()) {
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a sequence of bytes in big-endian order forming the integer
|
|
/// value of this "multi-precision integer" instance.
|
|
/// </summary>
|
|
/// <returns>Returns a sequence of bytes in big-endian order representing
|
|
/// this "multi-precision integer" instance.</returns>
|
|
public byte[] ToBytes() {
|
|
byte[] b = Value.ToByteArray().Reverse().ToArray();
|
|
// Strip off the 0 byte.
|
|
if (b[0] == 0)
|
|
return b.Skip(1).ToArray();
|
|
return b;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serializes the "multi-precision integer" into a sequence of bytes
|
|
/// according to the requirements of the SRP specification.
|
|
/// </summary>
|
|
/// <returns>A big-endian sequence of bytes representing the integer
|
|
/// value of the MPI.</returns>
|
|
public byte[] Serialize() {
|
|
// MPI's expect a big-endian sequence of bytes forming the integer
|
|
// value, whereas BigInteger uses little-endian.
|
|
byte[] data = ToBytes();
|
|
ushort length = Convert.ToUInt16(data.Length);
|
|
|
|
return new ByteBuilder()
|
|
.Append(length, true)
|
|
.Append(data)
|
|
.ToArray();
|
|
}
|
|
}
|
|
}
|