/// <summary> /// Create a <see cref="SecureBigNumber" /> with a value /// sampled uniformly at random less than <paramref name="range"/>. /// </summary> /// <param name="range">The upper bound for the randomly generated value.</param> /// <returns> /// New <see cref="SecureBigNumber" /> instance containing /// the random value. /// </returns> public static SecureBigNumber Random(BigNumber range) { var result = new SecureBigNumber(); BigNumberHandle.SecureRandom(result.Handle, range.Handle); return(result); }
/// <inheritdoc /> public (SecureBigNumber, ECPoint) GenerateRandomElement(RandomNumberGenerator randomNumberGenerator) { using (var keyHandle = ECKeyHandle.Create()) { ECKeyHandle.SetGroup(keyHandle, Handle); // note(lumip): OpenSSL up to version 1.1.1 does not generate private keys for EC // as secure BIGNUM. Workaround by setting an empty secure private key BIGNUM before // generation. (cf. https://github.com/openssl/openssl/issues/13892) using (var privKeyTemplateHandle = BigNumberHandle.CreateSecure()) { ECKeyHandle.SetPrivateKey(keyHandle, privKeyTemplateHandle); } ECKeyHandle.GenerateKey(keyHandle); // note(lumip): ensure the workaround worked var privKeyHandle = ECKeyHandle.GetPrivateKey(keyHandle); Debug.Assert(!privKeyHandle.IsInvalid); Debug.Assert(BigNumberHandle.GetFlags(privKeyHandle).HasFlag(BigNumberFlags.Secure)); var pubKeyHandle = ECKeyHandle.GetPublicKey(keyHandle); Debug.Assert(!pubKeyHandle.IsInvalid); var point = new ECPoint(Handle, pubKeyHandle); var index = SecureBigNumber.FromRawHandle(privKeyHandle); return(index, point); } }
public void TestFromRawHandleFailsOnInvalid() { var invalidHandle = new BigNumberHandle(); Assert.That(invalidHandle.IsInvalid); Assert.Throws <ArgumentException>(() => SecureBigNumber.FromRawHandle(invalidHandle)); }
/// <summary> /// Computes the multiplicative inverse of this <see cref="BigNumber" /> /// modulo <paramref name="modulo"/> and returns the result. /// /// Precisely, computes <c>z</c> such that <c>x * z % m = 1</c>, where /// <c>x</c> is the value of this <see cref="BigNumber" /> instance /// and <c>m</c> the value of <paramref name="modulo"/>. /// </summary> /// <param name="modulo">The modulo for computing the multiplicative inverse.</param> /// <returns> /// A <see cref="BigNumber" /> instance with value<c>z</c>. /// </returns> public BigNumber ModReciprocal(BigNumber modulo) { using (var ctx = BigNumberContextHandle.CreateSecure()) { var result = new BigNumber(); BigNumberHandle.ModInverse(result.Handle, Handle, modulo.Handle, ctx); return(result); } }
public void TestFromRawHandle() { using (var handle = BigNumberHandle.Create()) { BigNumberHandle.SetWord(handle, 3); var number = BigNumber.FromRawHandle(handle); Assert.That(BigNumberHandle.Compare(number.Handle, handle) == 0); } }
/// <summary> /// Computes this <see cref="BigNumber" /> to the power /// of <paramref name="exponent"/> modulo <paramref name="modulo"/> /// and returns the result. /// /// Precisely, the returned value is <c>z = x^y % m</c>, where /// <c>x</c> is the value of this <see cref="BigNumber" /> instance, /// <c>y</c> the value of <paramref name="exponent"/> and <c>m</c> the /// value of <paramref name="modulo"/>. /// /// The computation is not secure. For a secure variant see /// <see cref="BigNumber.ModExp(SecureBigNumber, BigNumber)" />. /// </summary> /// <param name="exponent">The exponent which to raise this <see cref="BigNumber" /> to.</param> /// <param name="modulo">The modulo for the exponentiation.</param> /// <returns> /// A <see cref="BigNumber" /> instance with value<c>z</c>. /// </returns> public BigNumber ModExp(BigNumber exponent, BigNumber modulo) { using (var ctx = BigNumberContextHandle.CreateSecure()) { var result = new BigNumber(); BigNumberHandle.ModExp(result.Handle, Handle, exponent.Handle, modulo.Handle, ctx); return(result); } }
/// <summary> /// Multiplies this <see cref="BigNumber" /> with <paramref name="other"/> /// modulo <paramref name="modulo"/> and returns the result. /// /// Precisely, the returned value is <c>z = x * y % m</c>, where /// <c>x</c> is the value of this <see cref="BigNumber" /> instance, /// <c>y</c> the value of <paramref name="other"/> and <c>m</c> the /// value of <paramref name="modulo"/>. /// </summary> /// <param name="other">The number with which to multiply.</param> /// <param name="modulo">The modulo for the multiplication.</param> /// <returns> /// A <see cref="BigNumber" /> instance with value<c>z</c>. /// </returns> public BigNumber ModMul(BigNumber other, BigNumber modulo) { using (var ctx = BigNumberContextHandle.Create()) { var result = new BigNumber(); BigNumberHandle.ModMul(result.Handle, Handle, other.Handle, modulo.Handle, ctx); return(result); } }
/// <inheritdoc /> public bool IsPotentialElement(BigNumber element) { // implementation-specific checks if (element.Equals(BigNumber.Zero) || BigNumberHandle.Compare(element.Handle, _modulo.Handle) >= 0) { return(false); } return(true); }
/// <summary> /// Creates a <see cref="SecureBigNumber" /> instance from a valid <see cref="BigNumberHandle" /> /// to a secure OpenSSL <c>BIGNUM</c> structure. A copy of the pointed to <c>BIGNUM</c> structure /// is made for the created instance. /// </summary> /// <param name="bigNumberHandle"> /// A handle to a raw OpenSSL <c>BIGNUM</c> structure with which to initialize the new <see cref="SecureBigNumber" />. /// </param> /// <returns> /// A new <see cref="SecureBigNumber" /> instance with the same value as /// referred to by <paramref name="bigNumberHandle"/>. /// </returns> internal static SecureBigNumber FromRawHandle(BigNumberHandle bigNumberHandle) { if (bigNumberHandle.IsInvalid) { throw new ArgumentException("The provided handle is invalid.", nameof(bigNumberHandle)); } var bn = new SecureBigNumber(); BigNumberHandle.Copy(bn.Handle, bigNumberHandle); return(bn); }
public void TestFromBigNumber() { var rawValue = 0x548f07; var number = SecureBigNumber.FromBigNumber(new BigNumber(rawValue)); using (var expectedHandle = BigNumberHandle.Create()) { BigNumberHandle.SetWord(expectedHandle, (ulong)rawValue); Assert.That(BigNumberHandle.Compare(number.Handle, expectedHandle) == 0); } }
public void TestIntegerConstructor() { var rawValue = 869235; var number = new BigNumber(rawValue); using (var expectedHandle = BigNumberHandle.Create()) { BigNumberHandle.SetWord(expectedHandle, (ulong)rawValue); Assert.That(BigNumberHandle.Compare(number.Handle, expectedHandle) == 0); } }
/// <inheritdoc /> public override bool Equals(object?obj) { var other = obj as BigNumber; if (other == null) { return(false); } return(BigNumberHandle.Compare(this.Handle, other.Handle) == 0); }
public void TestConstructor() { var number = new SecureBigNumber(); Assert.That(BigNumberHandle.GetFlags( number.Handle, BigNumberFlags.Secure).HasFlag(BigNumberFlags.Secure) ); Assert.That(BigNumberHandle.GetFlags( number.Handle, BigNumberFlags.ConstantTime).HasFlag(BigNumberFlags.ConstantTime) ); Assert.That(!number.Handle.IsInvalid); Assert.That(!number.Handle.IsClosed); }
public void TestFromRawHandle() { using (var handle = BigNumberHandle.Create()) { BigNumberHandle.SetWord(handle, 3); var number = SecureBigNumber.FromRawHandle(handle); Assert.That(BigNumberHandle.Compare(number.Handle, handle) == 0); Assert.That(BigNumberHandle.GetFlags( number.Handle, BigNumberFlags.Secure).HasFlag(BigNumberFlags.Secure) ); Assert.That(BigNumberHandle.GetFlags( number.Handle, BigNumberFlags.ConstantTime).HasFlag(BigNumberFlags.ConstantTime) ); } }
/// <summary> /// Creates a <see cref="BigNumber" /> instance from a valid <see cref="BigNumberHandle" /> /// to an OpenSSL <c>BIGNUM</c> structure. A copy of the pointed to <c>BIGNUM</c> structure /// is made for the created instance. /// </summary> /// <param name="bigNumberHandle"> /// A handle to a raw OpenSSL <c>BIGNUM</c> structure with which to initialize the new <see cref="BigNumber" />. /// </param> /// <returns> /// A new <see cref="BigNumber" /> instance with the same value as /// referred to by <paramref name="bigNumberHandle"/>. /// </returns> internal static BigNumber FromRawHandle(BigNumberHandle bigNumberHandle) { if (bigNumberHandle.IsInvalid) { throw new ArgumentException("The provided handle is invalid.", nameof(bigNumberHandle)); } if (BigNumberHandle.GetFlags(bigNumberHandle).HasFlag(BigNumberFlags.Secure)) { throw new ArgumentException( "The provided handle is that of a secure big number. Converting secure into regular big numbers is not supported.", nameof(bigNumberHandle) ); } var bn = new BigNumber(); BigNumberHandle.Copy(bn.Handle, bigNumberHandle); return(bn); }
public void TestRandom() { var NumTests = 100; var range = new BigNumber(0x869375a76); for (var k = 0; k < NumTests; k++) { using (var number = SecureBigNumber.Random(range)) { Assert.That(BigNumberHandle.GetFlags( number.Handle, BigNumberFlags.Secure).HasFlag(BigNumberFlags.Secure) ); Assert.That(BigNumberHandle.GetFlags( number.Handle, BigNumberFlags.ConstantTime).HasFlag(BigNumberFlags.ConstantTime) ); Assert.That(BigNumberHandle.Compare(number.Handle, range.Handle) < 0); } } }
/// <summary> /// Creates a new uninitialized <see cref="SecureBigNumber" /> instance. /// </summary> public SecureBigNumber() { Handle = BigNumberHandle.CreateSecure(); }
/// <summary> /// Internal constructor for a given valid <see cref="BigNumberHandle" />. /// </summary> private BigNumber(BigNumberHandle handle) { Debug.Assert(!handle.IsInvalid, "BigNumberBase received an invalid handle internally!"); Handle = handle; }
/// <summary> /// Creates an unintialized <see cref="BigNumber" /> instance. /// </summary> public BigNumber() : this(BigNumberHandle.Create()) { }
/// <summary> /// Creates a <see cref="BigNumber" /> instance from a /// little endian byte encoding. /// </summary> public BigNumber(byte[] buffer) : this() { BigNumberHandle.FromBytes(buffer, Handle); }
public void TestFromRawHandleFailsWithSecure() { var secureHandle = BigNumberHandle.CreateSecure(); Assert.Throws <ArgumentException>(() => BigNumber.FromRawHandle(secureHandle)); }
/// <summary> /// Returns a byte encoding of the <see cref="BigNumber" /> in little endian encoding. /// /// Optionally adds padding with zeros at then end of the byte encoding, /// the length of which is specified by the <paramref name="backPadding"/> parameter. /// </summary> /// <param name="backPadding">How many bytes of zero to add at the end of the byte encoding.</param> /// <returns>Byte buffer containing the byte encoding of the number.</returns> public byte[] ToBytes(uint backPadding = 0) { byte[] buffer = new byte[Length.InBytes + backPadding]; BigNumberHandle.ToBytes(Handle, buffer); return(buffer); }
/// <summary> /// Creates a <see cref="BigNumber" /> instance from a /// <see cref="ulong" /> number. /// </summary> public BigNumber(ulong x) : this() { BigNumberHandle.SetWord(Handle, x); }