diff options
Diffstat (limited to 'crypto/src')
250 files changed, 7325 insertions, 3901 deletions
diff --git a/crypto/src/AssemblyInfo.cs b/crypto/src/AssemblyInfo.cs index f89d58fbd..dfc22336a 100644 --- a/crypto/src/AssemblyInfo.cs +++ b/crypto/src/AssemblyInfo.cs @@ -3,29 +3,3 @@ using System.Runtime.InteropServices; [assembly: CLSCompliant(true)] [assembly: ComVisible(false)] - -// Start with no permissions -//[assembly: PermissionSet(SecurityAction.RequestOptional, Unrestricted=false)] -//...and explicitly add those we need - -// see Org.BouncyCastle.Crypto.Encodings.Pkcs1Encoding.StrictLengthEnabledProperty -//[assembly: EnvironmentPermission(SecurityAction.RequestOptional, Read="Org.BouncyCastle.Pkcs1.Strict")] - -#if !(NET45_OR_GREATER || NETSTANDARD1_0_OR_GREATER) -namespace System.Reflection -{ - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] - internal sealed class AssemblyMetadataAttribute : Attribute - { - public AssemblyMetadataAttribute(string key, string value) - { - Key = key; - Value = value; - } - - public string Key { get; } - - public string Value { get; } - } -} -#endif diff --git a/crypto/src/BouncyCastle.Crypto.csproj b/crypto/src/BouncyCastle.Crypto.csproj index 9786cd985..44925aebd 100644 --- a/crypto/src/BouncyCastle.Crypto.csproj +++ b/crypto/src/BouncyCastle.Crypto.csproj @@ -5,13 +5,32 @@ <RootNamespace>Org.BouncyCastle</RootNamespace> <AssemblyOriginatorKeyFile>..\..\BouncyCastle.snk</AssemblyOriginatorKeyFile> <SignAssembly>true</SignAssembly> + <NoWarn>1591</NoWarn> + + <Authors /> + <Company>Legion of the Bouncy Castle Inc.</Company> + <Copyright>Copyright © Legion of the Bouncy Castle Inc. 2000-2022</Copyright> + <DebugType>embedded</DebugType> + <Description>BouncyCastle.NET is a popular cryptography library for .NET</Description> + <EmbedUntrackedSources>true</EmbedUntrackedSources> + <PackageIconUrl>https://www.bouncycastle.org/images/csharp_logo.gif</PackageIconUrl> + <PackageId>BouncyCastle.Cryptography</PackageId> + <PackageLicenseFile>License.html</PackageLicenseFile> + <PackageProjectUrl>https://www.bouncycastle.org/csharp/</PackageProjectUrl> + <PackageReleaseNotes>https://www.bouncycastle.org/csharp/</PackageReleaseNotes> + <PackageTags>bouncycastle cryptography dtls encryption security tls</PackageTags> + <Product>BouncyCastle.NET</Product> + <!--<PublishRepositoryUrl>true</PublishRepositoryUrl>--> + <RepositoryType>git</RepositoryType> + <RepositoryUrl>https://github.com/bcgit/bc-csharp</RepositoryUrl> + <Title>BouncyCastle.NET Cryptography</Title> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> + <PropertyGroup Condition="'$(Configuration)'=='Debug'"> <DefineConstants>DEBUG;TRACE</DefineConstants> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> + <PropertyGroup Condition="'$(Configuration)'=='Release'"> <DefineConstants /> <GenerateDocumentationFile>true</GenerateDocumentationFile> </PropertyGroup> @@ -20,12 +39,23 @@ <None Remove="**\*.properties" /> <EmbeddedResource Include="**\*.properties" /> </ItemGroup> + + <ItemGroup> + <None Include="..\License.html"> + <Pack>True</Pack> + <PackagePath>\</PackagePath> + </None> + </ItemGroup> <ItemGroup> + <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + </PackageReference> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> - <PackageReference Include="Nerdbank.GitVersioning" Version="3.5.113"> + <PackageReference Include="Nerdbank.GitVersioning" Version="3.5.119"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> diff --git a/crypto/src/asn1/Asn1GeneralizedTime.cs b/crypto/src/asn1/Asn1GeneralizedTime.cs new file mode 100644 index 000000000..e844c8ca2 --- /dev/null +++ b/crypto/src/asn1/Asn1GeneralizedTime.cs @@ -0,0 +1,439 @@ +using System; +using System.Globalization; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Base class representing the ASN.1 GeneralizedTime type. + * <p> + * The main difference between these and UTC time is a 4 digit year. + * </p> + * <p> + * One second resolution date+time on UTC timezone (Z) + * with 4 digit year (valid from 0001 to 9999). + * </p><p> + * Timestamp format is: yyyymmddHHMMSS'Z' + * </p><p> + * <h2>X.690</h2> + * This is what is called "restricted string", + * and it uses ASCII characters to encode digits and supplemental data. + * + * <h3>11: Restrictions on BER employed by both CER and DER</h3> + * <h4>11.7 GeneralizedTime </h4> + * <p> + * <b>11.7.1</b> The encoding shall terminate with a "Z", + * as described in the ITU-T Rec. X.680 | ISO/IEC 8824-1 clause on + * GeneralizedTime. + * </p><p> + * <b>11.7.2</b> The seconds element shall always be present. + * </p> + * <p> + * <b>11.7.3</b> The fractional-seconds elements, if present, + * shall omit all trailing zeros; if the elements correspond to 0, + * they shall be wholly omitted, and the decimal point element also + * shall be omitted. + */ + public class Asn1GeneralizedTime + : Asn1Object + { + internal class Meta : Asn1UniversalType + { + internal static readonly Asn1UniversalType Instance = new Meta(); + + private Meta() : base(typeof(Asn1GeneralizedTime), Asn1Tags.GeneralizedTime) { } + + internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString) + { + return CreatePrimitive(octetString.GetOctets()); + } + } + + public static Asn1GeneralizedTime GetInstance(object obj) + { + if (obj == null) + return null; + + if (obj is Asn1GeneralizedTime asn1GeneralizedTime) + return asn1GeneralizedTime; + + if (obj is IAsn1Convertible asn1Convertible) + { + Asn1Object asn1Object = asn1Convertible.ToAsn1Object(); + if (asn1Object is Asn1GeneralizedTime converted) + return converted; + } + else if (obj is byte[] bytes) + { + try + { + return (Asn1GeneralizedTime)Meta.Instance.FromByteArray(bytes); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct generalized time from byte[]: " + e.Message); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), nameof(obj)); + } + + public static Asn1GeneralizedTime GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return (Asn1GeneralizedTime)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit); + } + + internal readonly byte[] m_contents; + + public Asn1GeneralizedTime(string time) + { + m_contents = Strings.ToByteArray(time); + + try + { + ToDateTime(); + } + catch (FormatException e) + { + throw new ArgumentException("invalid date string: " + e.Message); + } + } + + public Asn1GeneralizedTime(DateTime time) + { + DateTime utc = time.ToUniversalTime(); + var formatStr = @"yyyyMMddHHmmss\Z"; + var formatProvider = DateTimeFormatInfo.InvariantInfo; + string utcString = utc.ToString(formatStr, formatProvider); + m_contents = Strings.ToByteArray(utcString); + } + + // TODO Custom locale constructor? + //public Asn1GeneralizedTime(DateTime time, Locale locale) + //{ + // SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss\Z", locale); + + // dateF.setTimeZone(new SimpleTimeZone(0, "Z")); + + // this.contents = Strings.toByteArray(dateF.format(time)); + //} + + internal Asn1GeneralizedTime(byte[] bytes) + { + if (bytes == null) + throw new ArgumentNullException(nameof(bytes)); + if (bytes.Length < 4) + throw new ArgumentException("GeneralizedTime string too short", nameof(bytes)); + + m_contents = bytes; + + if (!(IsDigit(0) && IsDigit(1) && IsDigit(2) && IsDigit(3))) + throw new ArgumentException("illegal characters in GeneralizedTime string", nameof(bytes)); + } + + public string TimeString => Strings.FromByteArray(m_contents); + + public string GetTime() + { + string stime = Strings.FromByteArray(m_contents); + + // + // standardise the format. + // + if (stime[stime.Length - 1] == 'Z') + return stime.Substring(0, stime.Length - 1) + "GMT+00:00"; + + int signPos = stime.Length - 6; + char sign = stime[signPos]; + if ((sign == '-' || sign == '+') && stime.IndexOf("GMT") == signPos - 3) + { + // already a GMT string! + return stime; + } + + signPos = stime.Length - 5; + sign = stime[signPos]; + if (sign == '-' || sign == '+') + { + return stime.Substring(0, signPos) + + "GMT" + + stime.Substring(signPos, 3) + + ":" + + stime.Substring(signPos + 3); + } + + signPos = stime.Length - 3; + sign = stime[signPos]; + if (sign == '-' || sign == '+') + { + return stime.Substring(0, signPos) + + "GMT" + + stime.Substring(signPos) + + ":00"; + } + + return stime + CalculateGmtOffset(stime); + } + + private string CalculateGmtOffset(string stime) + { + TimeZoneInfo timeZone = TimeZoneInfo.Local; + TimeSpan offset = timeZone.BaseUtcOffset; + + string sign = "+"; + if (offset.CompareTo(TimeSpan.Zero) < 0) + { + sign = "-"; + offset = offset.Duration(); + } + + int hours = offset.Hours; + int minutes = offset.Minutes; + + try + { + if (timeZone.SupportsDaylightSavingTime) + { + string d = stime + "GMT" + sign + Convert(hours) + ":" + Convert(minutes); + string formatStr = CalculateGmtFormatString(d); + + DateTime dateTime = ParseDateString(d, formatStr, makeUniversal: true); + + if (timeZone.IsDaylightSavingTime(dateTime)) + { + hours += sign.Equals("+") ? 1 : -1; + } + } + } + catch (Exception) + { + // we'll do our best and ignore daylight savings + } + + return "GMT" + sign + Convert(hours) + ":" + Convert(minutes); + } + + private string CalculateGmtFormatString(string d) + { + if (HasFractionalSeconds()) + { + int fCount = Platform.IndexOf(d, "GMT") - 1 - d.IndexOf('.'); + return @"yyyyMMddHHmmss." + FString(fCount) + @"'GMT'zzz"; + } + + if (HasSeconds()) + return @"yyyyMMddHHmmss'GMT'zzz"; + + if (HasMinutes()) + return @"yyyyMMddHHmm'GMT'zzz"; + + return @"yyyyMMddHH'GMT'zzz"; + } + + private string Convert(int time) + { + if (time < 10) + return "0" + time; + + return time.ToString(); + } + + public DateTime ToDateTime() + { + string formatStr; + string stime = Strings.FromByteArray(m_contents); + string d = stime; + bool makeUniversal = false; + + if (Platform.EndsWith(stime, "Z")) + { + if (HasFractionalSeconds()) + { + int fCount = d.Length - d.IndexOf('.') - 2; + formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"\Z"; + } + else if (HasSeconds()) + { + formatStr = @"yyyyMMddHHmmss\Z"; + } + else if (HasMinutes()) + { + formatStr = @"yyyyMMddHHmm\Z"; + } + else + { + formatStr = @"yyyyMMddHH\Z"; + } + } + else if (stime.IndexOf('-') > 0 || stime.IndexOf('+') > 0) + { + d = GetTime(); + formatStr = CalculateGmtFormatString(d); + makeUniversal = true; + } + else + { + if (HasFractionalSeconds()) + { + int fCount = d.Length - 1 - d.IndexOf('.'); + formatStr = @"yyyyMMddHHmmss." + FString(fCount); + } + else if (HasSeconds()) + { + formatStr = @"yyyyMMddHHmmss"; + } + else if (HasMinutes()) + { + formatStr = @"yyyyMMddHHmm"; + } + else + { + formatStr = @"yyyyMMddHH"; + } + } + + // TODO Epoch adjustment? + //return DateUtil.epochAdjust(dateF.parse(d)); + return ParseDateString(d, formatStr, makeUniversal); + } + + protected bool HasFractionalSeconds() + { + return m_contents.Length > 14 && m_contents[14] == '.'; + } + + protected bool HasSeconds() + { + return IsDigit(12) && IsDigit(13); + } + + protected bool HasMinutes() + { + return IsDigit(10) && IsDigit(11); + } + + private bool IsDigit(int pos) + { + return m_contents.Length > pos && m_contents[pos] >= '0' && m_contents[pos] <= '9'; + } + + internal override IAsn1Encoding GetEncoding(int encoding) + { + if (Asn1OutputStream.EncodingDer == encoding) + return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, GetDerTime()); + + return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, m_contents); + } + + internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo) + { + if (Asn1OutputStream.EncodingDer == encoding) + return new PrimitiveEncoding(tagClass, tagNo, GetDerTime()); + + return new PrimitiveEncoding(tagClass, tagNo, m_contents); + } + + protected override bool Asn1Equals(Asn1Object asn1Object) + { + if (!(asn1Object is Asn1GeneralizedTime that)) + return false; + + return Arrays.AreEqual(m_contents, that.m_contents); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(m_contents); + } + + internal static Asn1GeneralizedTime CreatePrimitive(byte[] contents) + { + return new Asn1GeneralizedTime(contents); + } + + internal byte[] GetDerTime() + { + if (m_contents[m_contents.Length - 1] != 'Z') + { + return m_contents; // TODO: is there a better way? + } + + if (!HasMinutes()) + { + byte[] derTime = new byte[m_contents.Length + 4]; + + Array.Copy(m_contents, 0, derTime, 0, m_contents.Length - 1); + Array.Copy(Strings.ToByteArray("0000Z"), 0, derTime, m_contents.Length - 1, 5); + + return derTime; + } + else if (!HasSeconds()) + { + byte[] derTime = new byte[m_contents.Length + 2]; + + Array.Copy(m_contents, 0, derTime, 0, m_contents.Length - 1); + Array.Copy(Strings.ToByteArray("00Z"), 0, derTime, m_contents.Length - 1, 3); + + return derTime; + } + else if (HasFractionalSeconds()) + { + int ind = m_contents.Length - 2; + while (ind > 0 && m_contents[ind] == '0') + { + ind--; + } + + if (m_contents[ind] == '.') + { + byte[] derTime = new byte[ind + 1]; + + Array.Copy(m_contents, 0, derTime, 0, ind); + derTime[ind] = (byte)'Z'; + + return derTime; + } + else + { + byte[] derTime = new byte[ind + 2]; + + Array.Copy(m_contents, 0, derTime, 0, ind + 1); + derTime[ind + 1] = (byte)'Z'; + + return derTime; + } + } + else + { + return m_contents; + } + } + + private static string FString(int count) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < count; ++i) + { + sb.Append('f'); + } + return sb.ToString(); + } + + private static DateTime ParseDateString(string s, string format, bool makeUniversal) + { + DateTimeStyles dateTimeStyles = DateTimeStyles.None; + if (Platform.EndsWith(format, "Z")) + { + dateTimeStyles |= DateTimeStyles.AdjustToUniversal; + dateTimeStyles |= DateTimeStyles.AssumeUniversal; + } + + DateTime dt = DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo, dateTimeStyles); + + return makeUniversal ? dt.ToUniversalTime() : dt; + } + } +} diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs index aa91cdf62..0e772010f 100644 --- a/crypto/src/asn1/Asn1InputStream.cs +++ b/crypto/src/asn1/Asn1InputStream.cs @@ -426,7 +426,7 @@ namespace Org.BouncyCastle.Asn1 case Asn1Tags.BitString: return DerBitString.CreatePrimitive(bytes); case Asn1Tags.GeneralizedTime: - return DerGeneralizedTime.CreatePrimitive(bytes); + return Asn1GeneralizedTime.CreatePrimitive(bytes); case Asn1Tags.GeneralString: return DerGeneralString.CreatePrimitive(bytes); case Asn1Tags.GraphicString: @@ -452,7 +452,7 @@ namespace Org.BouncyCastle.Asn1 case Asn1Tags.UniversalString: return DerUniversalString.CreatePrimitive(bytes); case Asn1Tags.UtcTime: - return DerUtcTime.CreatePrimitive(bytes); + return Asn1UtcTime.CreatePrimitive(bytes); case Asn1Tags.Utf8String: return DerUtf8String.CreatePrimitive(bytes); case Asn1Tags.VideotexString: diff --git a/crypto/src/asn1/Asn1UniversalTypes.cs b/crypto/src/asn1/Asn1UniversalTypes.cs index 214918bcd..f5b5d0498 100644 --- a/crypto/src/asn1/Asn1UniversalTypes.cs +++ b/crypto/src/asn1/Asn1UniversalTypes.cs @@ -49,9 +49,9 @@ namespace Org.BouncyCastle.Asn1 case Asn1Tags.IA5String: // [UNIVERSAL 22] IMPLICIT OCTET STRING (encode as if) return DerIA5String.Meta.Instance; case Asn1Tags.UtcTime: // [UNIVERSAL 23] IMPLICIT VisibleString (restricted values) - return DerUtcTime.Meta.Instance; + return Asn1UtcTime.Meta.Instance; case Asn1Tags.GeneralizedTime: // [UNIVERSAL 24] IMPLICIT VisibleString (restricted values) - return DerGeneralizedTime.Meta.Instance; + return Asn1GeneralizedTime.Meta.Instance; case Asn1Tags.GraphicString: // [UNIVERSAL 25] IMPLICIT OCTET STRING (encode as if) return DerGraphicString.Meta.Instance; case Asn1Tags.VisibleString: // [UNIVERSAL 26] IMPLICIT OCTET STRING (encode as if) diff --git a/crypto/src/asn1/Asn1UtcTime.cs b/crypto/src/asn1/Asn1UtcTime.cs new file mode 100644 index 000000000..05de430c4 --- /dev/null +++ b/crypto/src/asn1/Asn1UtcTime.cs @@ -0,0 +1,264 @@ +using System; +using System.Globalization; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * UTC time object. + */ + public class Asn1UtcTime + : Asn1Object + { + internal class Meta : Asn1UniversalType + { + internal static readonly Asn1UniversalType Instance = new Meta(); + + private Meta() : base(typeof(Asn1UtcTime), Asn1Tags.UtcTime) {} + + internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString) + { + return CreatePrimitive(octetString.GetOctets()); + } + } + + /** + * return a UTC Time from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static Asn1UtcTime GetInstance(object obj) + { + if (obj == null) + return null; + + if (obj is Asn1UtcTime asn1UtcTime) + return asn1UtcTime; + + if (obj is IAsn1Convertible asn1Convertible) + { + Asn1Object asn1Object = asn1Convertible.ToAsn1Object(); + if (asn1Object is Asn1UtcTime converted) + return converted; + } + else if (obj is byte[] bytes) + { + try + { + return (Asn1UtcTime)Meta.Instance.FromByteArray(bytes); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct UTC time from byte[]: " + e.Message); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return a UTC Time from a tagged object. + * + * @param taggedObject the tagged object holding the object we want + * @param declaredExplicit true if the object is meant to be explicitly tagged false otherwise. + * @exception ArgumentException if the tagged object cannot be converted. + */ + public static Asn1UtcTime GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return (Asn1UtcTime)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit); + } + + private readonly string time; + + /** + * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were + * never encoded. When you're creating one of these objects from scratch, that's + * what you want to use, otherwise we'll try to deal with whatever Gets read from + * the input stream... (this is why the input format is different from the GetTime() + * method output). + * <p> + * @param time the time string.</p> + */ + public Asn1UtcTime(string time) + { + if (time == null) + throw new ArgumentNullException("time"); + + this.time = time; + + try + { + ToDateTime(); + } + catch (FormatException e) + { + throw new ArgumentException("invalid date string: " + e.Message); + } + } + + /** + * base constructor from a DateTime object + */ + public Asn1UtcTime(DateTime time) + { + this.time = time.ToUniversalTime().ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; + } + + internal Asn1UtcTime(byte[] contents) + { + // + // explicitly convert to characters + // + this.time = Strings.FromAsciiByteArray(contents); + } + + /** + * return the time as a date based on whatever a 2 digit year will return. For + * standardised processing use ToAdjustedDateTime(). + * + * @return the resulting date + * @exception ParseException if the date string cannot be parsed. + */ + public DateTime ToDateTime() + { + return ParseDateString(TimeString, @"yyMMddHHmmss'GMT'zzz"); + } + + /** + * return the time as an adjusted date + * in the range of 1950 - 2049. + * + * @return a date in the range of 1950 to 2049. + * @exception ParseException if the date string cannot be parsed. + */ + public DateTime ToAdjustedDateTime() + { + return ParseDateString(AdjustedTimeString, @"yyyyMMddHHmmss'GMT'zzz"); + } + + private DateTime ParseDateString(string dateStr, string formatStr) + { + DateTime dt = DateTime.ParseExact( + dateStr, + formatStr, + DateTimeFormatInfo.InvariantInfo); + + return dt.ToUniversalTime(); + } + + /** + * return the time - always in the form of + * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). + * <p> + * Normally in a certificate we would expect "Z" rather than "GMT", + * however adding the "GMT" means we can just use: + * <pre> + * dateF = new SimpleDateFormat("yyMMddHHmmssz"); + * </pre> + * To read in the time and Get a date which is compatible with our local + * time zone.</p> + * <p> + * <b>Note:</b> In some cases, due to the local date processing, this + * may lead to unexpected results. If you want to stick the normal + * convention of 1950 to 2049 use the GetAdjustedTime() method.</p> + */ + public string TimeString + { + get + { + // + // standardise the format. + // + if (time.IndexOf('-') < 0 && time.IndexOf('+') < 0) + { + if (time.Length == 11) + { + return time.Substring(0, 10) + "00GMT+00:00"; + } + else + { + return time.Substring(0, 12) + "GMT+00:00"; + } + } + else + { + int index = time.IndexOf('-'); + if (index < 0) + { + index = time.IndexOf('+'); + } + string d = time; + + if (index == time.Length - 3) + { + d += "00"; + } + + if (index == 10) + { + return d.Substring(0, 10) + "00GMT" + d.Substring(10, 3) + ":" + d.Substring(13, 2); + } + else + { + return d.Substring(0, 12) + "GMT" + d.Substring(12, 3) + ":" + d.Substring(15, 2); + } + } + } + } + + /// <summary> + /// Return a time string as an adjusted date with a 4 digit year. + /// This goes in the range of 1950 - 2049. + /// </summary> + public string AdjustedTimeString + { + get + { + string d = TimeString; + string c = d[0] < '5' ? "20" : "19"; + + return c + d; + } + } + + internal byte[] GetOctets() + { + return Strings.ToAsciiByteArray(time); + } + + internal override IAsn1Encoding GetEncoding(int encoding) + { + return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.UtcTime, GetOctets()); + } + + internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo) + { + return new PrimitiveEncoding(tagClass, tagNo, GetOctets()); + } + + protected override bool Asn1Equals(Asn1Object asn1Object) + { + if (!(asn1Object is Asn1UtcTime that)) + return false; + + return this.time == that.time; + } + + protected override int Asn1GetHashCode() + { + return time.GetHashCode(); + } + + public override string ToString() + { + return time; + } + + internal static Asn1UtcTime CreatePrimitive(byte[] contents) + { + return new Asn1UtcTime(contents); + } + } +} diff --git a/crypto/src/asn1/DerGeneralizedTime.cs b/crypto/src/asn1/DerGeneralizedTime.cs index 898a3d585..0386ecb02 100644 --- a/crypto/src/asn1/DerGeneralizedTime.cs +++ b/crypto/src/asn1/DerGeneralizedTime.cs @@ -1,367 +1,33 @@ using System; -using System.Globalization; -using System.IO; -using System.Text; - -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1 { - /** - * Generalized time object. - */ public class DerGeneralizedTime - : Asn1Object + : Asn1GeneralizedTime { - internal class Meta : Asn1UniversalType - { - internal static readonly Asn1UniversalType Instance = new Meta(); - - private Meta() : base(typeof(DerGeneralizedTime), Asn1Tags.GeneralizedTime) {} - - internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString) - { - return CreatePrimitive(octetString.GetOctets()); - } - } - - /** - * return a generalized time from the passed in object - * - * @exception ArgumentException if the object cannot be converted. - */ - public static DerGeneralizedTime GetInstance(object obj) - { - if (obj == null || obj is DerGeneralizedTime) - { - return (DerGeneralizedTime)obj; - } - else if (obj is IAsn1Convertible) - { - Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); - if (asn1Object is DerGeneralizedTime) - return (DerGeneralizedTime)asn1Object; - } - else if (obj is byte[]) - { - try - { - return (DerGeneralizedTime)Meta.Instance.FromByteArray((byte[])obj); - } - catch (IOException e) - { - throw new ArgumentException("failed to construct generalized time from byte[]: " + e.Message); - } - } - - throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); - } - - /** - * return a generalized Time object from a tagged object. - * - * @param taggedObject the tagged object holding the object we want - * @param declaredExplicit true if the object is meant to be explicitly tagged false otherwise. - * @exception ArgumentException if the tagged object cannot be converted. - */ - public static DerGeneralizedTime GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + public DerGeneralizedTime(byte[] time) + : base(time) { - return (DerGeneralizedTime)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit); } - private readonly string time; - - /** - * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z - * for local time, or Z+-HHMM on the end, for difference between local - * time and UTC time. The fractional second amount f must consist of at - * least one number with trailing zeroes removed. - * - * @param time the time string. - * @exception ArgumentException if string is an illegal format. - */ - public DerGeneralizedTime( - string time) - { - this.time = time; - - try - { - ToDateTime(); - } - catch (FormatException e) - { - throw new ArgumentException("invalid date string: " + e.Message); - } - } - - /** - * base constructor from a local time object - */ public DerGeneralizedTime(DateTime time) + : base(time) { - this.time = time.ToUniversalTime().ToString(@"yyyyMMddHHmmss\Z"); - } - - internal DerGeneralizedTime( - byte[] bytes) - { - // - // explicitly convert to characters - // - this.time = Strings.FromAsciiByteArray(bytes); } - /** - * Return the time. - * @return The time string as it appeared in the encoded object. - */ - public string TimeString + public DerGeneralizedTime(string time) + : base(time) { - get { return time; } - } - - /** - * return the time - always in the form of - * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm). - * <p> - * Normally in a certificate we would expect "Z" rather than "GMT", - * however adding the "GMT" means we can just use: - * <pre> - * dateF = new SimpleDateFormat("yyyyMMddHHmmssz"); - * </pre> - * To read in the time and Get a date which is compatible with our local - * time zone.</p> - */ - public string GetTime() - { - // - // standardise the format. - // - if (time[time.Length - 1] == 'Z') - return time.Substring(0, time.Length - 1) + "GMT+00:00"; - - int signPos = time.Length - 5; - char sign = time[signPos]; - if (sign == '-' || sign == '+') - { - return time.Substring(0, signPos) - + "GMT" - + time.Substring(signPos, 3) - + ":" - + time.Substring(signPos + 3); - } - else - { - signPos = time.Length - 3; - sign = time[signPos]; - if (sign == '-' || sign == '+') - { - return time.Substring(0, signPos) - + "GMT" - + time.Substring(signPos) - + ":00"; - } - } - - return time + CalculateGmtOffset(); - } - - private string CalculateGmtOffset() - { - char sign = '+'; - DateTime time = ToDateTime(); - - TimeSpan offset = TimeZoneInfo.Local.GetUtcOffset(time); - if (offset.CompareTo(TimeSpan.Zero) < 0) - { - sign = '-'; - offset = offset.Duration(); - } - int hours = offset.Hours; - int minutes = offset.Minutes; - - return "GMT" + sign + Convert(hours) + ":" + Convert(minutes); - } - - private static string Convert( - int time) - { - if (time < 10) - { - return "0" + time; - } - - return time.ToString(); - } - - public DateTime ToDateTime() - { - string formatStr; - string d = time; - bool makeUniversal = false; - - if (Platform.EndsWith(d, "Z")) - { - if (HasFractionalSeconds) - { - int fCount = d.Length - d.IndexOf('.') - 2; - formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"\Z"; - } - else if (HasSeconds) - { - formatStr = @"yyyyMMddHHmmss\Z"; - } - else if (HasMinutes) - { - formatStr = @"yyyyMMddHHmm\Z"; - } - else - { - formatStr = @"yyyyMMddHH\Z"; - } - } - else if (time.IndexOf('-') > 0 || time.IndexOf('+') > 0) - { - d = GetTime(); - makeUniversal = true; - - if (HasFractionalSeconds) - { - int fCount = Platform.IndexOf(d, "GMT") - 1 - d.IndexOf('.'); - formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"'GMT'zzz"; - } - else - { - formatStr = @"yyyyMMddHHmmss'GMT'zzz"; - } - } - else - { - if (HasFractionalSeconds) - { - int fCount = d.Length - 1 - d.IndexOf('.'); - formatStr = @"yyyyMMddHHmmss." + FString(fCount); - } - else if (HasSeconds) - { - formatStr = @"yyyyMMddHHmmss"; - } - else if (HasMinutes) - { - formatStr = @"yyyyMMddHHmm"; - } - else - { - formatStr = @"yyyyMMddHH"; - } - - // TODO? -// dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID())); - } - - return ParseDateString(d, formatStr, makeUniversal); - } - - private string FString( - int count) - { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < count; ++i) - { - sb.Append('f'); - } - return sb.ToString(); - } - - private DateTime ParseDateString(string s, string format, bool makeUniversal) - { - /* - * NOTE: DateTime.Kind and DateTimeStyles.AssumeUniversal not available in .NET 1.1 - */ - DateTimeStyles style = DateTimeStyles.None; - if (Platform.EndsWith(format, "Z")) - { - style |= DateTimeStyles.AdjustToUniversal; - style |= DateTimeStyles.AssumeUniversal; - } - - DateTime dt = DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo, style); - - return makeUniversal ? dt.ToUniversalTime() : dt; - } - - private bool HasFractionalSeconds - { - get { return time.IndexOf('.') == 14; } - } - - private bool HasSeconds => IsDigit(12) && IsDigit(13); - - private bool HasMinutes => IsDigit(10) && IsDigit(11); - - private bool IsDigit(int pos) - { - return time.Length > pos && char.IsDigit(time[pos]); - } - - private byte[] GetOctets(int encoding) - { - if (Asn1OutputStream.EncodingDer == encoding && time[time.Length - 1] == 'Z') - { - if (!HasMinutes) - return Strings.ToAsciiByteArray(time.Insert(time.Length - 1, "0000")); - if (!HasSeconds) - return Strings.ToAsciiByteArray(time.Insert(time.Length - 1, "00")); - - if (HasFractionalSeconds) - { - int ind = time.Length - 2; - while (ind > 0 && time[ind] == '0') - { - --ind; - } - - if (time[ind] != '.') - { - ++ind; - } - - if (ind != time.Length - 1) - { - return Strings.ToAsciiByteArray(time.Remove(ind, time.Length - 1 - ind)); - } - } - } - - return Strings.ToAsciiByteArray(time); } internal override IAsn1Encoding GetEncoding(int encoding) { - return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, GetOctets(encoding)); + return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, GetDerTime()); } internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo) { - return new PrimitiveEncoding(tagClass, tagNo, GetOctets(encoding)); - } - - protected override bool Asn1Equals(Asn1Object asn1Object) - { - DerGeneralizedTime that = asn1Object as DerGeneralizedTime; - return null != that - && this.time.Equals(that.time); - } - - protected override int Asn1GetHashCode() - { - return time.GetHashCode(); - } - - internal static DerGeneralizedTime CreatePrimitive(byte[] contents) - { - return new DerGeneralizedTime(contents); + return new PrimitiveEncoding(tagClass, tagNo, GetDerTime()); } } } diff --git a/crypto/src/asn1/DerUTCTime.cs b/crypto/src/asn1/DerUTCTime.cs index 7f7756d49..089285367 100644 --- a/crypto/src/asn1/DerUTCTime.cs +++ b/crypto/src/asn1/DerUTCTime.cs @@ -1,274 +1,25 @@ using System; -using System.Globalization; -using System.IO; - -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1 { - /** - * UTC time object. - */ public class DerUtcTime - : Asn1Object + : Asn1UtcTime { - internal class Meta : Asn1UniversalType - { - internal static readonly Asn1UniversalType Instance = new Meta(); - - private Meta() : base(typeof(DerUtcTime), Asn1Tags.UtcTime) {} - - internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString) - { - return CreatePrimitive(octetString.GetOctets()); - } - } - - /** - * return a UTC Time from the passed in object. - * - * @exception ArgumentException if the object cannot be converted. - */ - public static DerUtcTime GetInstance(object obj) - { - if (obj == null || obj is DerUtcTime) - { - return (DerUtcTime)obj; - } - else if (obj is IAsn1Convertible) - { - Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); - if (asn1Object is DerUtcTime) - return (DerUtcTime)asn1Object; - } - else if (obj is byte[]) - { - try - { - return (DerUtcTime)Meta.Instance.FromByteArray((byte[])obj); - } - catch (IOException e) - { - throw new ArgumentException("failed to construct UTC time from byte[]: " + e.Message); - } - } - - throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); - } - - /** - * return a UTC Time from a tagged object. - * - * @param taggedObject the tagged object holding the object we want - * @param declaredExplicit true if the object is meant to be explicitly tagged false otherwise. - * @exception ArgumentException if the tagged object cannot be converted. - */ - public static DerUtcTime GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) - { - return (DerUtcTime)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit); - } - - private readonly string time; - - /** - * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were - * never encoded. When you're creating one of these objects from scratch, that's - * what you want to use, otherwise we'll try to deal with whatever Gets read from - * the input stream... (this is why the input format is different from the GetTime() - * method output). - * <p> - * @param time the time string.</p> - */ public DerUtcTime(string time) + : base(time) { - if (time == null) - throw new ArgumentNullException("time"); - - this.time = time; - - try - { - ToDateTime(); - } - catch (FormatException e) - { - throw new ArgumentException("invalid date string: " + e.Message); - } } - /** - * base constructor from a DateTime object - */ public DerUtcTime(DateTime time) + : base(time) { - this.time = time.ToUniversalTime().ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; } internal DerUtcTime(byte[] contents) + : base(contents) { - // - // explicitly convert to characters - // - this.time = Strings.FromAsciiByteArray(contents); - } - -// public DateTime ToDateTime() -// { -// string tm = this.AdjustedTimeString; -// -// return new DateTime( -// Int16.Parse(tm.Substring(0, 4)), -// Int16.Parse(tm.Substring(4, 2)), -// Int16.Parse(tm.Substring(6, 2)), -// Int16.Parse(tm.Substring(8, 2)), -// Int16.Parse(tm.Substring(10, 2)), -// Int16.Parse(tm.Substring(12, 2))); -// } - - /** - * return the time as a date based on whatever a 2 digit year will return. For - * standardised processing use ToAdjustedDateTime(). - * - * @return the resulting date - * @exception ParseException if the date string cannot be parsed. - */ - public DateTime ToDateTime() - { - return ParseDateString(TimeString, @"yyMMddHHmmss'GMT'zzz"); - } - - /** - * return the time as an adjusted date - * in the range of 1950 - 2049. - * - * @return a date in the range of 1950 to 2049. - * @exception ParseException if the date string cannot be parsed. - */ - public DateTime ToAdjustedDateTime() - { - return ParseDateString(AdjustedTimeString, @"yyyyMMddHHmmss'GMT'zzz"); - } - - private DateTime ParseDateString(string dateStr, string formatStr) - { - DateTime dt = DateTime.ParseExact( - dateStr, - formatStr, - DateTimeFormatInfo.InvariantInfo); - - return dt.ToUniversalTime(); - } - - /** - * return the time - always in the form of - * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). - * <p> - * Normally in a certificate we would expect "Z" rather than "GMT", - * however adding the "GMT" means we can just use: - * <pre> - * dateF = new SimpleDateFormat("yyMMddHHmmssz"); - * </pre> - * To read in the time and Get a date which is compatible with our local - * time zone.</p> - * <p> - * <b>Note:</b> In some cases, due to the local date processing, this - * may lead to unexpected results. If you want to stick the normal - * convention of 1950 to 2049 use the GetAdjustedTime() method.</p> - */ - public string TimeString - { - get - { - // - // standardise the format. - // - if (time.IndexOf('-') < 0 && time.IndexOf('+') < 0) - { - if (time.Length == 11) - { - return time.Substring(0, 10) + "00GMT+00:00"; - } - else - { - return time.Substring(0, 12) + "GMT+00:00"; - } - } - else - { - int index = time.IndexOf('-'); - if (index < 0) - { - index = time.IndexOf('+'); - } - string d = time; - - if (index == time.Length - 3) - { - d += "00"; - } - - if (index == 10) - { - return d.Substring(0, 10) + "00GMT" + d.Substring(10, 3) + ":" + d.Substring(13, 2); - } - else - { - return d.Substring(0, 12) + "GMT" + d.Substring(12, 3) + ":" + d.Substring(15, 2); - } - } - } - } - - /// <summary> - /// Return a time string as an adjusted date with a 4 digit year. - /// This goes in the range of 1950 - 2049. - /// </summary> - public string AdjustedTimeString - { - get - { - string d = TimeString; - string c = d[0] < '5' ? "20" : "19"; - - return c + d; - } - } - - private byte[] GetOctets() - { - return Strings.ToAsciiByteArray(time); - } - - internal override IAsn1Encoding GetEncoding(int encoding) - { - return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.UtcTime, GetOctets()); - } - - internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo) - { - return new PrimitiveEncoding(tagClass, tagNo, GetOctets()); - } - - protected override bool Asn1Equals(Asn1Object asn1Object) - { - DerUtcTime that = asn1Object as DerUtcTime; - return null != that - && this.time.Equals(that.time); } - protected override int Asn1GetHashCode() - { - return time.GetHashCode(); - } - - public override string ToString() - { - return time; - } - - internal static DerUtcTime CreatePrimitive(byte[] contents) - { - return new DerUtcTime(contents); - } + // TODO: create proper DER encoding. } } diff --git a/crypto/src/asn1/bc/BCObjectIdentifiers.cs b/crypto/src/asn1/bc/BCObjectIdentifiers.cs index f3933af87..d526980e5 100644 --- a/crypto/src/asn1/bc/BCObjectIdentifiers.cs +++ b/crypto/src/asn1/bc/BCObjectIdentifiers.cs @@ -192,7 +192,16 @@ namespace Org.BouncyCastle.Asn1.BC public static readonly DerObjectIdentifier lightsaberkem256r3 = pqc_kem_saber.Branch("7"); public static readonly DerObjectIdentifier saberkem256r3 = pqc_kem_saber.Branch("8"); public static readonly DerObjectIdentifier firesaberkem256r3 = pqc_kem_saber.Branch("9"); - + public static readonly DerObjectIdentifier ulightsaberkemr3 = pqc_kem_saber.Branch("10"); + public static readonly DerObjectIdentifier usaberkemr3 = pqc_kem_saber.Branch("11"); + public static readonly DerObjectIdentifier ufiresaberkemr3 = pqc_kem_saber.Branch("12"); + public static readonly DerObjectIdentifier lightsaberkem90sr3 = pqc_kem_saber.Branch("13"); + public static readonly DerObjectIdentifier saberkem90sr3 = pqc_kem_saber.Branch("14"); + public static readonly DerObjectIdentifier firesaberkem90sr3 = pqc_kem_saber.Branch("15"); + public static readonly DerObjectIdentifier ulightsaberkem90sr3 = pqc_kem_saber.Branch("16"); + public static readonly DerObjectIdentifier usaberkem90sr3 = pqc_kem_saber.Branch("17"); + public static readonly DerObjectIdentifier ufiresaberkem90sr3 = pqc_kem_saber.Branch("18"); + /** * SIKE */ diff --git a/crypto/src/asn1/cmp/PKIHeader.cs b/crypto/src/asn1/cmp/PKIHeader.cs index 553a81bc0..7ed914e6a 100644 --- a/crypto/src/asn1/cmp/PKIHeader.cs +++ b/crypto/src/asn1/cmp/PKIHeader.cs @@ -19,7 +19,7 @@ namespace Org.BouncyCastle.Asn1.Cmp private readonly DerInteger pvno; private readonly GeneralName sender; private readonly GeneralName recipient; - private readonly DerGeneralizedTime messageTime; + private readonly Asn1GeneralizedTime messageTime; private readonly AlgorithmIdentifier protectionAlg; private readonly Asn1OctetString senderKID; // KeyIdentifier private readonly Asn1OctetString recipKID; // KeyIdentifier @@ -42,7 +42,7 @@ namespace Org.BouncyCastle.Asn1.Cmp switch (tObj.TagNo) { case 0: - messageTime = DerGeneralizedTime.GetInstance(tObj, true); + messageTime = Asn1GeneralizedTime.GetInstance(tObj, true); break; case 1: protectionAlg = AlgorithmIdentifier.GetInstance(tObj, true); @@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Asn1.Cmp get { return recipient; } } - public virtual DerGeneralizedTime MessageTime + public virtual Asn1GeneralizedTime MessageTime { get { return messageTime; } } diff --git a/crypto/src/asn1/cmp/PKIHeaderBuilder.cs b/crypto/src/asn1/cmp/PKIHeaderBuilder.cs index d771dda4c..cbefc73b8 100644 --- a/crypto/src/asn1/cmp/PKIHeaderBuilder.cs +++ b/crypto/src/asn1/cmp/PKIHeaderBuilder.cs @@ -9,7 +9,7 @@ namespace Org.BouncyCastle.Asn1.Cmp private DerInteger pvno; private GeneralName sender; private GeneralName recipient; - private DerGeneralizedTime messageTime; + private Asn1GeneralizedTime messageTime; private AlgorithmIdentifier protectionAlg; private Asn1OctetString senderKID; // KeyIdentifier private Asn1OctetString recipKID; // KeyIdentifier @@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Asn1.Cmp this.recipient = recipient; } - public virtual PkiHeaderBuilder SetMessageTime(DerGeneralizedTime time) + public virtual PkiHeaderBuilder SetMessageTime(Asn1GeneralizedTime time) { messageTime = time; return this; diff --git a/crypto/src/asn1/cmp/RevAnnContent.cs b/crypto/src/asn1/cmp/RevAnnContent.cs index 4ef6fdbf7..cdd26c39f 100644 --- a/crypto/src/asn1/cmp/RevAnnContent.cs +++ b/crypto/src/asn1/cmp/RevAnnContent.cs @@ -19,18 +19,18 @@ namespace Org.BouncyCastle.Asn1.Cmp private readonly PkiStatusEncodable m_status; private readonly CertId m_certID; - private readonly DerGeneralizedTime m_willBeRevokedAt; - private readonly DerGeneralizedTime m_badSinceDate; + private readonly Asn1GeneralizedTime m_willBeRevokedAt; + private readonly Asn1GeneralizedTime m_badSinceDate; private readonly X509Extensions m_crlDetails; - public RevAnnContent(PkiStatusEncodable status, CertId certID, DerGeneralizedTime willBeRevokedAt, - DerGeneralizedTime badSinceDate) + public RevAnnContent(PkiStatusEncodable status, CertId certID, Asn1GeneralizedTime willBeRevokedAt, + Asn1GeneralizedTime badSinceDate) : this(status, certID, willBeRevokedAt, badSinceDate, null) { } - public RevAnnContent(PkiStatusEncodable status, CertId certID, DerGeneralizedTime willBeRevokedAt, - DerGeneralizedTime badSinceDate, X509Extensions crlDetails) + public RevAnnContent(PkiStatusEncodable status, CertId certID, Asn1GeneralizedTime willBeRevokedAt, + Asn1GeneralizedTime badSinceDate, X509Extensions crlDetails) { m_status = status; m_certID = certID; @@ -43,8 +43,8 @@ namespace Org.BouncyCastle.Asn1.Cmp { m_status = PkiStatusEncodable.GetInstance(seq[0]); m_certID = CertId.GetInstance(seq[1]); - m_willBeRevokedAt = DerGeneralizedTime.GetInstance(seq[2]); - m_badSinceDate = DerGeneralizedTime.GetInstance(seq[3]); + m_willBeRevokedAt = Asn1GeneralizedTime.GetInstance(seq[2]); + m_badSinceDate = Asn1GeneralizedTime.GetInstance(seq[3]); if (seq.Count > 4) { @@ -56,9 +56,9 @@ namespace Org.BouncyCastle.Asn1.Cmp public virtual CertId CertID => m_certID; - public virtual DerGeneralizedTime WillBeRevokedAt => m_willBeRevokedAt; + public virtual Asn1GeneralizedTime WillBeRevokedAt => m_willBeRevokedAt; - public virtual DerGeneralizedTime BadSinceDate => m_badSinceDate; + public virtual Asn1GeneralizedTime BadSinceDate => m_badSinceDate; public virtual X509Extensions CrlDetails => m_crlDetails; diff --git a/crypto/src/asn1/cms/CMSObjectIdentifiers.cs b/crypto/src/asn1/cms/CMSObjectIdentifiers.cs index 2ad0a3c7c..6f4f8fb5e 100644 --- a/crypto/src/asn1/cms/CMSObjectIdentifiers.cs +++ b/crypto/src/asn1/cms/CMSObjectIdentifiers.cs @@ -13,7 +13,8 @@ namespace Org.BouncyCastle.Asn1.Cms public static readonly DerObjectIdentifier AuthenticatedData = PkcsObjectIdentifiers.IdCTAuthData; public static readonly DerObjectIdentifier CompressedData = PkcsObjectIdentifiers.IdCTCompressedData; public static readonly DerObjectIdentifier AuthEnvelopedData = PkcsObjectIdentifiers.IdCTAuthEnvelopedData; - public static readonly DerObjectIdentifier timestampedData = PkcsObjectIdentifiers.IdCTTimestampedData; + public static readonly DerObjectIdentifier TimestampedData = PkcsObjectIdentifiers.IdCTTimestampedData; + public static readonly DerObjectIdentifier ZlibCompress = PkcsObjectIdentifiers.IdAlgZlibCompress; /** * The other Revocation Info arc diff --git a/crypto/src/asn1/cms/KEKIdentifier.cs b/crypto/src/asn1/cms/KEKIdentifier.cs index a42217440..36ab94f52 100644 --- a/crypto/src/asn1/cms/KEKIdentifier.cs +++ b/crypto/src/asn1/cms/KEKIdentifier.cs @@ -8,12 +8,12 @@ namespace Org.BouncyCastle.Asn1.Cms : Asn1Encodable { private Asn1OctetString keyIdentifier; - private DerGeneralizedTime date; + private Asn1GeneralizedTime date; private OtherKeyAttribute other; public KekIdentifier( byte[] keyIdentifier, - DerGeneralizedTime date, + Asn1GeneralizedTime date, OtherKeyAttribute other) { this.keyIdentifier = new DerOctetString(keyIdentifier); @@ -31,9 +31,9 @@ namespace Org.BouncyCastle.Asn1.Cms case 1: break; case 2: - if (seq[1] is DerGeneralizedTime) + if (seq[1] is Asn1GeneralizedTime) { - date = (DerGeneralizedTime) seq[1]; + date = (Asn1GeneralizedTime) seq[1]; } else { @@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Asn1.Cms } break; case 3: - date = (DerGeneralizedTime) seq[1]; + date = (Asn1GeneralizedTime) seq[1]; other = OtherKeyAttribute.GetInstance(seq[2]); break; default: @@ -88,7 +88,7 @@ namespace Org.BouncyCastle.Asn1.Cms get { return keyIdentifier; } } - public DerGeneralizedTime Date + public Asn1GeneralizedTime Date { get { return date; } } diff --git a/crypto/src/asn1/cms/RecipientKeyIdentifier.cs b/crypto/src/asn1/cms/RecipientKeyIdentifier.cs index 995ddab51..dea9ce09d 100644 --- a/crypto/src/asn1/cms/RecipientKeyIdentifier.cs +++ b/crypto/src/asn1/cms/RecipientKeyIdentifier.cs @@ -8,12 +8,12 @@ namespace Org.BouncyCastle.Asn1.Cms : Asn1Encodable { private Asn1OctetString subjectKeyIdentifier; - private DerGeneralizedTime date; + private Asn1GeneralizedTime date; private OtherKeyAttribute other; public RecipientKeyIdentifier( Asn1OctetString subjectKeyIdentifier, - DerGeneralizedTime date, + Asn1GeneralizedTime date, OtherKeyAttribute other) { this.subjectKeyIdentifier = subjectKeyIdentifier; @@ -29,7 +29,7 @@ namespace Org.BouncyCastle.Asn1.Cms public RecipientKeyIdentifier( byte[] subjectKeyIdentifier, - DerGeneralizedTime date, + Asn1GeneralizedTime date, OtherKeyAttribute other) { this.subjectKeyIdentifier = new DerOctetString(subjectKeyIdentifier); @@ -48,9 +48,9 @@ namespace Org.BouncyCastle.Asn1.Cms case 1: break; case 2: - if (seq[1] is DerGeneralizedTime) + if (seq[1] is Asn1GeneralizedTime) { - date = (DerGeneralizedTime) seq[1]; + date = (Asn1GeneralizedTime)seq[1]; } else { @@ -58,7 +58,7 @@ namespace Org.BouncyCastle.Asn1.Cms } break; case 3: - date = (DerGeneralizedTime) seq[1]; + date = (Asn1GeneralizedTime)seq[1]; other = OtherKeyAttribute.GetInstance(seq[2]); break; default: @@ -105,7 +105,7 @@ namespace Org.BouncyCastle.Asn1.Cms get { return subjectKeyIdentifier; } } - public DerGeneralizedTime Date + public Asn1GeneralizedTime Date { get { return date; } } diff --git a/crypto/src/asn1/cms/Time.cs b/crypto/src/asn1/cms/Time.cs index 52fb4f937..89f1e4dae 100644 --- a/crypto/src/asn1/cms/Time.cs +++ b/crypto/src/asn1/cms/Time.cs @@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Asn1.Cms { if (time == null) throw new ArgumentNullException("time"); - if (!(time is DerUtcTime) && !(time is DerGeneralizedTime)) + if (!(time is Asn1UtcTime) && !(time is Asn1GeneralizedTime)) throw new ArgumentException("unknown object passed to Time"); this.time = time; @@ -33,8 +33,7 @@ namespace Org.BouncyCastle.Asn1.Cms * and 2049 a UTCTime object is Generated, otherwise a GeneralizedTime * is used. */ - public Time( - DateTime date) + public Time(DateTime date) { string d = date.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; @@ -50,15 +49,16 @@ namespace Org.BouncyCastle.Asn1.Cms } } - public static Time GetInstance( - object obj) + public static Time GetInstance(object obj) { - if (obj == null || obj is Time) - return (Time)obj; - if (obj is DerUtcTime) - return new Time((DerUtcTime)obj); - if (obj is DerGeneralizedTime) - return new Time((DerGeneralizedTime)obj); + if (obj == null) + return null; + if (obj is Time time) + return time; + if (obj is Asn1UtcTime utcTime) + return new Time(utcTime); + if (obj is Asn1GeneralizedTime generalizedTime) + return new Time(generalizedTime); throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); } @@ -67,14 +67,10 @@ namespace Org.BouncyCastle.Asn1.Cms { get { - if (time is DerUtcTime) - { - return ((DerUtcTime)time).AdjustedTimeString; - } - else - { - return ((DerGeneralizedTime)time).GetTime(); - } + if (time is Asn1UtcTime utcTime) + return utcTime.AdjustedTimeString; + + return ((Asn1GeneralizedTime)time).GetTime(); } } @@ -84,12 +80,10 @@ namespace Org.BouncyCastle.Asn1.Cms { try { - if (time is DerUtcTime) - { - return ((DerUtcTime)time).ToAdjustedDateTime(); - } + if (time is Asn1UtcTime utcTime) + return utcTime.ToAdjustedDateTime(); - return ((DerGeneralizedTime)time).ToDateTime(); + return ((Asn1GeneralizedTime)time).ToDateTime(); } catch (FormatException e) { diff --git a/crypto/src/asn1/esf/CrlIdentifier.cs b/crypto/src/asn1/esf/CrlIdentifier.cs index a8e40c870..44c99170c 100644 --- a/crypto/src/asn1/esf/CrlIdentifier.cs +++ b/crypto/src/asn1/esf/CrlIdentifier.cs @@ -1,5 +1,5 @@ using System; - +using System.Reflection; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; using Org.BouncyCastle.Utilities; @@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Asn1.Esf : Asn1Encodable { private readonly X509Name crlIssuer; - private readonly DerUtcTime crlIssuedTime; + private readonly Asn1UtcTime crlIssuedTime; private readonly DerInteger crlNumber; public static CrlIdentifier GetInstance( @@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Asn1.Esf throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); this.crlIssuer = X509Name.GetInstance(seq[0]); - this.crlIssuedTime = DerUtcTime.GetInstance(seq[1]); + this.crlIssuedTime = Asn1UtcTime.GetInstance(seq[1]); if (seq.Count > 2) { @@ -56,31 +56,36 @@ namespace Org.BouncyCastle.Asn1.Esf } } - public CrlIdentifier( - X509Name crlIssuer, - DateTime crlIssuedTime) - : this(crlIssuer, crlIssuedTime, null) + public CrlIdentifier(X509Name crlIssuer, DateTime crlIssuedTime) + : this(crlIssuer, crlIssuedTime, null) { } - public CrlIdentifier( - X509Name crlIssuer, - DateTime crlIssuedTime, - BigInteger crlNumber) + public CrlIdentifier(X509Name crlIssuer, DateTime crlIssuedTime, BigInteger crlNumber) + : this(crlIssuer, new Asn1UtcTime(crlIssuedTime), crlNumber) { - if (crlIssuer == null) - throw new ArgumentNullException("crlIssuer"); + } - this.crlIssuer = crlIssuer; - this.crlIssuedTime = new DerUtcTime(crlIssuedTime); + public CrlIdentifier(X509Name crlIssuer, Asn1UtcTime crlIssuedTime) + : this(crlIssuer, crlIssuedTime, null) + { + } - if (crlNumber != null) - { - this.crlNumber = new DerInteger(crlNumber); - } - } + public CrlIdentifier(X509Name crlIssuer, Asn1UtcTime crlIssuedTime, BigInteger crlNumber) + { + if (crlIssuer == null) + throw new ArgumentNullException(nameof(crlIssuer)); + + this.crlIssuer = crlIssuer; + this.crlIssuedTime = crlIssuedTime; + + if (null != crlNumber) + { + this.crlNumber = new DerInteger(crlNumber); + } + } - public X509Name CrlIssuer + public X509Name CrlIssuer { get { return crlIssuer; } } diff --git a/crypto/src/asn1/esf/OcspIdentifier.cs b/crypto/src/asn1/esf/OcspIdentifier.cs index e65f1cfe7..fa7069aed 100644 --- a/crypto/src/asn1/esf/OcspIdentifier.cs +++ b/crypto/src/asn1/esf/OcspIdentifier.cs @@ -20,7 +20,7 @@ namespace Org.BouncyCastle.Asn1.Esf : Asn1Encodable { private readonly ResponderID ocspResponderID; - private readonly DerGeneralizedTime producedAt; + private readonly Asn1GeneralizedTime producedAt; public static OcspIdentifier GetInstance( object obj) @@ -46,21 +46,30 @@ namespace Org.BouncyCastle.Asn1.Esf throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); this.ocspResponderID = ResponderID.GetInstance(seq[0].ToAsn1Object()); - this.producedAt = (DerGeneralizedTime) seq[1].ToAsn1Object(); + this.producedAt = (Asn1GeneralizedTime)seq[1].ToAsn1Object(); } - public OcspIdentifier( - ResponderID ocspResponderID, - DateTime producedAt) + public OcspIdentifier(ResponderID ocspResponderID, DateTime producedAt) { if (ocspResponderID == null) - throw new ArgumentNullException(); + throw new ArgumentNullException(nameof(ocspResponderID)); this.ocspResponderID = ocspResponderID; - this.producedAt = new DerGeneralizedTime(producedAt); + this.producedAt = new Asn1GeneralizedTime(producedAt); } - public ResponderID OcspResponderID + public OcspIdentifier(ResponderID ocspResponderID, Asn1GeneralizedTime producedAt) + { + if (ocspResponderID == null) + throw new ArgumentNullException(nameof(ocspResponderID)); + if (producedAt == null) + throw new ArgumentNullException(nameof(producedAt)); + + this.ocspResponderID = ocspResponderID; + this.producedAt = producedAt; + } + + public ResponderID OcspResponderID { get { return ocspResponderID; } } diff --git a/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs b/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs index b82c9373d..c9c96cbda 100644 --- a/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs +++ b/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs @@ -64,7 +64,7 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 } public DeclarationOfMajority( - DerGeneralizedTime dateOfBirth) + Asn1GeneralizedTime dateOfBirth) { this.declaration = new DerTaggedObject(false, 2, dateOfBirth); } @@ -155,14 +155,14 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 } } - public virtual DerGeneralizedTime DateOfBirth + public virtual Asn1GeneralizedTime DateOfBirth { get { switch ((Choice) declaration.TagNo) { case Choice.DateOfBirth: - return DerGeneralizedTime.GetInstance(declaration, false); + return Asn1GeneralizedTime.GetInstance(declaration, false); default: return null; } diff --git a/crypto/src/asn1/ocsp/CrlID.cs b/crypto/src/asn1/ocsp/CrlID.cs index fc1e59d22..24dda4edf 100644 --- a/crypto/src/asn1/ocsp/CrlID.cs +++ b/crypto/src/asn1/ocsp/CrlID.cs @@ -7,7 +7,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp { private readonly DerIA5String crlUrl; private readonly DerInteger crlNum; - private readonly DerGeneralizedTime crlTime; + private readonly Asn1GeneralizedTime crlTime; // TODO Add GetInstance method(s) and make this private? public CrlID(Asn1Sequence seq) @@ -23,7 +23,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp crlNum = DerInteger.GetInstance(o, true); break; case 2: - crlTime = DerGeneralizedTime.GetInstance(o, true); + crlTime = Asn1GeneralizedTime.GetInstance(o, true); break; default: throw new ArgumentException("unknown tag number: " + o.TagNo); @@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp get { return crlNum; } } - public DerGeneralizedTime CrlTime + public Asn1GeneralizedTime CrlTime { get { return crlTime; } } diff --git a/crypto/src/asn1/ocsp/ResponseData.cs b/crypto/src/asn1/ocsp/ResponseData.cs index a5769c0fa..dfb234bc1 100644 --- a/crypto/src/asn1/ocsp/ResponseData.cs +++ b/crypto/src/asn1/ocsp/ResponseData.cs @@ -13,7 +13,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp private readonly bool versionPresent; private readonly DerInteger version; private readonly ResponderID responderID; - private readonly DerGeneralizedTime producedAt; + private readonly Asn1GeneralizedTime producedAt; private readonly Asn1Sequence responses; private readonly X509Extensions responseExtensions; @@ -43,7 +43,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp public ResponseData( DerInteger version, ResponderID responderID, - DerGeneralizedTime producedAt, + Asn1GeneralizedTime producedAt, Asn1Sequence responses, X509Extensions responseExtensions) { @@ -56,7 +56,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp public ResponseData( ResponderID responderID, - DerGeneralizedTime producedAt, + Asn1GeneralizedTime producedAt, Asn1Sequence responses, X509Extensions responseExtensions) : this(V1, responderID, producedAt, responses, responseExtensions) @@ -90,7 +90,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp } this.responderID = ResponderID.GetInstance(seq[index++]); - this.producedAt = (DerGeneralizedTime)seq[index++]; + this.producedAt = (Asn1GeneralizedTime)seq[index++]; this.responses = (Asn1Sequence)seq[index++]; if (seq.Count > index) @@ -110,7 +110,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp get { return responderID; } } - public DerGeneralizedTime ProducedAt + public Asn1GeneralizedTime ProducedAt { get { return producedAt; } } diff --git a/crypto/src/asn1/ocsp/RevokedInfo.cs b/crypto/src/asn1/ocsp/RevokedInfo.cs index c67be0678..e6438dd08 100644 --- a/crypto/src/asn1/ocsp/RevokedInfo.cs +++ b/crypto/src/asn1/ocsp/RevokedInfo.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp public class RevokedInfo : Asn1Encodable { - private readonly DerGeneralizedTime revocationTime; + private readonly Asn1GeneralizedTime revocationTime; private readonly CrlReason revocationReason; public static RevokedInfo GetInstance( @@ -35,13 +35,13 @@ namespace Org.BouncyCastle.Asn1.Ocsp } public RevokedInfo( - DerGeneralizedTime revocationTime) + Asn1GeneralizedTime revocationTime) : this(revocationTime, null) { } public RevokedInfo( - DerGeneralizedTime revocationTime, + Asn1GeneralizedTime revocationTime, CrlReason revocationReason) { if (revocationTime == null) @@ -54,7 +54,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp private RevokedInfo( Asn1Sequence seq) { - this.revocationTime = (DerGeneralizedTime) seq[0]; + this.revocationTime = (Asn1GeneralizedTime)seq[0]; if (seq.Count > 1) { @@ -63,7 +63,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp } } - public DerGeneralizedTime RevocationTime + public Asn1GeneralizedTime RevocationTime { get { return revocationTime; } } diff --git a/crypto/src/asn1/ocsp/SingleResponse.cs b/crypto/src/asn1/ocsp/SingleResponse.cs index ecdf3dab0..42b451af7 100644 --- a/crypto/src/asn1/ocsp/SingleResponse.cs +++ b/crypto/src/asn1/ocsp/SingleResponse.cs @@ -10,15 +10,15 @@ namespace Org.BouncyCastle.Asn1.Ocsp { private readonly CertID certID; private readonly CertStatus certStatus; - private readonly DerGeneralizedTime thisUpdate; - private readonly DerGeneralizedTime nextUpdate; + private readonly Asn1GeneralizedTime thisUpdate; + private readonly Asn1GeneralizedTime nextUpdate; private readonly X509Extensions singleExtensions; public SingleResponse( CertID certID, CertStatus certStatus, - DerGeneralizedTime thisUpdate, - DerGeneralizedTime nextUpdate, + Asn1GeneralizedTime thisUpdate, + Asn1GeneralizedTime nextUpdate, X509Extensions singleExtensions) { this.certID = certID; @@ -33,11 +33,11 @@ namespace Org.BouncyCastle.Asn1.Ocsp { this.certID = CertID.GetInstance(seq[0]); this.certStatus = CertStatus.GetInstance(seq[1]); - this.thisUpdate = (DerGeneralizedTime)seq[2]; + this.thisUpdate = (Asn1GeneralizedTime)seq[2]; if (seq.Count > 4) { - this.nextUpdate = DerGeneralizedTime.GetInstance( + this.nextUpdate = Asn1GeneralizedTime.GetInstance( (Asn1TaggedObject) seq[3], true); this.singleExtensions = X509Extensions.GetInstance( (Asn1TaggedObject) seq[4], true); @@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp if (o.TagNo == 0) { - this.nextUpdate = DerGeneralizedTime.GetInstance(o, true); + this.nextUpdate = Asn1GeneralizedTime.GetInstance(o, true); } else { @@ -90,12 +90,12 @@ namespace Org.BouncyCastle.Asn1.Ocsp get { return certStatus; } } - public DerGeneralizedTime ThisUpdate + public Asn1GeneralizedTime ThisUpdate { get { return thisUpdate; } } - public DerGeneralizedTime NextUpdate + public Asn1GeneralizedTime NextUpdate { get { return nextUpdate; } } diff --git a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs index 1a6a5417a..570e0ded7 100644 --- a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs +++ b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs @@ -138,11 +138,12 @@ namespace Org.BouncyCastle.Asn1.Pkcs public static readonly DerObjectIdentifier IdAlg = IdSmime.Branch("3"); - public static readonly DerObjectIdentifier IdAlgEsdh = IdAlg.Branch("5"); - public static readonly DerObjectIdentifier IdAlgCms3DesWrap = IdAlg.Branch("6"); - public static readonly DerObjectIdentifier IdAlgCmsRC2Wrap = IdAlg.Branch("7"); - public static readonly DerObjectIdentifier IdAlgPwriKek = IdAlg.Branch("9"); - public static readonly DerObjectIdentifier IdAlgSsdh = IdAlg.Branch("10"); + public static readonly DerObjectIdentifier IdAlgEsdh = IdAlg.Branch("5"); + public static readonly DerObjectIdentifier IdAlgCms3DesWrap = IdAlg.Branch("6"); + public static readonly DerObjectIdentifier IdAlgCmsRC2Wrap = IdAlg.Branch("7"); + public static readonly DerObjectIdentifier IdAlgZlibCompress = IdAlg.Branch("8"); + public static readonly DerObjectIdentifier IdAlgPwriKek = IdAlg.Branch("9"); + public static readonly DerObjectIdentifier IdAlgSsdh = IdAlg.Branch("10"); /* * <pre> diff --git a/crypto/src/asn1/tsp/TSTInfo.cs b/crypto/src/asn1/tsp/TSTInfo.cs index 28a840e77..dde11494c 100644 --- a/crypto/src/asn1/tsp/TSTInfo.cs +++ b/crypto/src/asn1/tsp/TSTInfo.cs @@ -11,7 +11,7 @@ namespace Org.BouncyCastle.Asn1.Tsp private readonly DerObjectIdentifier tsaPolicyId; private readonly MessageImprint messageImprint; private readonly DerInteger serialNumber; - private readonly DerGeneralizedTime genTime; + private readonly Asn1GeneralizedTime genTime; private readonly Accuracy accuracy; private readonly DerBoolean ordering; private readonly DerInteger nonce; @@ -49,7 +49,7 @@ namespace Org.BouncyCastle.Asn1.Tsp // genTime e.MoveNext(); - genTime = DerGeneralizedTime.GetInstance(e.Current); + genTime = Asn1GeneralizedTime.GetInstance(e.Current); // default for ordering ordering = DerBoolean.False; @@ -96,7 +96,7 @@ namespace Org.BouncyCastle.Asn1.Tsp DerObjectIdentifier tsaPolicyId, MessageImprint messageImprint, DerInteger serialNumber, - DerGeneralizedTime genTime, + Asn1GeneralizedTime genTime, Accuracy accuracy, DerBoolean ordering, DerInteger nonce, @@ -140,7 +140,7 @@ namespace Org.BouncyCastle.Asn1.Tsp get { return accuracy; } } - public DerGeneralizedTime GenTime + public Asn1GeneralizedTime GenTime { get { return genTime; } } diff --git a/crypto/src/asn1/util/Asn1Dump.cs b/crypto/src/asn1/util/Asn1Dump.cs index 7bae766c3..6c005f512 100644 --- a/crypto/src/asn1/util/Asn1Dump.cs +++ b/crypto/src/asn1/util/Asn1Dump.cs @@ -206,12 +206,12 @@ namespace Org.BouncyCastle.Asn1.Utilities buf.Append(indent); buf.AppendLine("VideotexString(" + videotexString.GetString() + ")"); } - else if (obj is DerUtcTime utcTime) + else if (obj is Asn1UtcTime utcTime) { buf.Append(indent); buf.AppendLine("UTCTime(" + utcTime.TimeString + ")"); } - else if (obj is DerGeneralizedTime generalizedTime) + else if (obj is Asn1GeneralizedTime generalizedTime) { buf.Append(indent); buf.AppendLine("GeneralizedTime(" + generalizedTime.GetTime() + ")"); diff --git a/crypto/src/asn1/x509/AttCertValidityPeriod.cs b/crypto/src/asn1/x509/AttCertValidityPeriod.cs index d31e07402..893bc0838 100644 --- a/crypto/src/asn1/x509/AttCertValidityPeriod.cs +++ b/crypto/src/asn1/x509/AttCertValidityPeriod.cs @@ -7,8 +7,8 @@ namespace Org.BouncyCastle.Asn1.X509 public class AttCertValidityPeriod : Asn1Encodable { - private readonly DerGeneralizedTime notBeforeTime; - private readonly DerGeneralizedTime notAfterTime; + private readonly Asn1GeneralizedTime notBeforeTime; + private readonly Asn1GeneralizedTime notAfterTime; public static AttCertValidityPeriod GetInstance( object obj) @@ -39,24 +39,24 @@ namespace Org.BouncyCastle.Asn1.X509 if (seq.Count != 2) throw new ArgumentException("Bad sequence size: " + seq.Count); - notBeforeTime = DerGeneralizedTime.GetInstance(seq[0]); - notAfterTime = DerGeneralizedTime.GetInstance(seq[1]); + notBeforeTime = Asn1GeneralizedTime.GetInstance(seq[0]); + notAfterTime = Asn1GeneralizedTime.GetInstance(seq[1]); } public AttCertValidityPeriod( - DerGeneralizedTime notBeforeTime, - DerGeneralizedTime notAfterTime) + Asn1GeneralizedTime notBeforeTime, + Asn1GeneralizedTime notAfterTime) { this.notBeforeTime = notBeforeTime; this.notAfterTime = notAfterTime; } - public DerGeneralizedTime NotBeforeTime + public Asn1GeneralizedTime NotBeforeTime { get { return notBeforeTime; } } - public DerGeneralizedTime NotAfterTime + public Asn1GeneralizedTime NotAfterTime { get { return notAfterTime; } } diff --git a/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs b/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs index 89e8de6cb..a87c2ee9e 100644 --- a/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs +++ b/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs @@ -36,7 +36,7 @@ namespace Org.BouncyCastle.Asn1.X509 throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } - private DerGeneralizedTime _notBefore, _notAfter; + private Asn1GeneralizedTime _notBefore, _notAfter; private PrivateKeyUsagePeriod( Asn1Sequence seq) @@ -45,21 +45,21 @@ namespace Org.BouncyCastle.Asn1.X509 { if (tObj.TagNo == 0) { - _notBefore = DerGeneralizedTime.GetInstance(tObj, false); + _notBefore = Asn1GeneralizedTime.GetInstance(tObj, false); } else if (tObj.TagNo == 1) { - _notAfter = DerGeneralizedTime.GetInstance(tObj, false); + _notAfter = Asn1GeneralizedTime.GetInstance(tObj, false); } } } - public DerGeneralizedTime NotBefore + public Asn1GeneralizedTime NotBefore { get { return _notBefore; } } - public DerGeneralizedTime NotAfter + public Asn1GeneralizedTime NotAfter { get { return _notAfter; } } diff --git a/crypto/src/asn1/x509/TBSCertList.cs b/crypto/src/asn1/x509/TBSCertList.cs index ab847d563..2b288850f 100644 --- a/crypto/src/asn1/x509/TBSCertList.cs +++ b/crypto/src/asn1/x509/TBSCertList.cs @@ -193,8 +193,8 @@ namespace Org.BouncyCastle.Asn1.X509 thisUpdate = Time.GetInstance(seq[seqPos++]); if (seqPos < seq.Count - && (seq[seqPos] is DerUtcTime - || seq[seqPos] is DerGeneralizedTime + && (seq[seqPos] is Asn1UtcTime + || seq[seqPos] is Asn1GeneralizedTime || seq[seqPos] is Time)) { nextUpdate = Time.GetInstance(seq[seqPos++]); diff --git a/crypto/src/asn1/x509/Time.cs b/crypto/src/asn1/x509/Time.cs index efdf63850..1a6ac15c0 100644 --- a/crypto/src/asn1/x509/Time.cs +++ b/crypto/src/asn1/x509/Time.cs @@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Asn1.X509 { if (time == null) throw new ArgumentNullException("time"); - if (!(time is DerUtcTime) && !(time is DerGeneralizedTime)) + if (!(time is Asn1UtcTime) && !(time is Asn1GeneralizedTime)) throw new ArgumentException("unknown object passed to Time"); this.time = time; @@ -49,27 +49,26 @@ namespace Org.BouncyCastle.Asn1.X509 } } - public static Time GetInstance( - object obj) + public static Time GetInstance(object obj) { - if (obj == null || obj is Time) - return (Time)obj; - if (obj is DerUtcTime) - return new Time((DerUtcTime)obj); - if (obj is DerGeneralizedTime) - return new Time((DerGeneralizedTime)obj); + if (obj == null) + return null; + if (obj is Time time) + return time; + if (obj is Asn1UtcTime utcTime) + return new Time(utcTime); + if (obj is Asn1GeneralizedTime generalizedTime) + return new Time(generalizedTime); throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); } public string GetTime() { - if (time is DerUtcTime) - { - return ((DerUtcTime) time).AdjustedTimeString; - } + if (time is Asn1UtcTime utcTime) + return utcTime.AdjustedTimeString; - return ((DerGeneralizedTime) time).GetTime(); + return ((Asn1GeneralizedTime)time).GetTime(); } /// <summary> @@ -80,14 +79,10 @@ namespace Org.BouncyCastle.Asn1.X509 { try { - if (time is DerUtcTime) - { - return ((DerUtcTime)time).ToAdjustedDateTime(); - } - else - { - return ((DerGeneralizedTime)time).ToDateTime(); - } + if (time is Asn1UtcTime utcTime) + return utcTime.ToAdjustedDateTime(); + + return ((Asn1GeneralizedTime)time).ToDateTime(); } catch (FormatException e) { diff --git a/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs b/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs index 20b525a48..9cbff1ef0 100644 --- a/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs +++ b/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs @@ -56,7 +56,7 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetStartDate( - DerUtcTime startDate) + Asn1UtcTime startDate) { this.startDate = new Time(startDate); } @@ -68,7 +68,7 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetEndDate( - DerUtcTime endDate) + Asn1UtcTime endDate) { this.endDate = new Time(endDate); } diff --git a/crypto/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs b/crypto/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs index 02580b5b8..c78c966b0 100644 --- a/crypto/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs +++ b/crypto/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs @@ -26,11 +26,13 @@ namespace Org.BouncyCastle.Asn1.X509 internal AttCertIssuer issuer; internal AlgorithmIdentifier signature; internal DerInteger serialNumber; -// internal AttCertValidityPeriod attrCertValidityPeriod; internal Asn1EncodableVector attributes; internal DerBitString issuerUniqueID; internal X509Extensions extensions; - internal DerGeneralizedTime startDate, endDate; + + // Note: validity period start/end dates stored directly + //internal AttCertValidityPeriod attrCertValidityPeriod; + internal Asn1GeneralizedTime startDate, endDate; public V2AttributeCertificateInfoGenerator() { @@ -78,13 +80,13 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetStartDate( - DerGeneralizedTime startDate) + Asn1GeneralizedTime startDate) { this.startDate = startDate; } public void SetEndDate( - DerGeneralizedTime endDate) + Asn1GeneralizedTime endDate) { this.endDate = endDate; } diff --git a/crypto/src/asn1/x509/V2TBSCertListGenerator.cs b/crypto/src/asn1/x509/V2TBSCertListGenerator.cs index 1d58751fd..aa1a0b95d 100644 --- a/crypto/src/asn1/x509/V2TBSCertListGenerator.cs +++ b/crypto/src/asn1/x509/V2TBSCertListGenerator.cs @@ -55,13 +55,13 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetThisUpdate( - DerUtcTime thisUpdate) + Asn1UtcTime thisUpdate) { this.thisUpdate = new Time(thisUpdate); } public void SetNextUpdate( - DerUtcTime nextUpdate) + Asn1UtcTime nextUpdate) { this.nextUpdate = (nextUpdate != null) ? new Time(nextUpdate) @@ -90,7 +90,7 @@ namespace Org.BouncyCastle.Asn1.X509 crlEntries.Add(crlEntry); } - public void AddCrlEntry(DerInteger userCertificate, DerUtcTime revocationDate, int reason) + public void AddCrlEntry(DerInteger userCertificate, Asn1UtcTime revocationDate, int reason) { AddCrlEntry(userCertificate, new Time(revocationDate), reason); } @@ -101,7 +101,7 @@ namespace Org.BouncyCastle.Asn1.X509 } public void AddCrlEntry(DerInteger userCertificate, Time revocationDate, int reason, - DerGeneralizedTime invalidityDate) + Asn1GeneralizedTime invalidityDate) { var extOids = new List<DerObjectIdentifier>(); var extValues = new List<X509Extension>(); diff --git a/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs b/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs index beb469a0d..544582ddb 100644 --- a/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs +++ b/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs @@ -58,7 +58,7 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetStartDate( - DerUtcTime startDate) + Asn1UtcTime startDate) { this.startDate = new Time(startDate); } @@ -70,7 +70,7 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetEndDate( - DerUtcTime endDate) + Asn1UtcTime endDate) { this.endDate = new Time(endDate); } diff --git a/crypto/src/asn1/x509/X509DefaultEntryConverter.cs b/crypto/src/asn1/x509/X509DefaultEntryConverter.cs index 7282ead26..d155efc5a 100644 --- a/crypto/src/asn1/x509/X509DefaultEntryConverter.cs +++ b/crypto/src/asn1/x509/X509DefaultEntryConverter.cs @@ -46,7 +46,7 @@ namespace Org.BouncyCastle.Asn1.X509 if (oid.Equals(X509Name.DateOfBirth)) // accept time string as well as # (for compatibility) { - return new DerGeneralizedTime(value); + return new Asn1GeneralizedTime(value); } if (oid.Equals(X509Name.C) diff --git a/crypto/src/asn1/x509/sigi/PersonalData.cs b/crypto/src/asn1/x509/sigi/PersonalData.cs index 439039888..e8c75bf93 100644 --- a/crypto/src/asn1/x509/sigi/PersonalData.cs +++ b/crypto/src/asn1/x509/sigi/PersonalData.cs @@ -29,7 +29,7 @@ namespace Org.BouncyCastle.Asn1.X509.SigI { private readonly NameOrPseudonym nameOrPseudonym; private readonly BigInteger nameDistinguisher; - private readonly DerGeneralizedTime dateOfBirth; + private readonly Asn1GeneralizedTime dateOfBirth; private readonly DirectoryString placeOfBirth; private readonly string gender; private readonly DirectoryString postalAddress; @@ -88,7 +88,7 @@ namespace Org.BouncyCastle.Asn1.X509.SigI nameDistinguisher = DerInteger.GetInstance(o, false).Value; break; case 1: - dateOfBirth = DerGeneralizedTime.GetInstance(o, false); + dateOfBirth = Asn1GeneralizedTime.GetInstance(o, false); break; case 2: placeOfBirth = DirectoryString.GetInstance(o, true); @@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Asn1.X509.SigI public PersonalData( NameOrPseudonym nameOrPseudonym, BigInteger nameDistinguisher, - DerGeneralizedTime dateOfBirth, + Asn1GeneralizedTime dateOfBirth, DirectoryString placeOfBirth, string gender, DirectoryString postalAddress) @@ -141,7 +141,7 @@ namespace Org.BouncyCastle.Asn1.X509.SigI get { return nameDistinguisher; } } - public DerGeneralizedTime DateOfBirth + public Asn1GeneralizedTime DateOfBirth { get { return dateOfBirth; } } diff --git a/crypto/src/bcpg/SignaturePacket.cs b/crypto/src/bcpg/SignaturePacket.cs index 3256ee35e..dd9cc78e3 100644 --- a/crypto/src/bcpg/SignaturePacket.cs +++ b/crypto/src/bcpg/SignaturePacket.cs @@ -237,7 +237,7 @@ namespace Org.BouncyCastle.Bcpg if (hashedData != null) { - setCreationTime(); + SetCreationTime(); } } @@ -446,18 +446,18 @@ namespace Org.BouncyCastle.Bcpg return sOut.ToArray(); } - private void setCreationTime() + private void SetCreationTime() { foreach (SignatureSubpacket p in hashedData) { - if (p is SignatureCreationTime) + if (p is SignatureCreationTime signatureCreationTime) { - creationTime = DateTimeUtilities.DateTimeToUnixMs( - ((SignatureCreationTime)p).GetTime()); + creationTime = DateTimeUtilities.DateTimeToUnixMs(signatureCreationTime.GetTime()); break; } } } + public static SignaturePacket FromByteArray(byte[] data) { BcpgInputStream input = BcpgInputStream.Wrap(new MemoryStream(data)); diff --git a/crypto/src/bcpg/sig/Exportable.cs b/crypto/src/bcpg/sig/Exportable.cs index 4d030346f..8a9eafe09 100644 --- a/crypto/src/bcpg/sig/Exportable.cs +++ b/crypto/src/bcpg/sig/Exportable.cs @@ -10,17 +10,7 @@ namespace Org.BouncyCastle.Bcpg.Sig { private static byte[] BooleanToByteArray(bool val) { - byte[] data = new byte[1]; - - if (val) - { - data[0] = 1; - return data; - } - else - { - return data; - } + return new byte[1]{ Convert.ToByte(val) }; } public Exportable( diff --git a/crypto/src/bcpg/sig/Features.cs b/crypto/src/bcpg/sig/Features.cs index 135d7f54e..f6123d612 100644 --- a/crypto/src/bcpg/sig/Features.cs +++ b/crypto/src/bcpg/sig/Features.cs @@ -19,31 +19,25 @@ namespace Org.BouncyCastle.Bcpg.Sig fingerprint format */ public static readonly byte FEATURE_VERSION_5_PUBLIC_KEY = 0x04; - private static byte[] featureToByteArray(byte feature) + private static byte[] FeatureToByteArray(byte feature) { - byte[] data = new byte[1]; - data[0] = feature; - return data; + return new byte[1]{ feature }; } public Features( bool critical, bool isLongLength, - byte[] data): base(SignatureSubpacketTag.Features, critical, isLongLength, data) + byte[] data) + : base(SignatureSubpacketTag.Features, critical, isLongLength, data) { - } - - public Features(bool critical, byte features): this(critical, false, featureToByteArray(features)) + public Features(bool critical, byte features): this(critical, false, FeatureToByteArray(features)) { - } - - public Features(bool critical, int features): this(critical, false, featureToByteArray((byte)features)) + public Features(bool critical, int features): this(critical, false, FeatureToByteArray((byte)features)) { - } /** diff --git a/crypto/src/bcpg/sig/IssuerKeyId.cs b/crypto/src/bcpg/sig/IssuerKeyId.cs index 627ea3ecf..1281a110e 100644 --- a/crypto/src/bcpg/sig/IssuerKeyId.cs +++ b/crypto/src/bcpg/sig/IssuerKeyId.cs @@ -1,6 +1,4 @@ -using System; - - +using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Bcpg.Sig { @@ -10,21 +8,9 @@ namespace Org.BouncyCastle.Bcpg.Sig public class IssuerKeyId : SignatureSubpacket { - protected static byte[] KeyIdToBytes( - long keyId) + protected static byte[] KeyIdToBytes(long keyId) { - byte[] data = new byte[8]; - - data[0] = (byte)(keyId >> 56); - data[1] = (byte)(keyId >> 48); - data[2] = (byte)(keyId >> 40); - data[3] = (byte)(keyId >> 32); - data[4] = (byte)(keyId >> 24); - data[5] = (byte)(keyId >> 16); - data[6] = (byte)(keyId >> 8); - data[7] = (byte)keyId; - - return data; + return Pack.UInt64_To_BE((ulong)keyId); } public IssuerKeyId( @@ -42,21 +28,6 @@ namespace Org.BouncyCastle.Bcpg.Sig { } - public long KeyId - { - get - { - long keyId = ((long)(data[0] & 0xff) << 56) - | ((long)(data[1] & 0xff) << 48) - | ((long)(data[2] & 0xff) << 40) - | ((long)(data[3] & 0xff) << 32) - | ((long)(data[4] & 0xff) << 24) - | ((long)(data[5] & 0xff) << 16) - | ((long)(data[6] & 0xff) << 8) - | ((long)data[7] & 0xff); - - return keyId; - } - } + public long KeyId => (long)Pack.BE_To_UInt64(data); } } diff --git a/crypto/src/bcpg/sig/KeyExpirationTime.cs b/crypto/src/bcpg/sig/KeyExpirationTime.cs index dfd3e76fd..62184b2a1 100644 --- a/crypto/src/bcpg/sig/KeyExpirationTime.cs +++ b/crypto/src/bcpg/sig/KeyExpirationTime.cs @@ -1,4 +1,4 @@ -using System; +using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Bcpg.Sig { @@ -8,17 +8,9 @@ namespace Org.BouncyCastle.Bcpg.Sig public class KeyExpirationTime : SignatureSubpacket { - protected static byte[] TimeToBytes( - long t) + protected static byte[] TimeToBytes(long t) { - byte[] data = new byte[4]; - - data[0] = (byte)(t >> 24); - data[1] = (byte)(t >> 16); - data[2] = (byte)(t >> 8); - data[3] = (byte)t; - - return data; + return Pack.UInt32_To_BE((uint)t); } public KeyExpirationTime( @@ -41,15 +33,6 @@ namespace Org.BouncyCastle.Bcpg.Sig * * @return second count for key validity. */ - public long Time - { - get - { - long time = ((long)(data[0] & 0xff) << 24) | ((long)(data[1] & 0xff) << 16) - | ((long)(data[2] & 0xff) << 8) | ((long)data[3] & 0xff); - - return time; - } - } + public long Time => (long)Pack.BE_To_UInt32(data); } } diff --git a/crypto/src/bcpg/sig/NotationData.cs b/crypto/src/bcpg/sig/NotationData.cs index 9ac6f89cf..71c34d3de 100644 --- a/crypto/src/bcpg/sig/NotationData.cs +++ b/crypto/src/bcpg/sig/NotationData.cs @@ -79,7 +79,7 @@ namespace Org.BouncyCastle.Bcpg.Sig public bool IsHumanReadable { - get { return data[0] == (byte)0x80; } + get { return data[0] == 0x80; } } public string GetNotationName() diff --git a/crypto/src/bcpg/sig/PrimaryUserId.cs b/crypto/src/bcpg/sig/PrimaryUserId.cs index 1f16f40eb..184dfe8f7 100644 --- a/crypto/src/bcpg/sig/PrimaryUserId.cs +++ b/crypto/src/bcpg/sig/PrimaryUserId.cs @@ -8,20 +8,9 @@ namespace Org.BouncyCastle.Bcpg.Sig public class PrimaryUserId : SignatureSubpacket { - private static byte[] BooleanToByteArray( - bool val) + private static byte[] BooleanToByteArray(bool val) { - byte[] data = new byte[1]; - - if (val) - { - data[0] = 1; - return data; - } - else - { - return data; - } + return new byte[1]{ Convert.ToByte(val) }; } public PrimaryUserId( diff --git a/crypto/src/bcpg/sig/Revocable.cs b/crypto/src/bcpg/sig/Revocable.cs index 7aa91391f..6ded4d865 100644 --- a/crypto/src/bcpg/sig/Revocable.cs +++ b/crypto/src/bcpg/sig/Revocable.cs @@ -8,20 +8,9 @@ namespace Org.BouncyCastle.Bcpg.Sig public class Revocable : SignatureSubpacket { - private static byte[] BooleanToByteArray( - bool value) + private static byte[] BooleanToByteArray(bool value) { - byte[] data = new byte[1]; - - if (value) - { - data[0] = 1; - return data; - } - else - { - return data; - } + return new byte[1]{ Convert.ToByte(value) }; } public Revocable( diff --git a/crypto/src/bcpg/sig/RevocationReason.cs b/crypto/src/bcpg/sig/RevocationReason.cs index 42afd5f5b..bd0c91428 100644 --- a/crypto/src/bcpg/sig/RevocationReason.cs +++ b/crypto/src/bcpg/sig/RevocationReason.cs @@ -46,9 +46,7 @@ namespace Org.BouncyCastle.Bcpg { byte[] data = GetData(); if (data.Length == 1) - { return string.Empty; - } byte[] description = new byte[data.Length - 1]; Array.Copy(data, 1, description, 0, description.Length); diff --git a/crypto/src/bcpg/sig/SignatureCreationTime.cs b/crypto/src/bcpg/sig/SignatureCreationTime.cs index d172e5d52..233dd18e6 100644 --- a/crypto/src/bcpg/sig/SignatureCreationTime.cs +++ b/crypto/src/bcpg/sig/SignatureCreationTime.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities.Date; namespace Org.BouncyCastle.Bcpg.Sig @@ -10,41 +11,25 @@ namespace Org.BouncyCastle.Bcpg.Sig public class SignatureCreationTime : SignatureSubpacket { - protected static byte[] TimeToBytes( - DateTime time) + protected static byte[] TimeToBytes(DateTime time) { long t = DateTimeUtilities.DateTimeToUnixMs(time) / 1000L; - byte[] data = new byte[4]; - data[0] = (byte)(t >> 24); - data[1] = (byte)(t >> 16); - data[2] = (byte)(t >> 8); - data[3] = (byte)t; - return data; + return Pack.UInt32_To_BE((uint)t); } - public SignatureCreationTime( - bool critical, - bool isLongLength, - byte[] data) + public SignatureCreationTime(bool critical, bool isLongLength, byte[] data) : base(SignatureSubpacketTag.CreationTime, critical, isLongLength, data) { } - public SignatureCreationTime( - bool critical, - DateTime date) + public SignatureCreationTime(bool critical, DateTime date) : base(SignatureSubpacketTag.CreationTime, critical, false, TimeToBytes(date)) { } public DateTime GetTime() { - long time = (long)( - ((uint)data[0] << 24) - | ((uint)data[1] << 16) - | ((uint)data[2] << 8) - | ((uint)data[3]) - ); + uint time = Pack.BE_To_UInt32(data, 0); return DateTimeUtilities.UnixMsToDateTime(time * 1000L); } } diff --git a/crypto/src/bcpg/sig/SignatureExpirationTime.cs b/crypto/src/bcpg/sig/SignatureExpirationTime.cs index 24f0a9f8a..44c714f33 100644 --- a/crypto/src/bcpg/sig/SignatureExpirationTime.cs +++ b/crypto/src/bcpg/sig/SignatureExpirationTime.cs @@ -1,4 +1,4 @@ -using System; +using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Bcpg.Sig { @@ -8,28 +8,17 @@ namespace Org.BouncyCastle.Bcpg.Sig public class SignatureExpirationTime : SignatureSubpacket { - protected static byte[] TimeToBytes( - long t) + protected static byte[] TimeToBytes(long t) { - byte[] data = new byte[4]; - data[0] = (byte)(t >> 24); - data[1] = (byte)(t >> 16); - data[2] = (byte)(t >> 8); - data[3] = (byte)t; - return data; + return Pack.UInt32_To_BE((uint)t); } - public SignatureExpirationTime( - bool critical, - bool isLongLength, - byte[] data) + public SignatureExpirationTime(bool critical, bool isLongLength, byte[] data) : base(SignatureSubpacketTag.ExpireTime, critical, isLongLength, data) { } - public SignatureExpirationTime( - bool critical, - long seconds) + public SignatureExpirationTime(bool critical, long seconds) : base(SignatureSubpacketTag.ExpireTime, critical, false, TimeToBytes(seconds)) { } @@ -37,15 +26,6 @@ namespace Org.BouncyCastle.Bcpg.Sig /** * return time in seconds before signature expires after creation time. */ - public long Time - { - get - { - long time = ((long)(data[0] & 0xff) << 24) | ((long)(data[1] & 0xff) << 16) - | ((long)(data[2] & 0xff) << 8) | ((long)data[3] & 0xff); - - return time; - } - } + public long Time => Pack.BE_To_UInt32(data, 0); } } diff --git a/crypto/src/bcpg/sig/SignerUserId.cs b/crypto/src/bcpg/sig/SignerUserId.cs index 8ab62ed2e..6f812e210 100644 --- a/crypto/src/bcpg/sig/SignerUserId.cs +++ b/crypto/src/bcpg/sig/SignerUserId.cs @@ -1,7 +1,3 @@ -using System; - - - namespace Org.BouncyCastle.Bcpg.Sig { /** diff --git a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs index 837eb177f..505747960 100644 --- a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs +++ b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.X509; @@ -44,7 +45,13 @@ namespace Org.BouncyCastle.Cmp return this; } - public ProtectedPkiMessageBuilder SetMessageTime(DerGeneralizedTime generalizedTime) + public ProtectedPkiMessageBuilder SetMessageTime(DateTime time) + { + m_hdrBuilder.SetMessageTime(new Asn1GeneralizedTime(time)); + return this; + } + + public ProtectedPkiMessageBuilder SetMessageTime(Asn1GeneralizedTime generalizedTime) { m_hdrBuilder.SetMessageTime(generalizedTime); return this; diff --git a/crypto/src/cms/CMSAuthenticatedDataGenerator.cs b/crypto/src/cms/CMSAuthenticatedDataGenerator.cs index 9bfabe8b1..6c68bccd1 100644 --- a/crypto/src/cms/CMSAuthenticatedDataGenerator.cs +++ b/crypto/src/cms/CMSAuthenticatedDataGenerator.cs @@ -29,20 +29,14 @@ namespace Org.BouncyCastle.Cms public class CmsAuthenticatedDataGenerator : CmsAuthenticatedGenerator { - /** - * base constructor - */ public CmsAuthenticatedDataGenerator() { } - /** - * constructor allowing specific source of randomness - * @param rand instance of SecureRandom to use - */ - public CmsAuthenticatedDataGenerator( - SecureRandom rand) - : base(rand) + /// <summary>Constructor allowing specific source of randomness</summary> + /// <param name="random">Instance of <c>SecureRandom</c> to use.</param> + public CmsAuthenticatedDataGenerator(SecureRandom random) + : base(random) { } @@ -109,7 +103,7 @@ namespace Org.BouncyCastle.Cms { try { - recipientInfos.Add(rig.Generate(encKey, rand)); + recipientInfos.Add(rig.Generate(encKey, m_random)); } catch (InvalidKeyException e) { @@ -142,7 +136,7 @@ namespace Org.BouncyCastle.Cms // FIXME Will this work for macs? CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); - keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength)); + keyGen.Init(new KeyGenerationParameters(m_random, keyGen.DefaultStrength)); return Generate(content, encryptionOid, keyGen); } diff --git a/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs b/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs index d66b0aea9..b2c5cac28 100644 --- a/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs @@ -42,20 +42,14 @@ namespace Org.BouncyCastle.Cms private int _bufferSize; private bool _berEncodeRecipientSet; - /** - * base constructor - */ public CmsAuthenticatedDataStreamGenerator() { } - /** - * constructor allowing specific source of randomness - * @param rand instance of SecureRandom to use - */ - public CmsAuthenticatedDataStreamGenerator( - SecureRandom rand) - : base(rand) + /// <summary>Constructor allowing specific source of randomness</summary> + /// <param name="random">Instance of <c>SecureRandom</c> to use.</param> + public CmsAuthenticatedDataStreamGenerator(SecureRandom random) + : base(random) { } @@ -105,7 +99,7 @@ namespace Org.BouncyCastle.Cms { try { - recipientInfos.Add(rig.Generate(encKey, rand)); + recipientInfos.Add(rig.Generate(encKey, m_random)); } catch (InvalidKeyException e) { @@ -195,7 +189,7 @@ namespace Org.BouncyCastle.Cms { CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); - keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength)); + keyGen.Init(new KeyGenerationParameters(m_random, keyGen.DefaultStrength)); return Open(outStr, encryptionOid, keyGen); } @@ -210,7 +204,7 @@ namespace Org.BouncyCastle.Cms { CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); - keyGen.Init(new KeyGenerationParameters(rand, keySize)); + keyGen.Init(new KeyGenerationParameters(m_random, keySize)); return Open(outStr, encryptionOid, keyGen); } diff --git a/crypto/src/cms/CMSAuthenticatedGenerator.cs b/crypto/src/cms/CMSAuthenticatedGenerator.cs index 8824d1913..1f73c9b19 100644 --- a/crypto/src/cms/CMSAuthenticatedGenerator.cs +++ b/crypto/src/cms/CMSAuthenticatedGenerator.cs @@ -14,21 +14,14 @@ namespace Org.BouncyCastle.Cms public class CmsAuthenticatedGenerator : CmsEnvelopedGenerator { - /** - * base constructor - */ public CmsAuthenticatedGenerator() { } - /** - * constructor allowing specific source of randomness - * - * @param rand instance of SecureRandom to use - */ - public CmsAuthenticatedGenerator( - SecureRandom rand) - : base(rand) + /// <summary>Constructor allowing specific source of randomness</summary> + /// <param name="random">Instance of <c>SecureRandom</c> to use.</param> + public CmsAuthenticatedGenerator(SecureRandom random) + : base(random) { } } diff --git a/crypto/src/cms/CMSCompressedData.cs b/crypto/src/cms/CMSCompressedData.cs index 21651f041..5f8165005 100644 --- a/crypto/src/cms/CMSCompressedData.cs +++ b/crypto/src/cms/CMSCompressedData.cs @@ -1,10 +1,9 @@ -using System; using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Utilities; -using Org.BouncyCastle.Utilities.Zlib; +using Org.BouncyCastle.Utilities.IO.Compression; namespace Org.BouncyCastle.Cms { @@ -45,7 +44,7 @@ namespace Org.BouncyCastle.Cms ContentInfo content = comData.EncapContentInfo; Asn1OctetString bytes = (Asn1OctetString) content.Content; - ZInputStream zIn = new ZInputStream(bytes.GetOctetStream()); + Stream zIn = ZLib.DecompressInput(bytes.GetOctetStream()); try { @@ -76,8 +75,7 @@ namespace Org.BouncyCastle.Cms ContentInfo content = comData.EncapContentInfo; Asn1OctetString bytes = (Asn1OctetString)content.Content; - - ZInputStream zIn = new ZInputStream(new MemoryStream(bytes.GetOctets(), false)); + Stream zIn = ZLib.DecompressInput(bytes.GetOctetStream()); try { diff --git a/crypto/src/cms/CMSCompressedDataGenerator.cs b/crypto/src/cms/CMSCompressedDataGenerator.cs index bea04752a..70515e8d3 100644 --- a/crypto/src/cms/CMSCompressedDataGenerator.cs +++ b/crypto/src/cms/CMSCompressedDataGenerator.cs @@ -5,7 +5,6 @@ using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Utilities; -using Org.BouncyCastle.Utilities.Zlib; namespace Org.BouncyCastle.Cms { @@ -22,32 +21,34 @@ namespace Org.BouncyCastle.Cms */ public class CmsCompressedDataGenerator { - public const string ZLib = "1.2.840.113549.1.9.16.3.8"; + public static readonly string ZLib = CmsObjectIdentifiers.ZlibCompress.Id; - public CmsCompressedDataGenerator() + public CmsCompressedDataGenerator() { } /** * Generate an object that contains an CMS Compressed Data */ - public CmsCompressedData Generate( - CmsProcessable content, - string compressionOid) + public CmsCompressedData Generate(CmsProcessable content, string compressionOid) { + if (ZLib != compressionOid) + throw new ArgumentException("Unsupported compression algorithm: " + compressionOid, + nameof(compressionOid)); + AlgorithmIdentifier comAlgId; Asn1OctetString comOcts; try { MemoryStream bOut = new MemoryStream(); - ZOutputStream zOut = new ZOutputStream(bOut, JZlib.Z_DEFAULT_COMPRESSION); + Stream zOut = Utilities.IO.Compression.ZLib.CompressOutput(bOut, -1); content.Write(zOut); Platform.Dispose(zOut); - comAlgId = new AlgorithmIdentifier(new DerObjectIdentifier(compressionOid)); + comAlgId = new AlgorithmIdentifier(CmsObjectIdentifiers.ZlibCompress); comOcts = new BerOctetString(bOut.ToArray()); } catch (IOException e) diff --git a/crypto/src/cms/CMSCompressedDataParser.cs b/crypto/src/cms/CMSCompressedDataParser.cs index b107ff608..38ff88968 100644 --- a/crypto/src/cms/CMSCompressedDataParser.cs +++ b/crypto/src/cms/CMSCompressedDataParser.cs @@ -3,7 +3,7 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; -using Org.BouncyCastle.Utilities.Zlib; +using Org.BouncyCastle.Utilities.IO.Compression; namespace Org.BouncyCastle.Cms { @@ -44,8 +44,9 @@ namespace Org.BouncyCastle.Cms ContentInfoParser content = comData.GetEncapContentInfo(); Asn1OctetStringParser bytes = (Asn1OctetStringParser)content.GetContent(Asn1Tags.OctetString); + Stream zIn = ZLib.DecompressInput(bytes.GetOctetStream()); - return new CmsTypedStream(content.ContentType.ToString(), new ZInputStream(bytes.GetOctetStream())); + return new CmsTypedStream(content.ContentType.ToString(), zIn); } catch (IOException e) { diff --git a/crypto/src/cms/CMSCompressedDataStreamGenerator.cs b/crypto/src/cms/CMSCompressedDataStreamGenerator.cs index 9a9c29b01..1594500cd 100644 --- a/crypto/src/cms/CMSCompressedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSCompressedDataStreamGenerator.cs @@ -6,7 +6,6 @@ using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; -using Org.BouncyCastle.Utilities.Zlib; namespace Org.BouncyCastle.Cms { @@ -27,10 +26,10 @@ namespace Org.BouncyCastle.Cms */ public class CmsCompressedDataStreamGenerator { - public const string ZLib = "1.2.840.113549.1.9.16.3.8"; + public static readonly string ZLib = CmsObjectIdentifiers.ZlibCompress.Id; + + private int _bufferSize; - private int _bufferSize; - /** * base constructor */ @@ -43,24 +42,27 @@ namespace Org.BouncyCastle.Cms * * @param bufferSize length of octet strings to buffer the data. */ - public void SetBufferSize( - int bufferSize) + public void SetBufferSize(int bufferSize) { _bufferSize = bufferSize; } - public Stream Open( - Stream outStream, - string compressionOID) + public Stream Open(Stream outStream) + { + return Open(outStream, CmsObjectIdentifiers.Data.Id, ZLib); + } + + public Stream Open(Stream outStream, string compressionOid) { - return Open(outStream, CmsObjectIdentifiers.Data.Id, compressionOID); + return Open(outStream, CmsObjectIdentifiers.Data.Id, compressionOid); } - public Stream Open( - Stream outStream, - string contentOID, - string compressionOID) + public Stream Open(Stream outStream, string contentOid, string compressionOid) { + if (ZLib != compressionOid) + throw new ArgumentException("Unsupported compression algorithm: " + compressionOid, + nameof(compressionOid)); + BerSequenceGenerator sGen = new BerSequenceGenerator(outStream); sGen.AddObject(CmsObjectIdentifiers.CompressedData); @@ -75,32 +77,32 @@ namespace Org.BouncyCastle.Cms cGen.AddObject(new DerInteger(0)); // CompressionAlgorithmIdentifier - cGen.AddObject(new AlgorithmIdentifier(new DerObjectIdentifier(ZLib))); + cGen.AddObject(new AlgorithmIdentifier(CmsObjectIdentifiers.ZlibCompress)); // // Encapsulated ContentInfo // BerSequenceGenerator eiGen = new BerSequenceGenerator(cGen.GetRawOutputStream()); - eiGen.AddObject(new DerObjectIdentifier(contentOID)); + eiGen.AddObject(new DerObjectIdentifier(contentOid)); Stream octetStream = CmsUtilities.CreateBerOctetOutputStream( eiGen.GetRawOutputStream(), 0, true, _bufferSize); return new CmsCompressedOutputStream( - new ZOutputStream(octetStream, JZlib.Z_DEFAULT_COMPRESSION), sGen, cGen, eiGen); + Utilities.IO.Compression.ZLib.CompressOutput(octetStream, -1), sGen, cGen, eiGen); } private class CmsCompressedOutputStream : BaseOutputStream { - private ZOutputStream _out; + private Stream _out; private BerSequenceGenerator _sGen; private BerSequenceGenerator _cGen; private BerSequenceGenerator _eiGen; internal CmsCompressedOutputStream( - ZOutputStream outStream, + Stream outStream, BerSequenceGenerator sGen, BerSequenceGenerator cGen, BerSequenceGenerator eiGen) diff --git a/crypto/src/cms/CMSEnvelopedDataGenerator.cs b/crypto/src/cms/CMSEnvelopedDataGenerator.cs index d646480e0..1b618b331 100644 --- a/crypto/src/cms/CMSEnvelopedDataGenerator.cs +++ b/crypto/src/cms/CMSEnvelopedDataGenerator.cs @@ -33,10 +33,9 @@ namespace Org.BouncyCastle.Cms } /// <summary>Constructor allowing specific source of randomness</summary> - /// <param name="rand">Instance of <c>SecureRandom</c> to use.</param> - public CmsEnvelopedDataGenerator( - SecureRandom rand) - : base(rand) + /// <param name="random">Instance of <c>SecureRandom</c> to use.</param> + public CmsEnvelopedDataGenerator(SecureRandom random) + : base(random) { } @@ -65,7 +64,7 @@ namespace Org.BouncyCastle.Cms encryptionOid, encKey, asn1Params, out cipherParameters); IBufferedCipher cipher = CipherUtilities.GetCipher(encryptionOid); - cipher.Init(true, new ParametersWithRandom(cipherParameters, rand)); + cipher.Init(true, new ParametersWithRandom(cipherParameters, m_random)); MemoryStream bOut = new MemoryStream(); CipherStream cOut = new CipherStream(bOut, null, cipher); @@ -96,7 +95,7 @@ namespace Org.BouncyCastle.Cms { try { - recipientInfos.Add(rig.Generate(encKey, rand)); + recipientInfos.Add(rig.Generate(encKey, m_random)); } catch (InvalidKeyException e) { @@ -138,7 +137,7 @@ namespace Org.BouncyCastle.Cms { CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); - keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength)); + keyGen.Init(new KeyGenerationParameters(m_random, keyGen.DefaultStrength)); return Generate(content, encryptionOid, keyGen); } @@ -185,7 +184,7 @@ namespace Org.BouncyCastle.Cms { try { - recipientInfos.Add(rig.Generate(encKey, rand)); + recipientInfos.Add(rig.Generate(encKey, m_random)); } catch (InvalidKeyException e) { @@ -228,7 +227,7 @@ namespace Org.BouncyCastle.Cms { CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); - keyGen.Init(new KeyGenerationParameters(rand, keySize)); + keyGen.Init(new KeyGenerationParameters(m_random, keySize)); return Generate(content, encryptionOid, keyGen); } diff --git a/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs b/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs index 4a8b57aad..6a362e13f 100644 --- a/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs @@ -46,10 +46,9 @@ namespace Org.BouncyCastle.Cms } /// <summary>Constructor allowing specific source of randomness</summary> - /// <param name="rand">Instance of <c>SecureRandom</c> to use.</param> - public CmsEnvelopedDataStreamGenerator( - SecureRandom rand) - : base(rand) + /// <param name="random">Instance of <c>SecureRandom</c> to use.</param> + public CmsEnvelopedDataStreamGenerator(SecureRandom random) + : base(random) { } @@ -104,7 +103,7 @@ namespace Org.BouncyCastle.Cms { try { - recipientInfos.Add(rig.Generate(encKey, rand)); + recipientInfos.Add(rig.Generate(encKey, m_random)); } catch (InvalidKeyException e) { @@ -162,7 +161,7 @@ namespace Org.BouncyCastle.Cms eiGen.GetRawOutputStream(), 0, false, _bufferSize); IBufferedCipher cipher = CipherUtilities.GetCipher(encAlgID.Algorithm); - cipher.Init(true, new ParametersWithRandom(cipherParameters, rand)); + cipher.Init(true, new ParametersWithRandom(cipherParameters, m_random)); CipherStream cOut = new CipherStream(octetOutputStream, null, cipher); return new CmsEnvelopedDataOutputStream(this, cOut, cGen, envGen, eiGen); @@ -191,7 +190,7 @@ namespace Org.BouncyCastle.Cms { CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); - keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength)); + keyGen.Init(new KeyGenerationParameters(m_random, keyGen.DefaultStrength)); return Open(outStream, encryptionOid, keyGen); } @@ -207,7 +206,7 @@ namespace Org.BouncyCastle.Cms { CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); - keyGen.Init(new KeyGenerationParameters(rand, keySize)); + keyGen.Init(new KeyGenerationParameters(m_random, keySize)); return Open(outStream, encryptionOid, keyGen); } diff --git a/crypto/src/cms/CMSEnvelopedGenerator.cs b/crypto/src/cms/CMSEnvelopedGenerator.cs index e0a94c4d3..eef572878 100644 --- a/crypto/src/cms/CMSEnvelopedGenerator.cs +++ b/crypto/src/cms/CMSEnvelopedGenerator.cs @@ -30,7 +30,7 @@ namespace Org.BouncyCastle.Cms * CMSEnvelopedData data = fact.generate(content, algorithm, "BC"); * </pre> */ - public class CmsEnvelopedGenerator + public abstract class CmsEnvelopedGenerator { // Note: These tables are complementary: If rc2Table[i]==j, then rc2Ekb[j]==i internal static readonly short[] rc2Table = @@ -100,21 +100,23 @@ namespace Org.BouncyCastle.Cms public static readonly string ECMqvSha1Kdf = X9ObjectIdentifiers.MqvSinglePassSha1KdfScheme.Id; internal readonly IList<RecipientInfoGenerator> recipientInfoGenerators = new List<RecipientInfoGenerator>(); - internal readonly SecureRandom rand; + internal readonly SecureRandom m_random; internal CmsAttributeTableGenerator unprotectedAttributeGenerator = null; - public CmsEnvelopedGenerator() - : this(new SecureRandom()) + protected CmsEnvelopedGenerator() + : this(CryptoServicesRegistrar.GetSecureRandom()) { } /// <summary>Constructor allowing specific source of randomness</summary> - /// <param name="rand">Instance of <c>SecureRandom</c> to use.</param> - public CmsEnvelopedGenerator( - SecureRandom rand) + /// <param name="random">Instance of <c>SecureRandom</c> to use.</param> + protected CmsEnvelopedGenerator(SecureRandom random) { - this.rand = rand; + if (random == null) + throw new ArgumentNullException(nameof(random)); + + m_random = random; } public CmsAttributeTableGenerator UnprotectedAttributeGenerator @@ -304,7 +306,7 @@ namespace Org.BouncyCastle.Cms if (encryptionOid.Equals(RC2Cbc)) { byte[] iv = new byte[8]; - rand.NextBytes(iv); + m_random.NextBytes(iv); // TODO Is this detailed repeat of Java version really necessary? int effKeyBits = encKeyBytes.Length * 8; @@ -323,7 +325,7 @@ namespace Org.BouncyCastle.Cms } else { - asn1Params = ParameterUtilities.GenerateParameters(encryptionOid, rand); + asn1Params = ParameterUtilities.GenerateParameters(encryptionOid, m_random); } } catch (SecurityUtilityException) diff --git a/crypto/src/cms/CMSSignedDataGenerator.cs b/crypto/src/cms/CMSSignedDataGenerator.cs index c2304a09b..fff22e057 100644 --- a/crypto/src/cms/CMSSignedDataGenerator.cs +++ b/crypto/src/cms/CMSSignedDataGenerator.cs @@ -55,6 +55,7 @@ namespace Org.BouncyCastle.Cms internal SignerInf( CmsSignedGenerator outer, AsymmetricKeyParameter key, + SecureRandom random, SignerIdentifier signerIdentifier, string digestOID, string encOID, @@ -67,7 +68,7 @@ namespace Org.BouncyCastle.Cms string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(encOID); this.outer = outer; - this.sigCalc = new Asn1SignatureFactory(signatureName, key); + this.sigCalc = new Asn1SignatureFactory(signatureName, key, random); this.signerIdentifier = signerIdentifier; this.digestOID = digestOID; this.encOID = encOID; @@ -110,10 +111,7 @@ namespace Org.BouncyCastle.Cms get { return unsAttr; } } - internal SignerInfo ToSignerInfo( - DerObjectIdentifier contentType, - CmsProcessable content, - SecureRandom random) + internal SignerInfo ToSignerInfo(DerObjectIdentifier contentType, CmsProcessable content) { AlgorithmIdentifier digAlgId = DigestAlgorithmID; string digestName = Helper.GetDigestAlgName(digestOID); @@ -196,10 +194,9 @@ namespace Org.BouncyCastle.Cms } /// <summary>Constructor allowing specific source of randomness</summary> - /// <param name="rand">Instance of <c>SecureRandom</c> to use.</param> - public CmsSignedDataGenerator( - SecureRandom rand) - : base(rand) + /// <param name="random">Instance of <c>SecureRandom</c> to use.</param> + public CmsSignedDataGenerator(SecureRandom random) + : base(random) { } @@ -425,7 +422,7 @@ namespace Org.BouncyCastle.Cms CmsAttributeTableGenerator unsignedAttrGen, Asn1.Cms.AttributeTable baseSignedTable) { - signerInfs.Add(new SignerInf(this, privateKey, signerIdentifier, digestOID, encryptionOID, + signerInfs.Add(new SignerInf(this, privateKey, m_random, signerIdentifier, digestOID, encryptionOID, signedAttrGen, unsignedAttrGen, baseSignedTable)); } @@ -480,7 +477,7 @@ namespace Org.BouncyCastle.Cms try { digestAlgs.Add(signer.DigestAlgorithmID); - signerInfos.Add(signer.ToSignerInfo(contentTypeOid, content, rand)); + signerInfos.Add(signer.ToSignerInfo(contentTypeOid, content)); } catch (IOException e) { diff --git a/crypto/src/cms/CMSSignedDataStreamGenerator.cs b/crypto/src/cms/CMSSignedDataStreamGenerator.cs index 96200fc8c..f934b9259 100644 --- a/crypto/src/cms/CMSSignedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSSignedDataStreamGenerator.cs @@ -137,7 +137,7 @@ namespace Org.BouncyCastle.Cms } } - _sig.Init(true, new ParametersWithRandom(key, outer.rand)); + _sig.Init(true, new ParametersWithRandom(key, outer.m_random)); } public SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, @@ -234,10 +234,9 @@ namespace Org.BouncyCastle.Cms } /// <summary>Constructor allowing specific source of randomness</summary> - /// <param name="rand">Instance of <c>SecureRandom</c> to use.</param> - public CmsSignedDataStreamGenerator( - SecureRandom rand) - : base(rand) + /// <param name="random">Instance of <c>SecureRandom</c> to use.</param> + public CmsSignedDataStreamGenerator(SecureRandom random) + : base(random) { } diff --git a/crypto/src/cms/CMSSignedGenerator.cs b/crypto/src/cms/CMSSignedGenerator.cs index 58f66f214..c16f6e83c 100644 --- a/crypto/src/cms/CMSSignedGenerator.cs +++ b/crypto/src/cms/CMSSignedGenerator.cs @@ -15,6 +15,7 @@ using Org.BouncyCastle.Asn1.Rosstandart; using Org.BouncyCastle.Asn1.TeleTrust; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.X509; @@ -481,7 +482,7 @@ namespace Org.BouncyCastle.Cms } } - public class CmsSignedGenerator + public abstract class CmsSignedGenerator { /** * Default type for the signed data. @@ -516,19 +517,21 @@ namespace Org.BouncyCastle.Cms internal bool _useDerForCerts = false; internal bool _useDerForCrls = false; - protected readonly SecureRandom rand; + protected readonly SecureRandom m_random; protected CmsSignedGenerator() - : this(new SecureRandom()) + : this(CryptoServicesRegistrar.GetSecureRandom()) { } /// <summary>Constructor allowing specific source of randomness</summary> - /// <param name="rand">Instance of <c>SecureRandom</c> to use.</param> - protected CmsSignedGenerator( - SecureRandom rand) + /// <param name="random">Instance of <c>SecureRandom</c> to use.</param> + protected CmsSignedGenerator(SecureRandom random) { - this.rand = rand; + if (random == null) + throw new ArgumentNullException(nameof(random)); + + m_random = random; } internal protected virtual IDictionary<CmsAttributeTableParameter, object> GetBaseParameters( diff --git a/crypto/src/cms/CMSSignedHelper.cs b/crypto/src/cms/CMSSignedHelper.cs index 0ab7790d1..8df9e8f01 100644 --- a/crypto/src/cms/CMSSignedHelper.cs +++ b/crypto/src/cms/CMSSignedHelper.cs @@ -7,6 +7,7 @@ using Org.BouncyCastle.Asn1.Eac; using Org.BouncyCastle.Asn1.Nist; using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; using Org.BouncyCastle.Asn1.TeleTrust; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; @@ -82,15 +83,21 @@ namespace Org.BouncyCastle.Cms AddEntries(EacObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA"); AddEntries(EacObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1"); AddEntries(EacObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1"); + AddEntries(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94, "GOST3411", "GOST3410"); + AddEntries(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001, "GOST3411", "ECGOST3410"); + AddEntries(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "GOST3411_2012_256", "ECGOST3410"); + AddEntries(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "GOST3411_2012_512", "ECGOST3410"); - m_encryptionAlgs.Add(X9ObjectIdentifiers.IdDsa.Id, "DSA"); + m_encryptionAlgs.Add(X9ObjectIdentifiers.IdDsa.Id, "DSA"); m_encryptionAlgs.Add(PkcsObjectIdentifiers.RsaEncryption.Id, "RSA"); m_encryptionAlgs.Add(TeleTrusTObjectIdentifiers.TeleTrusTRsaSignatureAlgorithm.Id, "RSA"); m_encryptionAlgs.Add(X509ObjectIdentifiers.IdEARsa.Id, "RSA"); m_encryptionAlgs.Add(CmsSignedGenerator.EncryptionRsaPss, "RSAandMGF1"); m_encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x94.Id, "GOST3410"); m_encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x2001.Id, "ECGOST3410"); - m_encryptionAlgs.Add("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410"); + m_encryptionAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256.Id, "ECGOST3410"); + m_encryptionAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512.Id, "ECGOST3410"); + m_encryptionAlgs.Add("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410"); m_encryptionAlgs.Add("1.3.6.1.4.1.5849.1.1.5", "GOST3410"); m_digestAlgs.Add(PkcsObjectIdentifiers.MD2.Id, "MD2"); @@ -112,15 +119,17 @@ namespace Org.BouncyCastle.Cms m_digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, "RIPEMD256"); m_digestAlgs.Add(CryptoProObjectIdentifiers.GostR3411.Id, "GOST3411"); m_digestAlgs.Add("1.3.6.1.4.1.5849.1.2.1", "GOST3411"); + m_digestAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id, "GOST3411_2012_256"); + m_digestAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id, "GOST3411_2012_512"); - m_digestAliases.Add("SHA1", new string[]{ "SHA-1" }); + m_digestAliases.Add("SHA1", new string[]{ "SHA-1" }); m_digestAliases.Add("SHA224", new string[]{ "SHA-224" }); m_digestAliases.Add("SHA256", new string[]{ "SHA-256" }); m_digestAliases.Add("SHA384", new string[]{ "SHA-384" }); m_digestAliases.Add("SHA512", new string[]{ "SHA-512" }); noParams.Add(CmsSignedGenerator.EncryptionDsa); - // noParams.Add(EncryptionECDsa); + //noParams.Add(EncryptionECDsa); noParams.Add(EncryptionECDsaWithSha1); noParams.Add(EncryptionECDsaWithSha224); noParams.Add(EncryptionECDsaWithSha256); diff --git a/crypto/src/crmf/PKMacBuilder.cs b/crypto/src/crmf/PKMacBuilder.cs index bce26b825..ae9baa3d0 100644 --- a/crypto/src/crmf/PKMacBuilder.cs +++ b/crypto/src/crmf/PKMacBuilder.cs @@ -224,10 +224,7 @@ namespace Org.BouncyCastle.Crmf byte[] salt = new byte[saltLength]; - if (random == null) - { - this.random = new SecureRandom(); - } + this.random = CryptoServicesRegistrar.GetSecureRandom(random); random.NextBytes(salt); diff --git a/crypto/src/crypto/CipherKeyGenerator.cs b/crypto/src/crypto/CipherKeyGenerator.cs index 80d4782db..2d5d8c2e0 100644 --- a/crypto/src/crypto/CipherKeyGenerator.cs +++ b/crypto/src/crypto/CipherKeyGenerator.cs @@ -67,7 +67,7 @@ namespace Org.BouncyCastle.Crypto uninitialised = false; - EngineInit(new KeyGenerationParameters(new SecureRandom(), defaultStrength)); + EngineInit(new KeyGenerationParameters(CryptoServicesRegistrar.GetSecureRandom(), defaultStrength)); } return EngineGenerateKey(); diff --git a/crypto/src/crypto/Security.cs b/crypto/src/crypto/Security.cs deleted file mode 100644 index 7eb595f8e..000000000 --- a/crypto/src/crypto/Security.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Text; - -using Org.BouncyCastle.Crypto.Digests; -using Org.BouncyCastle.Crypto.Engines; -using Org.BouncyCastle.Crypto.Generators; -using Org.BouncyCastle.Crypto.Modes; -using Org.BouncyCastle.Crypto.Paddings; -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Security; -using Org.BouncyCastle.Utilities.Encoders; - -namespace Org.BouncyCastle.Crypto -{ - public static class Security - { - // USAGE - //var key = Security.GenerateText(32); - //var iv = Security.GenerateText(16); - //var encrypted = Security.Encrypt("MY SECRET", key, iv); - //var decrypted = Security.Decrypt(encrypted, key, iv); - - /// <summary> - /// Return a salted hash based on PBKDF2 for the UTF-8 encoding of the argument text. - /// </summary> - /// <param name="text">Provided key text</param> - /// <param name="salt">Base64 encoded string representing the salt</param> - /// <returns></returns> - public static string ComputeHash(string text, string salt) - { - byte[] data = Encoding.UTF8.GetBytes(text); - Sha512Digest sha = new Sha512Digest(); - Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator(sha); - - gen.Init(data, Base64.Decode(salt), 2048); - - return Base64.ToBase64String(((KeyParameter)gen.GenerateDerivedParameters("AES", sha.GetDigestSize() * 8)).GetKey()); - } - - public static string Decrypt(string cipherText, string key, string iv) - { - IBufferedCipher cipher = CreateCipher(false, key, iv); - byte[] textAsBytes = cipher.DoFinal(Base64.Decode(cipherText)); - - return Encoding.UTF8.GetString(textAsBytes, 0, textAsBytes.Length); - } - - public static string Encrypt(string plainText, string key, string iv) - { - IBufferedCipher cipher = CreateCipher(true, key, iv); - - return Base64.ToBase64String(cipher.DoFinal(Encoding.UTF8.GetBytes(plainText))); - } - - public static string GenerateText(int size) - { - byte[] textAsBytes = new byte[size]; - SecureRandom secureRandom = SecureRandom.GetInstance("SHA256PRNG", true); - - secureRandom.NextBytes(textAsBytes); - return Base64.ToBase64String(textAsBytes); - } - - private static IBufferedCipher CreateCipher(bool isEncryption, string key, string iv) - { - IBufferedCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(new RijndaelEngine()), new ISO10126d2Padding()); - KeyParameter keyParam = new KeyParameter(Base64.Decode(key)); - ICipherParameters cipherParams = (null == iv || iv.Length < 1) - ? (ICipherParameters)keyParam - : new ParametersWithIV(keyParam, Base64.Decode(iv)); - cipher.Init(isEncryption, cipherParams); - return cipher; - } - } -} diff --git a/crypto/src/crypto/agreement/DHAgreement.cs b/crypto/src/crypto/agreement/DHAgreement.cs index e988c0d53..6032c237a 100644 --- a/crypto/src/crypto/agreement/DHAgreement.cs +++ b/crypto/src/crypto/agreement/DHAgreement.cs @@ -26,30 +26,25 @@ namespace Org.BouncyCastle.Crypto.Agreement private BigInteger privateValue; private SecureRandom random; - public void Init( - ICipherParameters parameters) + public void Init(ICipherParameters parameters) { AsymmetricKeyParameter kParam; - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom rParam) { - ParametersWithRandom rParam = (ParametersWithRandom)parameters; - this.random = rParam.Random; kParam = (AsymmetricKeyParameter)rParam.Parameters; } else { - this.random = new SecureRandom(); + this.random = CryptoServicesRegistrar.GetSecureRandom(); kParam = (AsymmetricKeyParameter)parameters; } - if (!(kParam is DHPrivateKeyParameters)) - { + if (!(kParam is DHPrivateKeyParameters dhPrivateKeyParameters)) throw new ArgumentException("DHEngine expects DHPrivateKeyParameters"); - } - this.key = (DHPrivateKeyParameters)kParam; - this.dhParams = key.Parameters; + this.key = dhPrivateKeyParameters; + this.dhParams = dhPrivateKeyParameters.Parameters; } /** diff --git a/crypto/src/crypto/agreement/jpake/JPakeParticipant.cs b/crypto/src/crypto/agreement/jpake/JPakeParticipant.cs index 794284866..d6ed37032 100755 --- a/crypto/src/crypto/agreement/jpake/JPakeParticipant.cs +++ b/crypto/src/crypto/agreement/jpake/JPakeParticipant.cs @@ -142,7 +142,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.JPake /// Caller should clear the input password as soon as possible.</param> /// <param name="group">Prime order group. See JPakePrimeOrderGroups for standard groups.</param> public JPakeParticipant(string participantId, char[] password, JPakePrimeOrderGroup group) - : this(participantId, password, group, new Sha256Digest(), new SecureRandom()) { } + : this(participantId, password, group, new Sha256Digest(), CryptoServicesRegistrar.GetSecureRandom()) { } /// <summary> @@ -162,7 +162,8 @@ namespace Org.BouncyCastle.Crypto.Agreement.JPake /// <param name="digest">Digest to use during zero knowledge proofs and key confirmation /// (SHA-256 or stronger preferred).</param> /// <param name="random">Source of secure random data for x1 and x2, and for the zero knowledge proofs.</param> - public JPakeParticipant(string participantId, char[] password, JPakePrimeOrderGroup group, IDigest digest, SecureRandom random) + public JPakeParticipant(string participantId, char[] password, JPakePrimeOrderGroup group, IDigest digest, + SecureRandom random) { JPakeUtilities.ValidateNotNull(participantId, "participantId"); JPakeUtilities.ValidateNotNull(password, "password"); @@ -171,9 +172,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.JPake JPakeUtilities.ValidateNotNull(random, "random"); if (password.Length == 0) - { throw new ArgumentException("Password must not be empty."); - } this.participantId = participantId; diff --git a/crypto/src/crypto/digests/Haraka256_X86.cs b/crypto/src/crypto/digests/Haraka256_X86.cs index ab64f91ae..4c9a798c0 100644 --- a/crypto/src/crypto/digests/Haraka256_X86.cs +++ b/crypto/src/crypto/digests/Haraka256_X86.cs @@ -1,6 +1,8 @@ #if NETCOREAPP3_0_OR_GREATER using System; +using System.Buffers.Binary; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace Org.BouncyCastle.Crypto.Digests @@ -115,33 +117,27 @@ namespace Org.BouncyCastle.Crypto.Digests [MethodImpl(MethodImplOptions.AggressiveInlining)] 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 Unsafe.AsRef(t[0])); + return MemoryMarshal.Read<Vector128<byte>>(t); - 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]); -#endif + return Vector128.Create( + BinaryPrimitives.ReadUInt64LittleEndian(t[..8]), + BinaryPrimitives.ReadUInt64LittleEndian(t[8..]) + ).AsByte(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Store128(Vector128<byte> s, Span<byte> t) { -#if NET7_0_OR_GREATER - Vector128.CopyTo(s, t); -#else if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16) { - Unsafe.WriteUnaligned(ref t[0], s); + MemoryMarshal.Write(t, ref s); return; } var u = s.AsUInt64(); - Utilities.Pack.UInt64_To_LE(u.GetElement(0), t); - Utilities.Pack.UInt64_To_LE(u.GetElement(1), t[8..]); -#endif + BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0)); + BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1)); } } } diff --git a/crypto/src/crypto/digests/Haraka512_X86.cs b/crypto/src/crypto/digests/Haraka512_X86.cs index 8e67228ae..6dcd3e782 100644 --- a/crypto/src/crypto/digests/Haraka512_X86.cs +++ b/crypto/src/crypto/digests/Haraka512_X86.cs @@ -1,6 +1,8 @@ #if NETCOREAPP3_0_OR_GREATER using System; +using System.Buffers.Binary; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace Org.BouncyCastle.Crypto.Digests @@ -198,50 +200,40 @@ namespace Org.BouncyCastle.Crypto.Digests [MethodImpl(MethodImplOptions.AggressiveInlining)] 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 Unsafe.AsRef(t[0])); + return MemoryMarshal.Read<Vector128<byte>>(t); - 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]); -#endif + return Vector128.Create( + BinaryPrimitives.ReadUInt64LittleEndian(t[..8]), + BinaryPrimitives.ReadUInt64LittleEndian(t[8..]) + ).AsByte(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Store128(Vector128<byte> s, Span<byte> t) { -#if NET7_0_OR_GREATER - Vector128.CopyTo(s, t); -#else if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16) { - Unsafe.WriteUnaligned(ref t[0], s); + MemoryMarshal.Write(t, ref s); return; } var u = s.AsUInt64(); - Utilities.Pack.UInt64_To_LE(u.GetElement(0), t); - Utilities.Pack.UInt64_To_LE(u.GetElement(1), t[8..]); -#endif + BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0)); + BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Store64(Vector64<byte> s, Span<byte> t) { -#if NET7_0_OR_GREATER - Vector64.CopyTo(s, t); -#else if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector64<byte>>() == 8) { - Unsafe.WriteUnaligned(ref t[0], s); + MemoryMarshal.Write(t, ref s); return; } var u = s.AsUInt64(); - Utilities.Pack.UInt64_To_LE(u.ToScalar(), t); -#endif + BinaryPrimitives.WriteUInt64LittleEndian(t, u.ToScalar()); } } } diff --git a/crypto/src/crypto/digests/HarakaBase.cs b/crypto/src/crypto/digests/HarakaBase.cs index 37dda2163..1ca688914 100644 --- a/crypto/src/crypto/digests/HarakaBase.cs +++ b/crypto/src/crypto/digests/HarakaBase.cs @@ -102,7 +102,7 @@ namespace Org.BouncyCastle.Crypto.Digests s = SubBytes(s); s = ShiftRows(s); s = MixColumns(s); - XorWith(rk, s); + XorTo(rk, s); return s; } @@ -131,11 +131,14 @@ namespace Org.BouncyCastle.Crypto.Digests } #endif - private static void XorWith(byte[] x, byte[] z) + private static void XorTo(byte[] x, byte[] z) { - for (int i = 0; i < 16; ++i) + for (int i = 0; i < 16; i += 4) { - z[i] ^= x[i]; + z[i + 0] ^= x[i + 0]; + z[i + 1] ^= x[i + 1]; + z[i + 2] ^= x[i + 2]; + z[i + 3] ^= x[i + 3]; } } diff --git a/crypto/src/crypto/digests/KeccakDigest.cs b/crypto/src/crypto/digests/KeccakDigest.cs index b8305cc13..9f4a36b88 100644 --- a/crypto/src/crypto/digests/KeccakDigest.cs +++ b/crypto/src/crypto/digests/KeccakDigest.cs @@ -407,11 +407,11 @@ namespace Org.BouncyCastle.Crypto.Digests ulong c3 = a03 ^ a08 ^ a13 ^ a18 ^ a23; ulong c4 = a04 ^ a09 ^ a14 ^ a19 ^ a24; - ulong d1 = (c1 << 1 | c1 >> -1) ^ c4; - ulong d2 = (c2 << 1 | c2 >> -1) ^ c0; - ulong d3 = (c3 << 1 | c3 >> -1) ^ c1; - ulong d4 = (c4 << 1 | c4 >> -1) ^ c2; - ulong d0 = (c0 << 1 | c0 >> -1) ^ c3; + ulong d1 = Longs.RotateLeft(c1, 1) ^ c4; + ulong d2 = Longs.RotateLeft(c2, 1) ^ c0; + ulong d3 = Longs.RotateLeft(c3, 1) ^ c1; + ulong d4 = Longs.RotateLeft(c4, 1) ^ c2; + ulong d0 = Longs.RotateLeft(c0, 1) ^ c3; a00 ^= d1; a05 ^= d1; a10 ^= d1; a15 ^= d1; a20 ^= d1; a01 ^= d2; a06 ^= d2; a11 ^= d2; a16 ^= d2; a21 ^= d2; @@ -420,30 +420,30 @@ namespace Org.BouncyCastle.Crypto.Digests a04 ^= d0; a09 ^= d0; a14 ^= d0; a19 ^= d0; a24 ^= d0; // rho/pi - c1 = a01 << 1 | a01 >> 63; - a01 = a06 << 44 | a06 >> 20; - a06 = a09 << 20 | a09 >> 44; - a09 = a22 << 61 | a22 >> 3; - a22 = a14 << 39 | a14 >> 25; - a14 = a20 << 18 | a20 >> 46; - a20 = a02 << 62 | a02 >> 2; - a02 = a12 << 43 | a12 >> 21; - a12 = a13 << 25 | a13 >> 39; - a13 = a19 << 8 | a19 >> 56; - a19 = a23 << 56 | a23 >> 8; - a23 = a15 << 41 | a15 >> 23; - a15 = a04 << 27 | a04 >> 37; - a04 = a24 << 14 | a24 >> 50; - a24 = a21 << 2 | a21 >> 62; - a21 = a08 << 55 | a08 >> 9; - a08 = a16 << 45 | a16 >> 19; - a16 = a05 << 36 | a05 >> 28; - a05 = a03 << 28 | a03 >> 36; - a03 = a18 << 21 | a18 >> 43; - a18 = a17 << 15 | a17 >> 49; - a17 = a11 << 10 | a11 >> 54; - a11 = a07 << 6 | a07 >> 58; - a07 = a10 << 3 | a10 >> 61; + c1 = Longs.RotateLeft(a01, 1); + a01 = Longs.RotateLeft(a06, 44); + a06 = Longs.RotateLeft(a09, 20); + a09 = Longs.RotateLeft(a22, 61); + a22 = Longs.RotateLeft(a14, 39); + a14 = Longs.RotateLeft(a20, 18); + a20 = Longs.RotateLeft(a02, 62); + a02 = Longs.RotateLeft(a12, 43); + a12 = Longs.RotateLeft(a13, 25); + a13 = Longs.RotateLeft(a19, 8); + a19 = Longs.RotateLeft(a23, 56); + a23 = Longs.RotateLeft(a15, 41); + a15 = Longs.RotateLeft(a04, 27); + a04 = Longs.RotateLeft(a24, 14); + a24 = Longs.RotateLeft(a21, 2); + a21 = Longs.RotateLeft(a08, 55); + a08 = Longs.RotateLeft(a16, 45); + a16 = Longs.RotateLeft(a05, 36); + a05 = Longs.RotateLeft(a03, 28); + a03 = Longs.RotateLeft(a18, 21); + a18 = Longs.RotateLeft(a17, 15); + a17 = Longs.RotateLeft(a11, 10); + a11 = Longs.RotateLeft(a07, 6); + a07 = Longs.RotateLeft(a10, 3); a10 = c1; // chi diff --git a/crypto/src/crypto/encodings/OaepEncoding.cs b/crypto/src/crypto/encodings/OaepEncoding.cs index c151b7ac5..6871a039a 100644 --- a/crypto/src/crypto/encodings/OaepEncoding.cs +++ b/crypto/src/crypto/encodings/OaepEncoding.cs @@ -74,7 +74,7 @@ namespace Org.BouncyCastle.Crypto.Encodings } else { - this.random = new SecureRandom(); + this.random = CryptoServicesRegistrar.GetSecureRandom(); } engine.Init(forEncryption, parameters); diff --git a/crypto/src/crypto/encodings/Pkcs1Encoding.cs b/crypto/src/crypto/encodings/Pkcs1Encoding.cs index 5faf7f385..06e59d4f3 100644 --- a/crypto/src/crypto/encodings/Pkcs1Encoding.cs +++ b/crypto/src/crypto/encodings/Pkcs1Encoding.cs @@ -110,7 +110,7 @@ namespace Org.BouncyCastle.Crypto.Encodings } else { - this.random = new SecureRandom(); + this.random = CryptoServicesRegistrar.GetSecureRandom(); kParam = (AsymmetricKeyParameter)parameters; } diff --git a/crypto/src/crypto/engines/AesEngine_X86.cs b/crypto/src/crypto/engines/AesEngine_X86.cs index 32a58f2e3..e61deb174 100644 --- a/crypto/src/crypto/engines/AesEngine_X86.cs +++ b/crypto/src/crypto/engines/AesEngine_X86.cs @@ -1,6 +1,8 @@ #if NETCOREAPP3_0_OR_GREATER using System; +using System.Buffers.Binary; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using Org.BouncyCastle.Crypto.Parameters; @@ -16,7 +18,6 @@ namespace Org.BouncyCastle.Crypto.Engines { public static bool IsSupported => Aes.IsSupported; - [MethodImpl(MethodImplOptions.AggressiveOptimization)] private static Vector128<byte>[] CreateRoundKeys(byte[] key, bool forEncryption) { Vector128<byte>[] K; @@ -217,7 +218,7 @@ namespace Org.BouncyCastle.Crypto.Engines return 64; } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ImplRounds(ref Vector128<byte> state) { switch (m_mode) @@ -232,7 +233,7 @@ namespace Org.BouncyCastle.Crypto.Engines } } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ImplRounds( ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4) { @@ -248,7 +249,7 @@ namespace Org.BouncyCastle.Crypto.Engines } } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Decrypt128(Vector128<byte>[] roundKeys, ref Vector128<byte> state) { state = Sse2.Xor(state, roundKeys[0]); @@ -264,7 +265,7 @@ namespace Org.BouncyCastle.Crypto.Engines state = Aes.DecryptLast(state, roundKeys[10]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Decrypt192(Vector128<byte>[] roundKeys, ref Vector128<byte> state) { state = Sse2.Xor(state, roundKeys[0]); @@ -282,7 +283,7 @@ namespace Org.BouncyCastle.Crypto.Engines state = Aes.DecryptLast(state, roundKeys[12]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Decrypt256(Vector128<byte>[] roundKeys, ref Vector128<byte> state) { state = Sse2.Xor(state, roundKeys[0]); @@ -302,7 +303,7 @@ namespace Org.BouncyCastle.Crypto.Engines state = Aes.DecryptLast(state, roundKeys[14]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecryptFour128(Vector128<byte>[] rk, ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4) { @@ -362,7 +363,7 @@ namespace Org.BouncyCastle.Crypto.Engines s4 = Aes.DecryptLast(s4, rk[10]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecryptFour192(Vector128<byte>[] rk, ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4) { @@ -432,7 +433,7 @@ namespace Org.BouncyCastle.Crypto.Engines s4 = Aes.DecryptLast(s4, rk[12]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecryptFour256(Vector128<byte>[] rk, ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4) { @@ -512,7 +513,7 @@ namespace Org.BouncyCastle.Crypto.Engines s4 = Aes.DecryptLast(s4, rk[14]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Encrypt128(Vector128<byte>[] roundKeys, ref Vector128<byte> state) { state = Sse2.Xor(state, roundKeys[0]); @@ -528,7 +529,7 @@ namespace Org.BouncyCastle.Crypto.Engines state = Aes.EncryptLast(state, roundKeys[10]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Encrypt192(Vector128<byte>[] roundKeys, ref Vector128<byte> state) { state = Sse2.Xor(state, roundKeys[0]); @@ -546,7 +547,7 @@ namespace Org.BouncyCastle.Crypto.Engines state = Aes.EncryptLast(state, roundKeys[12]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Encrypt256(Vector128<byte>[] roundKeys, ref Vector128<byte> state) { state = Sse2.Xor(state, roundKeys[0]); @@ -566,7 +567,7 @@ namespace Org.BouncyCastle.Crypto.Engines state = Aes.EncryptLast(state, roundKeys[14]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void EncryptFour128(Vector128<byte>[] rk, ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4) { @@ -626,7 +627,7 @@ namespace Org.BouncyCastle.Crypto.Engines s4 = Aes.EncryptLast(s4, rk[10]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void EncryptFour192(Vector128<byte>[] rk, ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4) { @@ -696,7 +697,7 @@ namespace Org.BouncyCastle.Crypto.Engines s4 = Aes.EncryptLast(s4, rk[12]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void EncryptFour256(Vector128<byte>[] rk, ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4) { @@ -776,34 +777,38 @@ namespace Org.BouncyCastle.Crypto.Engines s4 = Aes.EncryptLast(s4, rk[14]); } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] 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 Unsafe.AsRef(t[0])); + return MemoryMarshal.Read<Vector128<byte>>(t); - 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]); + return Vector128.Create( + BinaryPrimitives.ReadUInt64LittleEndian(t[..8]), + BinaryPrimitives.ReadUInt64LittleEndian(t[8..]) + ).AsByte(); #endif } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] 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 Unsafe.AsRef(t[0])); + return MemoryMarshal.Read<Vector64<byte>>(t); - return Vector64.Create(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]); + return Vector64.Create( + BinaryPrimitives.ReadUInt64LittleEndian(t[..8]) + ).AsByte(); #endif } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Store128(Vector128<byte> s, Span<byte> t) { #if NET7_0_OR_GREATER @@ -811,13 +816,13 @@ namespace Org.BouncyCastle.Crypto.Engines #else if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16) { - Unsafe.WriteUnaligned(ref t[0], s); + MemoryMarshal.Write(t, ref s); return; } var u = s.AsUInt64(); - Utilities.Pack.UInt64_To_LE(u.GetElement(0), t); - Utilities.Pack.UInt64_To_LE(u.GetElement(1), t[8..]); + BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0)); + BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1)); #endif } } diff --git a/crypto/src/crypto/engines/ChaCha7539Engine.cs b/crypto/src/crypto/engines/ChaCha7539Engine.cs index f6e34b93a..d9cdac541 100644 --- a/crypto/src/crypto/engines/ChaCha7539Engine.cs +++ b/crypto/src/crypto/engines/ChaCha7539Engine.cs @@ -4,6 +4,8 @@ using System.Diagnostics; using System.Runtime.CompilerServices; #endif #if NETCOREAPP3_0_OR_GREATER +using System.Buffers.Binary; +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; #endif @@ -453,18 +455,20 @@ namespace Org.BouncyCastle.Crypto.Engines [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector128<byte> Load128_Byte(ReadOnlySpan<byte> t) { - if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16) - return Unsafe.ReadUnaligned<Vector128<byte>>(ref Unsafe.AsRef(t[0])); + if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16) + return MemoryMarshal.Read<Vector128<byte>>(t); - 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]); - } + return Vector128.Create( + BinaryPrimitives.ReadUInt64LittleEndian(t[..8]), + BinaryPrimitives.ReadUInt64LittleEndian(t[8..]) + ).AsByte(); + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] 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 Unsafe.AsRef(t[0]))); + return MemoryMarshal.Read<Vector128<uint>>(MemoryMarshal.AsBytes(t)); return Vector128.Create(t[0], t[1], t[2], t[3]); } @@ -472,42 +476,45 @@ namespace Org.BouncyCastle.Crypto.Engines [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256<byte> Load256_Byte(ReadOnlySpan<byte> t) { - if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector256<byte>>() == 32) - 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], - t[28], t[29], t[30], t[31]); + if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector256<byte>>() == 32) + return MemoryMarshal.Read<Vector256<byte>>(t); + + return Vector256.Create( + BinaryPrimitives.ReadUInt64LittleEndian(t[ 0.. 8]), + BinaryPrimitives.ReadUInt64LittleEndian(t[ 8..16]), + BinaryPrimitives.ReadUInt64LittleEndian(t[16..24]), + BinaryPrimitives.ReadUInt64LittleEndian(t[24..32]) + ).AsByte(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Store128_Byte(Vector128<byte> s, Span<byte> t) { - if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16) - { - Unsafe.WriteUnaligned(ref t[0], s); - return; - } + if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16) + { + MemoryMarshal.Write(t, ref s); + return; + } - var u = s.AsUInt64(); - Pack.UInt64_To_LE(u.GetElement(0), t); - Pack.UInt64_To_LE(u.GetElement(1), t[8..]); + var u = s.AsUInt64(); + BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0)); + BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Store256_Byte(Vector256<byte> s, Span<byte> t) { - if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector256<byte>>() == 32) + if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector256<byte>>() == 32) { - Unsafe.WriteUnaligned(ref t[0], s); + MemoryMarshal.Write(t, ref s); return; } var u = s.AsUInt64(); - Pack.UInt64_To_LE(u.GetElement(0), t); - 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..]); + BinaryPrimitives.WriteUInt64LittleEndian(t[ 0.. 8], u.GetElement(0)); + BinaryPrimitives.WriteUInt64LittleEndian(t[ 8..16], u.GetElement(1)); + BinaryPrimitives.WriteUInt64LittleEndian(t[16..24], u.GetElement(2)); + BinaryPrimitives.WriteUInt64LittleEndian(t[24..32], u.GetElement(3)); } #endif } diff --git a/crypto/src/crypto/engines/ChaChaEngine.cs b/crypto/src/crypto/engines/ChaChaEngine.cs index 2683e335a..093e1a250 100644 --- a/crypto/src/crypto/engines/ChaChaEngine.cs +++ b/crypto/src/crypto/engines/ChaChaEngine.cs @@ -1,7 +1,9 @@ using System; using System.Diagnostics; #if NETCOREAPP3_0_OR_GREATER +using System.Buffers.Binary; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; #endif @@ -215,10 +217,10 @@ namespace Org.BouncyCastle.Crypto.Engines [MethodImpl(MethodImplOptions.AggressiveInlining)] 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 Unsafe.AsRef(t[0]))); + if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<uint>>() == 16) + return MemoryMarshal.Read<Vector128<uint>>(MemoryMarshal.AsBytes(t)); - return Vector128.Create(t[0], t[1], t[2], t[3]); + return Vector128.Create(t[0], t[1], t[2], t[3]); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -226,13 +228,13 @@ namespace Org.BouncyCastle.Crypto.Engines { if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<uint>>() == 16) { - Unsafe.WriteUnaligned(ref t[0], s); + MemoryMarshal.Write(t, ref s); return; } var u = s.AsUInt64(); - Pack.UInt64_To_LE(u.GetElement(0), t); - Pack.UInt64_To_LE(u.GetElement(1), t[8..]); + BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0)); + BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1)); } #endif } diff --git a/crypto/src/crypto/engines/DesEdeWrapEngine.cs b/crypto/src/crypto/engines/DesEdeWrapEngine.cs index 43100a9bd..e05f9f555 100644 --- a/crypto/src/crypto/engines/DesEdeWrapEngine.cs +++ b/crypto/src/crypto/engines/DesEdeWrapEngine.cs @@ -60,15 +60,14 @@ namespace Org.BouncyCastle.Crypto.Engines this.engine = new CbcBlockCipher(new DesEdeEngine()); SecureRandom sr; - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom pr) { - ParametersWithRandom pr = (ParametersWithRandom) parameters; parameters = pr.Parameters; sr = pr.Random; } else { - sr = new SecureRandom(); + sr = CryptoServicesRegistrar.GetSecureRandom(); } if (parameters is KeyParameter) diff --git a/crypto/src/crypto/engines/ElGamalEngine.cs b/crypto/src/crypto/engines/ElGamalEngine.cs index 197d7bc15..ea5e5bc30 100644 --- a/crypto/src/crypto/engines/ElGamalEngine.cs +++ b/crypto/src/crypto/engines/ElGamalEngine.cs @@ -28,22 +28,18 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary ElGamal key parameters. */ - public virtual void Init( - bool forEncryption, - ICipherParameters parameters) + public virtual void Init(bool forEncryption, ICipherParameters parameters) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - ParametersWithRandom p = (ParametersWithRandom) parameters; - - this.key = (ElGamalKeyParameters) p.Parameters; - this.random = p.Random; + this.key = (ElGamalKeyParameters)withRandom.Parameters; + this.random = withRandom.Random; } else { - this.key = (ElGamalKeyParameters) parameters; - this.random = new SecureRandom(); - } + this.key = (ElGamalKeyParameters)parameters; + this.random = CryptoServicesRegistrar.GetSecureRandom(); + } this.forEncryption = forEncryption; this.bitSize = key.Parameters.P.BitLength; @@ -51,16 +47,12 @@ namespace Org.BouncyCastle.Crypto.Engines if (forEncryption) { if (!(key is ElGamalPublicKeyParameters)) - { throw new ArgumentException("ElGamalPublicKeyParameters are required for encryption."); - } } else { if (!(key is ElGamalPrivateKeyParameters)) - { throw new ArgumentException("ElGamalPrivateKeyParameters are required for decryption."); - } } } diff --git a/crypto/src/crypto/engines/RC2WrapEngine.cs b/crypto/src/crypto/engines/RC2WrapEngine.cs index 5742aa8b7..91ac7ded2 100644 --- a/crypto/src/crypto/engines/RC2WrapEngine.cs +++ b/crypto/src/crypto/engines/RC2WrapEngine.cs @@ -42,8 +42,8 @@ namespace Org.BouncyCastle.Crypto.Engines // // checksum digest // - IDigest sha1 = new Sha1Digest(); - byte[] digest = new byte[20]; + private readonly IDigest sha1 = new Sha1Digest(); + private readonly byte[] digest = new byte[20]; /** * Method init @@ -51,22 +51,19 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forWrapping * @param param */ - public virtual void Init( - bool forWrapping, - ICipherParameters parameters) + public virtual void Init(bool forWrapping, ICipherParameters parameters) { this.forWrapping = forWrapping; this.engine = new CbcBlockCipher(new RC2Engine()); - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom pWithR) { - ParametersWithRandom pWithR = (ParametersWithRandom)parameters; sr = pWithR.Random; parameters = pWithR.Parameters; } else { - sr = new SecureRandom(); + sr = CryptoServicesRegistrar.GetSecureRandom(); } if (parameters is ParametersWithIV) diff --git a/crypto/src/crypto/engines/RFC3211WrapEngine.cs b/crypto/src/crypto/engines/RFC3211WrapEngine.cs index 3fc7b3191..42027cf25 100644 --- a/crypto/src/crypto/engines/RFC3211WrapEngine.cs +++ b/crypto/src/crypto/engines/RFC3211WrapEngine.cs @@ -24,24 +24,20 @@ namespace Org.BouncyCastle.Crypto.Engines this.engine = new CbcBlockCipher(engine); } - public virtual void Init( - bool forWrapping, - ICipherParameters param) + public virtual void Init(bool forWrapping, ICipherParameters param) { this.forWrapping = forWrapping; - if (param is ParametersWithRandom) + if (param is ParametersWithRandom withRandom) { - ParametersWithRandom p = (ParametersWithRandom)param; - - this.rand = p.Random; - this.param = p.Parameters as ParametersWithIV; + this.rand = withRandom.Random; + this.param = withRandom.Parameters as ParametersWithIV; } else { if (forWrapping) { - rand = new SecureRandom(); + rand = CryptoServicesRegistrar.GetSecureRandom(); } this.param = param as ParametersWithIV; diff --git a/crypto/src/crypto/engines/RSABlindedEngine.cs b/crypto/src/crypto/engines/RSABlindedEngine.cs index 637bf3cc0..cdc0a7844 100644 --- a/crypto/src/crypto/engines/RSABlindedEngine.cs +++ b/crypto/src/crypto/engines/RSABlindedEngine.cs @@ -39,16 +39,12 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary RSA key parameters. */ - public virtual void Init( - bool forEncryption, - ICipherParameters param) + public virtual void Init(bool forEncryption, ICipherParameters param) { core.Init(forEncryption, param); - if (param is ParametersWithRandom) + if (param is ParametersWithRandom rParam) { - ParametersWithRandom rParam = (ParametersWithRandom)param; - this.key = (RsaKeyParameters)rParam.Parameters; if (key is RsaPrivateCrtKeyParameters) @@ -66,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Engines if (key is RsaPrivateCrtKeyParameters) { - this.random = new SecureRandom(); + this.random = CryptoServicesRegistrar.GetSecureRandom(); } else { diff --git a/crypto/src/crypto/engines/Salsa20Engine.cs b/crypto/src/crypto/engines/Salsa20Engine.cs index c3e44f645..1ccf68902 100644 --- a/crypto/src/crypto/engines/Salsa20Engine.cs +++ b/crypto/src/crypto/engines/Salsa20Engine.cs @@ -1,5 +1,12 @@ using System; -using System.Text; +#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER +using System.Runtime.CompilerServices; +#endif +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; @@ -254,7 +261,71 @@ namespace Org.BouncyCastle.Crypto.Engines if (rounds % 2 != 0) throw new ArgumentException("Number of rounds must be even"); - uint x00 = input[ 0]; +#if NETCOREAPP3_0_OR_GREATER + if (Sse41.IsSupported && BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<short>>() == 16) + { + Vector128<uint> b0, b1, b2, b3; + { + var I = MemoryMarshal.AsBytes(input.AsSpan(0, 16)); + var t0 = MemoryMarshal.Read<Vector128<short>>(I[0x00..0x10]); + var t1 = MemoryMarshal.Read<Vector128<short>>(I[0x10..0x20]); + var t2 = MemoryMarshal.Read<Vector128<short>>(I[0x20..0x30]); + var t3 = MemoryMarshal.Read<Vector128<short>>(I[0x30..0x40]); + + var u0 = Sse41.Blend(t0, t2, 0xF0); + var u1 = Sse41.Blend(t1, t3, 0xC3); + var u2 = Sse41.Blend(t0, t2, 0x0F); + var u3 = Sse41.Blend(t1, t3, 0x3C); + + b0 = Sse41.Blend(u0, u1, 0xCC).AsUInt32(); + b1 = Sse41.Blend(u0, u1, 0x33).AsUInt32(); + b2 = Sse41.Blend(u2, u3, 0xCC).AsUInt32(); + b3 = Sse41.Blend(u2, u3, 0x33).AsUInt32(); + } + + var c0 = b0; + var c1 = b1; + var c2 = b2; + var c3 = b3; + + for (int i = rounds; i > 0; i -= 2) + { + QuarterRound_Sse2(ref c0, ref c3, ref c2, ref c1); + QuarterRound_Sse2(ref c0, ref c1, ref c2, ref c3); + } + + b0 = Sse2.Add(b0, c0); + b1 = Sse2.Add(b1, c1); + b2 = Sse2.Add(b2, c2); + b3 = Sse2.Add(b3, c3); + + { + var t0 = b0.AsUInt16(); + var t1 = b1.AsUInt16(); + var t2 = b2.AsUInt16(); + var t3 = b3.AsUInt16(); + + var u0 = Sse41.Blend(t0, t1, 0xCC); + var u1 = Sse41.Blend(t0, t1, 0x33); + var u2 = Sse41.Blend(t2, t3, 0xCC); + var u3 = Sse41.Blend(t2, t3, 0x33); + + var v0 = Sse41.Blend(u0, u2, 0xF0); + var v1 = Sse41.Blend(u1, u3, 0xC3); + var v2 = Sse41.Blend(u0, u2, 0x0F); + var v3 = Sse41.Blend(u1, u3, 0x3C); + + var X = MemoryMarshal.AsBytes(x.AsSpan(0, 16)); + MemoryMarshal.Write(X[0x00..0x10], ref v0); + MemoryMarshal.Write(X[0x10..0x20], ref v1); + MemoryMarshal.Write(X[0x20..0x30], ref v2); + MemoryMarshal.Write(X[0x30..0x40], ref v3); + } + return; + } +#endif + + uint x00 = input[ 0]; uint x01 = input[ 1]; uint x02 = input[ 2]; uint x03 = input[ 3]; @@ -273,39 +344,15 @@ namespace Org.BouncyCastle.Crypto.Engines for (int i = rounds; i > 0; i -= 2) { - x04 ^= Integers.RotateLeft((x00+x12), 7); - x08 ^= Integers.RotateLeft((x04+x00), 9); - x12 ^= Integers.RotateLeft((x08+x04),13); - x00 ^= Integers.RotateLeft((x12+x08),18); - x09 ^= Integers.RotateLeft((x05+x01), 7); - x13 ^= Integers.RotateLeft((x09+x05), 9); - x01 ^= Integers.RotateLeft((x13+x09),13); - x05 ^= Integers.RotateLeft((x01+x13),18); - x14 ^= Integers.RotateLeft((x10+x06), 7); - x02 ^= Integers.RotateLeft((x14+x10), 9); - x06 ^= Integers.RotateLeft((x02+x14),13); - x10 ^= Integers.RotateLeft((x06+x02),18); - x03 ^= Integers.RotateLeft((x15+x11), 7); - x07 ^= Integers.RotateLeft((x03+x15), 9); - x11 ^= Integers.RotateLeft((x07+x03),13); - x15 ^= Integers.RotateLeft((x11+x07),18); - - x01 ^= Integers.RotateLeft((x00+x03), 7); - x02 ^= Integers.RotateLeft((x01+x00), 9); - x03 ^= Integers.RotateLeft((x02+x01),13); - x00 ^= Integers.RotateLeft((x03+x02),18); - x06 ^= Integers.RotateLeft((x05+x04), 7); - x07 ^= Integers.RotateLeft((x06+x05), 9); - x04 ^= Integers.RotateLeft((x07+x06),13); - x05 ^= Integers.RotateLeft((x04+x07),18); - x11 ^= Integers.RotateLeft((x10+x09), 7); - x08 ^= Integers.RotateLeft((x11+x10), 9); - x09 ^= Integers.RotateLeft((x08+x11),13); - x10 ^= Integers.RotateLeft((x09+x08),18); - x12 ^= Integers.RotateLeft((x15+x14), 7); - x13 ^= Integers.RotateLeft((x12+x15), 9); - x14 ^= Integers.RotateLeft((x13+x12),13); - x15 ^= Integers.RotateLeft((x14+x13),18); + QuarterRound(ref x00, ref x04, ref x08, ref x12); + QuarterRound(ref x05, ref x09, ref x13, ref x01); + QuarterRound(ref x10, ref x14, ref x02, ref x06); + QuarterRound(ref x15, ref x03, ref x07, ref x11); + + QuarterRound(ref x00, ref x01, ref x02, ref x03); + QuarterRound(ref x05, ref x06, ref x07, ref x04); + QuarterRound(ref x10, ref x11, ref x08, ref x09); + QuarterRound(ref x15, ref x12, ref x13, ref x14); } x[ 0] = x00 + input[ 0]; @@ -364,5 +411,39 @@ namespace Org.BouncyCastle.Crypto.Engines return false; } - } + +#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + private static void QuarterRound(ref uint a, ref uint b, ref uint c, ref uint d) + { + b ^= Integers.RotateLeft(a + d, 7); + c ^= Integers.RotateLeft(b + a, 9); + d ^= Integers.RotateLeft(c + b, 13); + a ^= Integers.RotateLeft(d + c, 18); + } + +#if NETCOREAPP3_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void QuarterRound_Sse2(ref Vector128<uint> a, ref Vector128<uint> b, ref Vector128<uint> c, + ref Vector128<uint> d) + { + b = Sse2.Xor(b, Rotate_Sse2(Sse2.Add(a, d), 7)); + c = Sse2.Xor(c, Rotate_Sse2(Sse2.Add(b, a), 9)); + d = Sse2.Xor(d, Rotate_Sse2(Sse2.Add(c, b), 13)); + a = Sse2.Xor(a, Rotate_Sse2(Sse2.Add(d, c), 18)); + + b = Sse2.Shuffle(b, 0x93); + c = Sse2.Shuffle(c, 0x4E); + d = Sse2.Shuffle(d, 0x39); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128<uint> Rotate_Sse2(Vector128<uint> x, byte sl) + { + byte sr = (byte)(32 - sl); + return Sse2.Xor(Sse2.ShiftLeftLogical(x, sl), Sse2.ShiftRightLogical(x, sr)); + } +#endif + } } diff --git a/crypto/src/crypto/engines/VMPCEngine.cs b/crypto/src/crypto/engines/VMPCEngine.cs index d8974b6ce..f34259248 100644 --- a/crypto/src/crypto/engines/VMPCEngine.cs +++ b/crypto/src/crypto/engines/VMPCEngine.cs @@ -97,16 +97,17 @@ namespace Org.BouncyCastle.Crypto.Engines for (int i = 0; i < len; i++) { - s = P[(s + P[n & 0xff]) & 0xff]; - byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + byte pn = P[n]; + s = P[(s + pn) & 0xff]; + byte ps = P[s]; + byte z = P[(P[ps] + 1) & 0xff]; // encryption - byte temp = P[n & 0xff]; - P[n & 0xff] = P[s & 0xff]; - P[s & 0xff] = temp; - n = (byte) ((n + 1) & 0xff); + P[n] = ps; + P[s] = pn; + n = (byte)(n + 1); // xor - output[i + outOff] = (byte) (input[i + inOff] ^ z); + output[i + outOff] = (byte)(input[i + inOff] ^ z); } } @@ -117,13 +118,14 @@ namespace Org.BouncyCastle.Crypto.Engines for (int i = 0; i < input.Length; i++) { - s = P[(s + P[n & 0xff]) & 0xff]; - byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + byte pn = P[n]; + s = P[(s + pn) & 0xff]; + byte ps = P[s]; + byte z = P[(P[ps] + 1) & 0xff]; // encryption - byte temp = P[n & 0xff]; - P[n & 0xff] = P[s & 0xff]; - P[s & 0xff] = temp; - n = (byte)((n + 1) & 0xff); + P[n] = ps; + P[s] = pn; + n = (byte)(n + 1); // xor output[i] = (byte)(input[i] ^ z); diff --git a/crypto/src/crypto/fpe/SP80038G.cs b/crypto/src/crypto/fpe/SP80038G.cs index 53efc1499..a9dc7f144 100644 --- a/crypto/src/crypto/fpe/SP80038G.cs +++ b/crypto/src/crypto/fpe/SP80038G.cs @@ -301,14 +301,13 @@ namespace Org.BouncyCastle.Crypto.Fpe int t = T.Length; // i. - BigInteger numAB = num(bigRadix, AB); - byte[] bytesAB = BigIntegers.AsUnsignedByteArray(numAB); - int zeroes = -(t + b + 1) & 15; byte[] Q = new byte[t + zeroes + 1 + b]; Array.Copy(T, 0, Q, 0, t); Q[t + zeroes] = (byte)round; - Array.Copy(bytesAB, 0, Q, Q.Length - bytesAB.Length, bytesAB.Length); + + BigInteger numAB = num(bigRadix, AB); + BigIntegers.AsUnsignedByteArray(numAB, Q, Q.Length - b, b); // ii. byte[] R = prf(cipher, Arrays.Concatenate(P, Q)); @@ -319,47 +318,43 @@ namespace Org.BouncyCastle.Crypto.Fpe { int sBlocksLen = (d + BLOCK_SIZE - 1) / BLOCK_SIZE; sBlocks = new byte[sBlocksLen * BLOCK_SIZE]; + + uint j0 = Pack.BE_To_UInt32(R, BLOCK_SIZE - 4); Array.Copy(R, 0, sBlocks, 0, BLOCK_SIZE); - byte[] uint32 = new byte[4]; for (uint j = 1; j < sBlocksLen; ++j) { int sOff = (int)(j * BLOCK_SIZE); - Array.Copy(R, 0, sBlocks, sOff, BLOCK_SIZE); - Pack.UInt32_To_BE(j, uint32, 0); - xor(uint32, 0, sBlocks, sOff + BLOCK_SIZE - 4, 4); + + Array.Copy(R, 0, sBlocks, sOff, BLOCK_SIZE - 4); + Pack.UInt32_To_BE(j0 ^ j, sBlocks, sOff + BLOCK_SIZE - 4); + cipher.ProcessBlock(sBlocks, sOff, sBlocks, sOff); } } // iv. - return num(sBlocks, 0, d); + return new BigInteger(1, sBlocks, 0, d); } - protected static BigInteger calculateY_FF3(IBlockCipher cipher, BigInteger bigRadix, byte[] T, int wOff, uint round, ushort[] AB) + protected static BigInteger calculateY_FF3(IBlockCipher cipher, BigInteger bigRadix, byte[] T, int wOff, + uint round, ushort[] AB) { // ii. byte[] P = new byte[BLOCK_SIZE]; - Pack.UInt32_To_BE(round, P, 0); - xor(T, wOff, P, 0, 4); - BigInteger numAB = num(bigRadix, AB); - - byte[] bytesAB = BigIntegers.AsUnsignedByteArray(numAB); + Pack.UInt32_To_BE(Pack.BE_To_UInt32(T, wOff) ^ round, P, 0); - if ((P.Length - bytesAB.Length) < 4) // to be sure... - { - throw new InvalidOperationException("input out of range"); - } - Array.Copy(bytesAB, 0, P, P.Length - bytesAB.Length, bytesAB.Length); + BigInteger numAB = num(bigRadix, AB); + BigIntegers.AsUnsignedByteArray(numAB, P, 4, BLOCK_SIZE - 4); // iii. - rev(P); + Array.Reverse(P); cipher.ProcessBlock(P, 0, P, 0); - rev(P); + Array.Reverse(P); byte[] S = P; // iv. - return num(S, 0, S.Length); + return new BigInteger(1, S); } protected static void checkArgs(IBlockCipher cipher, bool isFF1, int radix, ushort[] buf, int off, int len) @@ -471,8 +466,8 @@ namespace Org.BouncyCastle.Crypto.Fpe int m = u; // Note we keep A, B in reverse order throughout - rev(A); - rev(B); + Array.Reverse(A); + Array.Reverse(B); for (int i = 7; i >= 0; --i) { @@ -494,8 +489,8 @@ namespace Org.BouncyCastle.Crypto.Fpe str(bigRadix, c, m, C, 0); } - rev(A); - rev(B); + Array.Reverse(A); + Array.Reverse(B); return Arrays.Concatenate(A, B); } @@ -539,8 +534,8 @@ namespace Org.BouncyCastle.Crypto.Fpe int m = v; // Note we keep A, B in reverse order throughout - rev(a); - rev(b); + Array.Reverse(a); + Array.Reverse(b); for (uint i = 0; i < 8; ++i) { @@ -562,17 +557,12 @@ namespace Org.BouncyCastle.Crypto.Fpe str(bigRadix, c, m, C, 0); } - rev(a); - rev(b); + Array.Reverse(a); + Array.Reverse(b); return Arrays.Concatenate(a, b); } - protected static BigInteger num(byte[] buf, int off, int len) - { - return new BigInteger(1, Arrays.CopyOfRange(buf, off, off + len)); - } - protected static BigInteger num(BigInteger R, ushort[] x) { BigInteger result = BigInteger.Zero; @@ -586,9 +576,7 @@ namespace Org.BouncyCastle.Crypto.Fpe protected static byte[] prf(IBlockCipher c, byte[] x) { if ((x.Length % BLOCK_SIZE) != 0) - { throw new ArgumentException(); - } int m = x.Length / BLOCK_SIZE; byte[] y = new byte[BLOCK_SIZE]; @@ -602,42 +590,11 @@ namespace Org.BouncyCastle.Crypto.Fpe return y; } - // protected static void rev(byte[] x, int xOff, byte[] y, int yOff, int len) - // { - // for (int i = 1; i <= len; ++i) - // { - // y[yOff + len - i] = x[xOff + i - 1]; - // } - // } - - protected static void rev(byte[] x) - { - int half = x.Length / 2, end = x.Length - 1; - for (int i = 0; i < half; ++i) - { - byte tmp = x[i]; - x[i] = x[end - i]; - x[end - i] = tmp; - } - } - - protected static void rev(ushort[] x) - { - int half = x.Length / 2, end = x.Length - 1; - for (int i = 0; i < half; ++i) - { - ushort tmp = x[i]; - x[i] = x[end - i]; - x[end - i] = tmp; - } - } - protected static void str(BigInteger R, BigInteger x, int m, ushort[] output, int off) { if (x.SignValue < 0) - { throw new ArgumentException(); - } + for (int i = 1; i <= m; ++i) { BigInteger[] qr = x.DivideAndRemainder(R); @@ -645,9 +602,7 @@ namespace Org.BouncyCastle.Crypto.Fpe x = qr[0]; } if (x.SignValue != 0) - { throw new ArgumentException(); - } } protected static void xor(byte[] x, int xOff, byte[] y, int yOff, int len) diff --git a/crypto/src/crypto/generators/ECKeyPairGenerator.cs b/crypto/src/crypto/generators/ECKeyPairGenerator.cs index 7b6ee168b..6aba6921e 100644 --- a/crypto/src/crypto/generators/ECKeyPairGenerator.cs +++ b/crypto/src/crypto/generators/ECKeyPairGenerator.cs @@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Crypto.Generators if (this.random == null) { - this.random = new SecureRandom(); + this.random = CryptoServicesRegistrar.GetSecureRandom(); } } diff --git a/crypto/src/crypto/generators/RSABlindingFactorGenerator.cs b/crypto/src/crypto/generators/RSABlindingFactorGenerator.cs index e2f63face..a9eeb46df 100644 --- a/crypto/src/crypto/generators/RSABlindingFactorGenerator.cs +++ b/crypto/src/crypto/generators/RSABlindingFactorGenerator.cs @@ -21,20 +21,17 @@ namespace Org.BouncyCastle.Crypto.Generators * * @param param the necessary RSA key parameters. */ - public void Init( - ICipherParameters param) + public void Init(ICipherParameters param) { - if (param is ParametersWithRandom) + if (param is ParametersWithRandom rParam) { - ParametersWithRandom rParam = (ParametersWithRandom)param; - key = (RsaKeyParameters)rParam.Parameters; random = rParam.Random; } else { key = (RsaKeyParameters)param; - random = new SecureRandom(); + random = CryptoServicesRegistrar.GetSecureRandom(); } if (key.IsPrivate) diff --git a/crypto/src/crypto/generators/SCrypt.cs b/crypto/src/crypto/generators/SCrypt.cs index 0c51d89bc..1a8d4a003 100644 --- a/crypto/src/crypto/generators/SCrypt.cs +++ b/crypto/src/crypto/generators/SCrypt.cs @@ -5,6 +5,7 @@ using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Generators @@ -143,8 +144,8 @@ namespace Org.BouncyCastle.Crypto.Generators int j = (int)(X[BCount - 16] & mask); uint[] V = VV[j >> chunkPow]; int VOff = (j & chunkMask) * BCount; - Array.Copy(V, VOff, blockY, 0, BCount); - Xor(blockY, X, 0, blockY); + Nat.Xor(BCount, V, VOff, X, 0, blockY, 0); + BlockMix(blockY, blockX1, blockX2, X, r); } @@ -165,7 +166,7 @@ namespace Org.BouncyCastle.Crypto.Generators for (int i = 2 * r; i > 0; --i) { - Xor(X1, B, BOff, X2); + Nat512.Xor(X1, 0, B, BOff, X2, 0); Salsa20Engine.SalsaCore(8, X2, X1); Array.Copy(X1, 0, Y, YOff, 16); @@ -175,14 +176,6 @@ namespace Org.BouncyCastle.Crypto.Generators } } - private static void Xor(uint[] a, uint[] b, int bOff, uint[] output) - { - for (int i = output.Length - 1; i >= 0; --i) - { - output[i] = a[i] ^ b[bOff + i]; - } - } - private static void Clear(Array array) { if (array != null) diff --git a/crypto/src/crypto/macs/Poly1305.cs b/crypto/src/crypto/macs/Poly1305.cs index eb90e387e..d02216309 100644 --- a/crypto/src/crypto/macs/Poly1305.cs +++ b/crypto/src/crypto/macs/Poly1305.cs @@ -196,21 +196,13 @@ namespace Org.BouncyCastle.Crypto.Macs { Array.Copy(input, inOff, currentBlock, currentBlockOffset, available); pos = available; -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - ProcessBlock(currentBlock); -#else ProcessBlock(currentBlock, 0); -#endif } int remaining; while ((remaining = len - pos) >= BlockSize) { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - ProcessBlock(input.AsSpan(inOff + pos)); -#else ProcessBlock(input, inOff + pos); -#endif pos += BlockSize; } @@ -253,62 +245,24 @@ namespace Org.BouncyCastle.Crypto.Macs #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private void ProcessBlock(ReadOnlySpan<byte> block) { -#if NETCOREAPP3_0_OR_GREATER - if (BitConverter.IsLittleEndian) - { - Span<uint> t = stackalloc uint[4]; - Unsafe.CopyBlockUnaligned(ref Unsafe.As<uint, byte>(ref t[0]), ref Unsafe.AsRef(block[0]), 16); - - h0 += t[0] & 0x3ffffffU; - h1 += ((t[1] << 6) | (t[0] >> 26)) & 0x3ffffffU; - h2 += ((t[2] << 12) | (t[1] >> 20)) & 0x3ffffffU; - h3 += ((t[3] << 18) | (t[2] >> 14)) & 0x3ffffffU; - h4 += (1 << 24) | (t[3] >> 8); - } - else -#endif - { - uint t0 = Pack.LE_To_UInt32(block); - uint t1 = Pack.LE_To_UInt32(block[4..]); - uint t2 = Pack.LE_To_UInt32(block[8..]); - uint t3 = Pack.LE_To_UInt32(block[12..]); - - h0 += t0 & 0x3ffffffU; - h1 += ((t1 << 6) | (t0 >> 26)) & 0x3ffffffU; - h2 += ((t2 << 12) | (t1 >> 20)) & 0x3ffffffU; - h3 += ((t3 << 18) | (t2 >> 14)) & 0x3ffffffU; - h4 += ( 1 << 24) | (t3 >> 8); - } - - ulong tp0 = (ulong)h0 * r0 + (ulong)h1 * s4 + (ulong)h2 * s3 + (ulong)h3 * s2 + (ulong)h4 * s1; - ulong tp1 = (ulong)h0 * r1 + (ulong)h1 * r0 + (ulong)h2 * s4 + (ulong)h3 * s3 + (ulong)h4 * s2; - ulong tp2 = (ulong)h0 * r2 + (ulong)h1 * r1 + (ulong)h2 * r0 + (ulong)h3 * s4 + (ulong)h4 * s3; - ulong tp3 = (ulong)h0 * r3 + (ulong)h1 * r2 + (ulong)h2 * r1 + (ulong)h3 * r0 + (ulong)h4 * s4; - ulong tp4 = (ulong)h0 * r4 + (ulong)h1 * r3 + (ulong)h2 * r2 + (ulong)h3 * r1 + (ulong)h4 * r0; - - h0 = (uint)tp0 & 0x3ffffff; tp1 += (tp0 >> 26); - h1 = (uint)tp1 & 0x3ffffff; tp2 += (tp1 >> 26); - h2 = (uint)tp2 & 0x3ffffff; tp3 += (tp2 >> 26); - h3 = (uint)tp3 & 0x3ffffff; tp4 += (tp3 >> 26); - h4 = (uint)tp4 & 0x3ffffff; - h0 += (uint)(tp4 >> 26) * 5; - h1 += h0 >> 26; h0 &= 0x3ffffff; - } + uint t0 = Pack.LE_To_UInt32(block); + uint t1 = Pack.LE_To_UInt32(block[4..]); + uint t2 = Pack.LE_To_UInt32(block[8..]); + uint t3 = Pack.LE_To_UInt32(block[12..]); #else private void ProcessBlock(byte[] buf, int off) { - { - uint t0 = Pack.LE_To_UInt32(buf, off + 0); - uint t1 = Pack.LE_To_UInt32(buf, off + 4); - uint t2 = Pack.LE_To_UInt32(buf, off + 8); - uint t3 = Pack.LE_To_UInt32(buf, off + 12); - - h0 += t0 & 0x3ffffffU; - h1 += ((t1 << 6) | (t0 >> 26)) & 0x3ffffffU; - h2 += ((t2 << 12) | (t1 >> 20)) & 0x3ffffffU; - h3 += ((t3 << 18) | (t2 >> 14)) & 0x3ffffffU; - h4 += ( 1 << 24) | (t3 >> 8); - } + uint t0 = Pack.LE_To_UInt32(buf, off + 0); + uint t1 = Pack.LE_To_UInt32(buf, off + 4); + uint t2 = Pack.LE_To_UInt32(buf, off + 8); + uint t3 = Pack.LE_To_UInt32(buf, off + 12); +#endif + + h0 += t0 & 0x3ffffffU; + h1 += ((t1 << 6) | (t0 >> 26)) & 0x3ffffffU; + h2 += ((t2 << 12) | (t1 >> 20)) & 0x3ffffffU; + h3 += ((t3 << 18) | (t2 >> 14)) & 0x3ffffffU; + h4 += ( 1 << 24) | (t3 >> 8); ulong tp0 = (ulong)h0 * r0 + (ulong)h1 * s4 + (ulong)h2 * s3 + (ulong)h3 * s2 + (ulong)h4 * s1; ulong tp1 = (ulong)h0 * r1 + (ulong)h1 * r0 + (ulong)h2 * s4 + (ulong)h3 * s3 + (ulong)h4 * s2; @@ -324,7 +278,6 @@ namespace Org.BouncyCastle.Crypto.Macs h0 += (uint)(tp4 >> 26) * 5; h1 += h0 >> 26; h0 &= 0x3ffffff; } -#endif public int DoFinal(byte[] output, int outOff) { diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs index 2255b6276..ce5faf91f 100644 --- a/crypto/src/crypto/modes/GCMBlockCipher.cs +++ b/crypto/src/crypto/modes/GCMBlockCipher.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.CompilerServices; #endif #if NETCOREAPP3_0_OR_GREATER +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; #endif @@ -897,7 +898,6 @@ namespace Org.BouncyCastle.Crypto.Modes } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - [MethodImpl(MethodImplOptions.AggressiveOptimization)] private void DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output) { Check.OutputLength(output, BlockSize, "output buffer too short"); @@ -913,15 +913,15 @@ namespace Org.BouncyCastle.Crypto.Modes #if NETCOREAPP3_0_OR_GREATER if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == BlockSize) { - var t0 = Unsafe.ReadUnaligned<Vector128<byte>>(ref Unsafe.AsRef(input[0])); - var t1 = Unsafe.ReadUnaligned<Vector128<byte>>(ref ctrBlock[0]); - var t2 = Unsafe.ReadUnaligned<Vector128<byte>>(ref S[0]); + var t0 = MemoryMarshal.Read<Vector128<byte>>(input); + var t1 = MemoryMarshal.Read<Vector128<byte>>(ctrBlock); + var t2 = MemoryMarshal.Read<Vector128<byte>>(S.AsSpan()); t1 = Sse2.Xor(t1, t0); t2 = Sse2.Xor(t2, t0); - Unsafe.WriteUnaligned(ref output[0], t1); - Unsafe.WriteUnaligned(ref S[0], t2); + MemoryMarshal.Write(output, ref t1); + MemoryMarshal.Write(S.AsSpan(), ref t2); } else #endif @@ -949,7 +949,6 @@ namespace Org.BouncyCastle.Crypto.Modes totalLength += BlockSize; } - [MethodImpl(MethodImplOptions.AggressiveOptimization)] private void DecryptBlocks2(ReadOnlySpan<byte> input, Span<byte> output) { Check.OutputLength(output, BlockSize * 2, "output buffer too short"); @@ -965,15 +964,15 @@ namespace Org.BouncyCastle.Crypto.Modes #if NETCOREAPP3_0_OR_GREATER if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == BlockSize) { - var t0 = Unsafe.ReadUnaligned<Vector128<byte>>(ref Unsafe.AsRef(input[0])); - var t1 = Unsafe.ReadUnaligned<Vector128<byte>>(ref ctrBlock[0]); - var t2 = Unsafe.ReadUnaligned<Vector128<byte>>(ref S[0]); + var t0 = MemoryMarshal.Read<Vector128<byte>>(input); + var t1 = MemoryMarshal.Read<Vector128<byte>>(ctrBlock); + var t2 = MemoryMarshal.Read<Vector128<byte>>(S.AsSpan()); t1 = Sse2.Xor(t1, t0); t2 = Sse2.Xor(t2, t0); - Unsafe.WriteUnaligned(ref output[0], t1); - Unsafe.WriteUnaligned(ref S[0], t2); + MemoryMarshal.Write(output, ref t1); + MemoryMarshal.Write(S.AsSpan(), ref t2); } else #endif @@ -1005,15 +1004,15 @@ namespace Org.BouncyCastle.Crypto.Modes #if NETCOREAPP3_0_OR_GREATER if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == BlockSize) { - var t0 = Unsafe.ReadUnaligned<Vector128<byte>>(ref Unsafe.AsRef(input[0])); - var t1 = Unsafe.ReadUnaligned<Vector128<byte>>(ref ctrBlock[0]); - var t2 = Unsafe.ReadUnaligned<Vector128<byte>>(ref S[0]); + var t0 = MemoryMarshal.Read<Vector128<byte>>(input); + var t1 = MemoryMarshal.Read<Vector128<byte>>(ctrBlock); + var t2 = MemoryMarshal.Read<Vector128<byte>>(S.AsSpan()); t1 = Sse2.Xor(t1, t0); t2 = Sse2.Xor(t2, t0); - Unsafe.WriteUnaligned(ref output[0], t1); - Unsafe.WriteUnaligned(ref S[0], t2); + MemoryMarshal.Write(output, ref t1); + MemoryMarshal.Write(S.AsSpan(), ref t2); } else #endif @@ -1041,7 +1040,6 @@ namespace Org.BouncyCastle.Crypto.Modes totalLength += BlockSize * 2; } - [MethodImpl(MethodImplOptions.AggressiveOptimization)] private void EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output) { Check.OutputLength(output, BlockSize, "output buffer too short"); @@ -1057,15 +1055,15 @@ namespace Org.BouncyCastle.Crypto.Modes #if NETCOREAPP3_0_OR_GREATER if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == BlockSize) { - var t0 = Unsafe.ReadUnaligned<Vector128<byte>>(ref Unsafe.AsRef(input[0])); - var t1 = Unsafe.ReadUnaligned<Vector128<byte>>(ref ctrBlock[0]); - var t2 = Unsafe.ReadUnaligned<Vector128<byte>>(ref S[0]); + var t0 = MemoryMarshal.Read<Vector128<byte>>(input); + var t1 = MemoryMarshal.Read<Vector128<byte>>(ctrBlock); + var t2 = MemoryMarshal.Read<Vector128<byte>>(S.AsSpan()); t1 = Sse2.Xor(t1, t0); t2 = Sse2.Xor(t2, t1); - Unsafe.WriteUnaligned(ref output[0], t1); - Unsafe.WriteUnaligned(ref S[0], t2); + MemoryMarshal.Write(output, ref t1); + MemoryMarshal.Write(S.AsSpan(), ref t2); } else #endif @@ -1093,7 +1091,6 @@ namespace Org.BouncyCastle.Crypto.Modes totalLength += BlockSize; } - [MethodImpl(MethodImplOptions.AggressiveOptimization)] private void EncryptBlocks2(ReadOnlySpan<byte> input, Span<byte> output) { Check.OutputLength(output, BlockSize * 2, "Output buffer too short"); @@ -1109,15 +1106,15 @@ namespace Org.BouncyCastle.Crypto.Modes #if NETCOREAPP3_0_OR_GREATER if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == BlockSize) { - var t0 = Unsafe.ReadUnaligned<Vector128<byte>>(ref Unsafe.AsRef(input[0])); - var t1 = Unsafe.ReadUnaligned<Vector128<byte>>(ref ctrBlock[0]); - var t2 = Unsafe.ReadUnaligned<Vector128<byte>>(ref S[0]); + var t0 = MemoryMarshal.Read<Vector128<byte>>(input); + var t1 = MemoryMarshal.Read<Vector128<byte>>(ctrBlock); + var t2 = MemoryMarshal.Read<Vector128<byte>>(S.AsSpan()); t1 = Sse2.Xor(t1, t0); t2 = Sse2.Xor(t2, t1); - Unsafe.WriteUnaligned(ref output[0], t1); - Unsafe.WriteUnaligned(ref S[0], t2); + MemoryMarshal.Write(output, ref t1); + MemoryMarshal.Write(S.AsSpan(), ref t2); } else #endif @@ -1149,15 +1146,15 @@ namespace Org.BouncyCastle.Crypto.Modes #if NETCOREAPP3_0_OR_GREATER if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == BlockSize) { - var t0 = Unsafe.ReadUnaligned<Vector128<byte>>(ref Unsafe.AsRef(input[0])); - var t1 = Unsafe.ReadUnaligned<Vector128<byte>>(ref ctrBlock[0]); - var t2 = Unsafe.ReadUnaligned<Vector128<byte>>(ref S[0]); + var t0 = MemoryMarshal.Read<Vector128<byte>>(input); + var t1 = MemoryMarshal.Read<Vector128<byte>>(ctrBlock); + var t2 = MemoryMarshal.Read<Vector128<byte>>(S.AsSpan()); t1 = Sse2.Xor(t1, t0); t2 = Sse2.Xor(t2, t1); - Unsafe.WriteUnaligned(ref output[0], t1); - Unsafe.WriteUnaligned(ref S[0], t2); + MemoryMarshal.Write(output, ref t1); + MemoryMarshal.Write(S.AsSpan(), ref t2); } else #endif diff --git a/crypto/src/crypto/modes/gcm/GcmUtilities.cs b/crypto/src/crypto/modes/gcm/GcmUtilities.cs index 1aa437fcd..97b34fb61 100644 --- a/crypto/src/crypto/modes/gcm/GcmUtilities.cs +++ b/crypto/src/crypto/modes/gcm/GcmUtilities.cs @@ -16,12 +16,6 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm { internal abstract class GcmUtilities { -#if NETCOREAPP3_0_OR_GREATER - private static readonly Vector128<byte> EndianMask = Vector128.Create( - (byte)0x07, (byte)0x06, (byte)0x05, (byte)0x04, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x00, - (byte)0x0F, (byte)0x0E, (byte)0x0D, (byte)0x0C, (byte)0x0B, (byte)0x0A, (byte)0x09, (byte)0x08); -#endif - internal struct FieldElement { internal ulong n0, n1; @@ -41,17 +35,6 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm #endif internal static void AsBytes(ulong x0, ulong x1, byte[] z) { -#if NETCOREAPP3_0_OR_GREATER - if (Ssse3.IsSupported && BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16) - { - var X = Vector128.Create(x0, x1).AsByte(); - // TODO[Arm] System.Runtime.Intrinsics.Arm.AdvSimd.Reverse8 - var Z = Ssse3.Shuffle(X, EndianMask); - Unsafe.WriteUnaligned(ref z[0], Z); - return; - } -#endif - Pack.UInt64_To_BE(x0, z, 0); Pack.UInt64_To_BE(x1, z, 8); } @@ -69,17 +52,6 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm #endif internal static void AsFieldElement(byte[] x, out FieldElement z) { -#if NETCOREAPP3_0_OR_GREATER - if (Ssse3.IsSupported && BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16) - { - var X = Unsafe.ReadUnaligned<Vector128<byte>>(ref x[0]); - var Z = Ssse3.Shuffle(X, EndianMask).AsUInt64(); - z.n0 = Z.GetElement(0); - z.n1 = Z.GetElement(1); - return; - } -#endif - z.n0 = Pack.BE_To_UInt64(x, 0); z.n1 = Pack.BE_To_UInt64(x, 8); } diff --git a/crypto/src/crypto/operators/Asn1CipherBuilder.cs b/crypto/src/crypto/operators/Asn1CipherBuilder.cs index 0561bee4f..b151dfcc2 100644 --- a/crypto/src/crypto/operators/Asn1CipherBuilder.cs +++ b/crypto/src/crypto/operators/Asn1CipherBuilder.cs @@ -18,10 +18,7 @@ namespace Org.BouncyCastle.Crypto.Operators public Asn1CipherBuilderWithKey(DerObjectIdentifier encryptionOID, int keySize, SecureRandom random) { - if (random == null) - { - random = new SecureRandom(); - } + random = CryptoServicesRegistrar.GetSecureRandom(random); CipherKeyGenerator keyGen = CipherKeyGeneratorFactory.CreateKeyGenerator(encryptionOID, random); diff --git a/crypto/src/crypto/paddings/ISO10126d2Padding.cs b/crypto/src/crypto/paddings/ISO10126d2Padding.cs index 317b5db8c..21e007f1b 100644 --- a/crypto/src/crypto/paddings/ISO10126d2Padding.cs +++ b/crypto/src/crypto/paddings/ISO10126d2Padding.cs @@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Paddings SecureRandom random) //throws ArgumentException { - this.random = (random != null) ? random : new SecureRandom(); + this.random = CryptoServicesRegistrar.GetSecureRandom(random); } /** diff --git a/crypto/src/crypto/parameters/ParametersWithRandom.cs b/crypto/src/crypto/parameters/ParametersWithRandom.cs index e20ddd7ce..2fe885a8a 100644 --- a/crypto/src/crypto/parameters/ParametersWithRandom.cs +++ b/crypto/src/crypto/parameters/ParametersWithRandom.cs @@ -11,7 +11,7 @@ namespace Org.BouncyCastle.Crypto.Parameters private readonly SecureRandom m_random; public ParametersWithRandom(ICipherParameters parameters) - : this(parameters, new SecureRandom()) + : this(parameters, CryptoServicesRegistrar.GetSecureRandom()) { } diff --git a/crypto/src/crypto/prng/BasicEntropySourceProvider.cs b/crypto/src/crypto/prng/BasicEntropySourceProvider.cs index 485cf25ab..5de1e4e5e 100644 --- a/crypto/src/crypto/prng/BasicEntropySourceProvider.cs +++ b/crypto/src/crypto/prng/BasicEntropySourceProvider.cs @@ -21,6 +21,9 @@ namespace Org.BouncyCastle.Crypto.Prng */ public BasicEntropySourceProvider(SecureRandom secureRandom, bool isPredictionResistant) { + if (secureRandom == null) + throw new ArgumentNullException(nameof(secureRandom)); + mSecureRandom = secureRandom; mPredictionResistant = isPredictionResistant; } @@ -46,6 +49,9 @@ namespace Org.BouncyCastle.Crypto.Prng internal BasicEntropySource(SecureRandom secureRandom, bool predictionResistant, int entropySize) { + if (secureRandom == null) + throw new ArgumentNullException(nameof(secureRandom)); + this.mSecureRandom = secureRandom; this.mPredictionResistant = predictionResistant; this.mEntropySize = entropySize; diff --git a/crypto/src/crypto/prng/SP800SecureRandomBuilder.cs b/crypto/src/crypto/prng/SP800SecureRandomBuilder.cs index 7199f1ae7..8159f4822 100644 --- a/crypto/src/crypto/prng/SP800SecureRandomBuilder.cs +++ b/crypto/src/crypto/prng/SP800SecureRandomBuilder.cs @@ -26,7 +26,7 @@ namespace Org.BouncyCastle.Crypto.Prng * </p> */ public SP800SecureRandomBuilder() - : this(new SecureRandom(), false) + : this(CryptoServicesRegistrar.GetSecureRandom(), false) { } @@ -42,6 +42,9 @@ namespace Org.BouncyCastle.Crypto.Prng */ public SP800SecureRandomBuilder(SecureRandom entropySource, bool predictionResistant) { + if (entropySource == null) + throw new ArgumentNullException(nameof(entropySource)); + this.mRandom = entropySource; this.mEntropySourceProvider = new BasicEntropySourceProvider(entropySource, predictionResistant); } diff --git a/crypto/src/crypto/prng/VMPCRandomGenerator.cs b/crypto/src/crypto/prng/VMPCRandomGenerator.cs index 13b097789..92d163710 100644 --- a/crypto/src/crypto/prng/VMPCRandomGenerator.cs +++ b/crypto/src/crypto/prng/VMPCRandomGenerator.cs @@ -4,11 +4,9 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Crypto.Prng { - public class VmpcRandomGenerator + public sealed class VmpcRandomGenerator : IRandomGenerator { - private byte n = 0; - /// <remarks> /// Permutation generated by code: /// <code> @@ -28,77 +26,61 @@ namespace Org.BouncyCastle.Crypto.Prng /// P[s & 0xff] = temp; /// } </code> /// </remarks> - private byte[] P = + private readonly byte[] P = { - (byte) 0xbb, (byte) 0x2c, (byte) 0x62, (byte) 0x7f, (byte) 0xb5, (byte) 0xaa, (byte) 0xd4, - (byte) 0x0d, (byte) 0x81, (byte) 0xfe, (byte) 0xb2, (byte) 0x82, (byte) 0xcb, (byte) 0xa0, (byte) 0xa1, - (byte) 0x08, (byte) 0x18, (byte) 0x71, (byte) 0x56, (byte) 0xe8, (byte) 0x49, (byte) 0x02, (byte) 0x10, - (byte) 0xc4, (byte) 0xde, (byte) 0x35, (byte) 0xa5, (byte) 0xec, (byte) 0x80, (byte) 0x12, (byte) 0xb8, - (byte) 0x69, (byte) 0xda, (byte) 0x2f, (byte) 0x75, (byte) 0xcc, (byte) 0xa2, (byte) 0x09, (byte) 0x36, - (byte) 0x03, (byte) 0x61, (byte) 0x2d, (byte) 0xfd, (byte) 0xe0, (byte) 0xdd, (byte) 0x05, (byte) 0x43, - (byte) 0x90, (byte) 0xad, (byte) 0xc8, (byte) 0xe1, (byte) 0xaf, (byte) 0x57, (byte) 0x9b, (byte) 0x4c, - (byte) 0xd8, (byte) 0x51, (byte) 0xae, (byte) 0x50, (byte) 0x85, (byte) 0x3c, (byte) 0x0a, (byte) 0xe4, - (byte) 0xf3, (byte) 0x9c, (byte) 0x26, (byte) 0x23, (byte) 0x53, (byte) 0xc9, (byte) 0x83, (byte) 0x97, - (byte) 0x46, (byte) 0xb1, (byte) 0x99, (byte) 0x64, (byte) 0x31, (byte) 0x77, (byte) 0xd5, (byte) 0x1d, - (byte) 0xd6, (byte) 0x78, (byte) 0xbd, (byte) 0x5e, (byte) 0xb0, (byte) 0x8a, (byte) 0x22, (byte) 0x38, - (byte) 0xf8, (byte) 0x68, (byte) 0x2b, (byte) 0x2a, (byte) 0xc5, (byte) 0xd3, (byte) 0xf7, (byte) 0xbc, - (byte) 0x6f, (byte) 0xdf, (byte) 0x04, (byte) 0xe5, (byte) 0x95, (byte) 0x3e, (byte) 0x25, (byte) 0x86, - (byte) 0xa6, (byte) 0x0b, (byte) 0x8f, (byte) 0xf1, (byte) 0x24, (byte) 0x0e, (byte) 0xd7, (byte) 0x40, - (byte) 0xb3, (byte) 0xcf, (byte) 0x7e, (byte) 0x06, (byte) 0x15, (byte) 0x9a, (byte) 0x4d, (byte) 0x1c, - (byte) 0xa3, (byte) 0xdb, (byte) 0x32, (byte) 0x92, (byte) 0x58, (byte) 0x11, (byte) 0x27, (byte) 0xf4, - (byte) 0x59, (byte) 0xd0, (byte) 0x4e, (byte) 0x6a, (byte) 0x17, (byte) 0x5b, (byte) 0xac, (byte) 0xff, - (byte) 0x07, (byte) 0xc0, (byte) 0x65, (byte) 0x79, (byte) 0xfc, (byte) 0xc7, (byte) 0xcd, (byte) 0x76, - (byte) 0x42, (byte) 0x5d, (byte) 0xe7, (byte) 0x3a, (byte) 0x34, (byte) 0x7a, (byte) 0x30, (byte) 0x28, - (byte) 0x0f, (byte) 0x73, (byte) 0x01, (byte) 0xf9, (byte) 0xd1, (byte) 0xd2, (byte) 0x19, (byte) 0xe9, - (byte) 0x91, (byte) 0xb9, (byte) 0x5a, (byte) 0xed, (byte) 0x41, (byte) 0x6d, (byte) 0xb4, (byte) 0xc3, - (byte) 0x9e, (byte) 0xbf, (byte) 0x63, (byte) 0xfa, (byte) 0x1f, (byte) 0x33, (byte) 0x60, (byte) 0x47, - (byte) 0x89, (byte) 0xf0, (byte) 0x96, (byte) 0x1a, (byte) 0x5f, (byte) 0x93, (byte) 0x3d, (byte) 0x37, - (byte) 0x4b, (byte) 0xd9, (byte) 0xa8, (byte) 0xc1, (byte) 0x1b, (byte) 0xf6, (byte) 0x39, (byte) 0x8b, - (byte) 0xb7, (byte) 0x0c, (byte) 0x20, (byte) 0xce, (byte) 0x88, (byte) 0x6e, (byte) 0xb6, (byte) 0x74, - (byte) 0x8e, (byte) 0x8d, (byte) 0x16, (byte) 0x29, (byte) 0xf2, (byte) 0x87, (byte) 0xf5, (byte) 0xeb, - (byte) 0x70, (byte) 0xe3, (byte) 0xfb, (byte) 0x55, (byte) 0x9f, (byte) 0xc6, (byte) 0x44, (byte) 0x4a, - (byte) 0x45, (byte) 0x7d, (byte) 0xe2, (byte) 0x6b, (byte) 0x5c, (byte) 0x6c, (byte) 0x66, (byte) 0xa9, - (byte) 0x8c, (byte) 0xee, (byte) 0x84, (byte) 0x13, (byte) 0xa7, (byte) 0x1e, (byte) 0x9d, (byte) 0xdc, - (byte) 0x67, (byte) 0x48, (byte) 0xba, (byte) 0x2e, (byte) 0xe6, (byte) 0xa4, (byte) 0xab, (byte) 0x7c, - (byte) 0x94, (byte) 0x00, (byte) 0x21, (byte) 0xef, (byte) 0xea, (byte) 0xbe, (byte) 0xca, (byte) 0x72, - (byte) 0x4f, (byte) 0x52, (byte) 0x98, (byte) 0x3f, (byte) 0xc2, (byte) 0x14, (byte) 0x7b, (byte) 0x3b, - (byte) 0x54 + 0xbb, 0x2c, 0x62, 0x7f, 0xb5, 0xaa, 0xd4, 0x0d, 0x81, 0xfe, 0xb2, 0x82, 0xcb, 0xa0, 0xa1, 0x08, + 0x18, 0x71, 0x56, 0xe8, 0x49, 0x02, 0x10, 0xc4, 0xde, 0x35, 0xa5, 0xec, 0x80, 0x12, 0xb8, 0x69, + 0xda, 0x2f, 0x75, 0xcc, 0xa2, 0x09, 0x36, 0x03, 0x61, 0x2d, 0xfd, 0xe0, 0xdd, 0x05, 0x43, 0x90, + 0xad, 0xc8, 0xe1, 0xaf, 0x57, 0x9b, 0x4c, 0xd8, 0x51, 0xae, 0x50, 0x85, 0x3c, 0x0a, 0xe4, 0xf3, + 0x9c, 0x26, 0x23, 0x53, 0xc9, 0x83, 0x97, 0x46, 0xb1, 0x99, 0x64, 0x31, 0x77, 0xd5, 0x1d, 0xd6, + 0x78, 0xbd, 0x5e, 0xb0, 0x8a, 0x22, 0x38, 0xf8, 0x68, 0x2b, 0x2a, 0xc5, 0xd3, 0xf7, 0xbc, 0x6f, + 0xdf, 0x04, 0xe5, 0x95, 0x3e, 0x25, 0x86, 0xa6, 0x0b, 0x8f, 0xf1, 0x24, 0x0e, 0xd7, 0x40, 0xb3, + 0xcf, 0x7e, 0x06, 0x15, 0x9a, 0x4d, 0x1c, 0xa3, 0xdb, 0x32, 0x92, 0x58, 0x11, 0x27, 0xf4, 0x59, + 0xd0, 0x4e, 0x6a, 0x17, 0x5b, 0xac, 0xff, 0x07, 0xc0, 0x65, 0x79, 0xfc, 0xc7, 0xcd, 0x76, 0x42, + 0x5d, 0xe7, 0x3a, 0x34, 0x7a, 0x30, 0x28, 0x0f, 0x73, 0x01, 0xf9, 0xd1, 0xd2, 0x19, 0xe9, 0x91, + 0xb9, 0x5a, 0xed, 0x41, 0x6d, 0xb4, 0xc3, 0x9e, 0xbf, 0x63, 0xfa, 0x1f, 0x33, 0x60, 0x47, 0x89, + 0xf0, 0x96, 0x1a, 0x5f, 0x93, 0x3d, 0x37, 0x4b, 0xd9, 0xa8, 0xc1, 0x1b, 0xf6, 0x39, 0x8b, 0xb7, + 0x0c, 0x20, 0xce, 0x88, 0x6e, 0xb6, 0x74, 0x8e, 0x8d, 0x16, 0x29, 0xf2, 0x87, 0xf5, 0xeb, 0x70, + 0xe3, 0xfb, 0x55, 0x9f, 0xc6, 0x44, 0x4a, 0x45, 0x7d, 0xe2, 0x6b, 0x5c, 0x6c, 0x66, 0xa9, 0x8c, + 0xee, 0x84, 0x13, 0xa7, 0x1e, 0x9d, 0xdc, 0x67, 0x48, 0xba, 0x2e, 0xe6, 0xa4, 0xab, 0x7c, 0x94, + 0x00, 0x21, 0xef, 0xea, 0xbe, 0xca, 0x72, 0x4f, 0x52, 0x98, 0x3f, 0xc2, 0x14, 0x7b, 0x3b, 0x54, }; /// <remarks>Value generated in the same way as <c>P</c>.</remarks> - private byte s = (byte) 0xbe; + private byte s = 0xbe; + private byte n = 0; public VmpcRandomGenerator() { } - public virtual void AddSeedMaterial(byte[] seed) + public void AddSeedMaterial(byte[] seed) { for (int m = 0; m < seed.Length; m++) { - s = P[(s + P[n & 0xff] + seed[m]) & 0xff]; - byte temp = P[n & 0xff]; - P[n & 0xff] = P[s & 0xff]; - P[s & 0xff] = temp; - n = (byte) ((n + 1) & 0xff); + byte pn = P[n]; + s = P[(s + pn + seed[m]) & 0xff]; + P[n] = P[s]; + P[s] = pn; + n = (byte)(n + 1); } } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public virtual void AddSeedMaterial(ReadOnlySpan<byte> seed) + public void AddSeedMaterial(ReadOnlySpan<byte> seed) { for (int m = 0; m < seed.Length; m++) { - s = P[(s + P[n & 0xff] + seed[m]) & 0xff]; - byte temp = P[n & 0xff]; - P[n & 0xff] = P[s & 0xff]; - P[s & 0xff] = temp; - n = (byte)((n + 1) & 0xff); + byte pn = P[n]; + s = P[(s + pn + seed[m]) & 0xff]; + P[n] = P[s]; + P[s] = pn; + n = (byte)(n + 1); } } #endif - public virtual void AddSeedMaterial(long seed) + public void AddSeedMaterial(long seed) { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER Span<byte> bytes = stackalloc byte[8]; @@ -109,41 +91,47 @@ namespace Org.BouncyCastle.Crypto.Prng #endif } - public virtual void NextBytes(byte[] bytes) + public void NextBytes(byte[] bytes) { NextBytes(bytes, 0, bytes.Length); } - public virtual void NextBytes(byte[] bytes, int start, int len) + public void NextBytes(byte[] bytes, int start, int len) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + NextBytes(bytes.AsSpan(start, len)); +#else lock (P) { int end = start + len; for (int i = start; i != end; i++) { - s = P[(s + P[n & 0xff]) & 0xff]; - bytes[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; - byte temp = P[n & 0xff]; - P[n & 0xff] = P[s & 0xff]; - P[s & 0xff] = temp; - n = (byte) ((n + 1) & 0xff); + byte pn = P[n]; + s = P[(s + pn) & 0xFF]; + byte ps = P[s]; + bytes[i] = P[(P[ps] + 1) & 0xFF]; + P[s] = pn; + P[n] = ps; + n = (byte)(n + 1); } } +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public virtual void NextBytes(Span<byte> bytes) + public void NextBytes(Span<byte> bytes) { lock (P) { - for (int i = 0; i != bytes.Length; i++) + for (int i = 0; i < bytes.Length; ++i) { - s = P[(s + P[n & 0xff]) & 0xff]; - bytes[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; - byte temp = P[n & 0xff]; - P[n & 0xff] = P[s & 0xff]; - P[s & 0xff] = temp; - n = (byte) ((n + 1) & 0xff); + byte pn = P[n]; + s = P[(s + pn) & 0xFF]; + byte ps = P[s]; + bytes[i] = P[(P[ps] + 1) & 0xFF]; + P[s] = pn; + P[n] = ps; + n = (byte)(n + 1); } } } diff --git a/crypto/src/crypto/prng/X931SecureRandomBuilder.cs b/crypto/src/crypto/prng/X931SecureRandomBuilder.cs index 31e94312e..025eac1bb 100644 --- a/crypto/src/crypto/prng/X931SecureRandomBuilder.cs +++ b/crypto/src/crypto/prng/X931SecureRandomBuilder.cs @@ -23,7 +23,7 @@ namespace Org.BouncyCastle.Crypto.Prng * </p> */ public X931SecureRandomBuilder() - : this(new SecureRandom(), false) + : this(CryptoServicesRegistrar.GetSecureRandom(), false) { } @@ -39,6 +39,9 @@ namespace Org.BouncyCastle.Crypto.Prng */ public X931SecureRandomBuilder(SecureRandom entropySource, bool predictionResistant) { + if (entropySource == null) + throw new ArgumentNullException(nameof(entropySource)); + this.mRandom = entropySource; this.mEntropySourceProvider = new BasicEntropySourceProvider(mRandom, predictionResistant); } diff --git a/crypto/src/crypto/signers/DsaSigner.cs b/crypto/src/crypto/signers/DsaSigner.cs index 7799edc0e..318eeeb48 100644 --- a/crypto/src/crypto/signers/DsaSigner.cs +++ b/crypto/src/crypto/signers/DsaSigner.cs @@ -155,7 +155,7 @@ namespace Org.BouncyCastle.Crypto.Signers protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided) { - return !needed ? null : (provided != null) ? provided : new SecureRandom(); + return !needed ? null : CryptoServicesRegistrar.GetSecureRandom(provided); } } } diff --git a/crypto/src/crypto/signers/ECDsaSigner.cs b/crypto/src/crypto/signers/ECDsaSigner.cs index 590c3236b..d78e92516 100644 --- a/crypto/src/crypto/signers/ECDsaSigner.cs +++ b/crypto/src/crypto/signers/ECDsaSigner.cs @@ -239,7 +239,7 @@ namespace Org.BouncyCastle.Crypto.Signers protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided) { - return !needed ? null : (provided != null) ? provided : new SecureRandom(); + return !needed ? null : CryptoServicesRegistrar.GetSecureRandom(provided); } } } diff --git a/crypto/src/crypto/signers/ECGOST3410Signer.cs b/crypto/src/crypto/signers/ECGOST3410Signer.cs index 2defa943f..fd5fa4818 100644 --- a/crypto/src/crypto/signers/ECGOST3410Signer.cs +++ b/crypto/src/crypto/signers/ECGOST3410Signer.cs @@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Crypto.Signers } else { - this.random = new SecureRandom(); + this.random = CryptoServicesRegistrar.GetSecureRandom(); } if (!(parameters is ECPrivateKeyParameters ecPrivateKeyParameters)) diff --git a/crypto/src/crypto/signers/ECNRSigner.cs b/crypto/src/crypto/signers/ECNRSigner.cs index b22d7a977..d7790386a 100644 --- a/crypto/src/crypto/signers/ECNRSigner.cs +++ b/crypto/src/crypto/signers/ECNRSigner.cs @@ -24,24 +24,20 @@ namespace Org.BouncyCastle.Crypto.Signers get { return "ECNR"; } } - public virtual void Init( - bool forSigning, - ICipherParameters parameters) + public virtual void Init(bool forSigning, ICipherParameters parameters) { this.forSigning = forSigning; if (forSigning) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom rParam) { - ParametersWithRandom rParam = (ParametersWithRandom) parameters; - this.random = rParam.Random; parameters = rParam.Parameters; } else { - this.random = new SecureRandom(); + this.random = CryptoServicesRegistrar.GetSecureRandom(); } if (!(parameters is ECPrivateKeyParameters)) diff --git a/crypto/src/crypto/signers/GOST3410Signer.cs b/crypto/src/crypto/signers/GOST3410Signer.cs index a0d8f8a1f..03aab0b04 100644 --- a/crypto/src/crypto/signers/GOST3410Signer.cs +++ b/crypto/src/crypto/signers/GOST3410Signer.cs @@ -21,22 +21,18 @@ namespace Org.BouncyCastle.Crypto.Signers get { return "GOST3410"; } } - public virtual void Init( - bool forSigning, - ICipherParameters parameters) + public virtual void Init(bool forSigning, ICipherParameters parameters) { if (forSigning) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom rParam) { - ParametersWithRandom rParam = (ParametersWithRandom)parameters; - this.random = rParam.Random; parameters = rParam.Parameters; } else { - this.random = new SecureRandom(); + this.random = CryptoServicesRegistrar.GetSecureRandom(); } if (!(parameters is Gost3410PrivateKeyParameters)) diff --git a/crypto/src/crypto/signers/Iso9796d2PssSigner.cs b/crypto/src/crypto/signers/Iso9796d2PssSigner.cs index 573765c1a..72afabf4c 100644 --- a/crypto/src/crypto/signers/Iso9796d2PssSigner.cs +++ b/crypto/src/crypto/signers/Iso9796d2PssSigner.cs @@ -109,42 +109,36 @@ namespace Org.BouncyCastle.Crypto.Signers /// <exception cref="ArgumentException">if wrong parameter type or a fixed /// salt is passed in which is the wrong length. /// </exception> - public virtual void Init( - bool forSigning, - ICipherParameters parameters) + public virtual void Init(bool forSigning, ICipherParameters parameters) { RsaKeyParameters kParam; - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - ParametersWithRandom p = (ParametersWithRandom) parameters; - - kParam = (RsaKeyParameters) p.Parameters; + kParam = (RsaKeyParameters)withRandom.Parameters; if (forSigning) { - random = p.Random; + random = withRandom.Random; } } - else if (parameters is ParametersWithSalt) + else if (parameters is ParametersWithSalt withSalt) { if (!forSigning) - throw new ArgumentException("ParametersWithSalt only valid for signing", "parameters"); - - ParametersWithSalt p = (ParametersWithSalt) parameters; + throw new ArgumentException("ParametersWithSalt only valid for signing", nameof(parameters)); - kParam = (RsaKeyParameters) p.Parameters; - standardSalt = p.GetSalt(); + kParam = (RsaKeyParameters)withSalt.Parameters; + standardSalt = withSalt.GetSalt(); if (standardSalt.Length != saltLength) throw new ArgumentException("Fixed salt is of wrong length"); } else { - kParam = (RsaKeyParameters) parameters; + kParam = (RsaKeyParameters)parameters; if (forSigning) { - random = new SecureRandom(); + random = CryptoServicesRegistrar.GetSecureRandom(); } } diff --git a/crypto/src/crypto/signers/PssSigner.cs b/crypto/src/crypto/signers/PssSigner.cs index 6d34e6edd..df73a7472 100644 --- a/crypto/src/crypto/signers/PssSigner.cs +++ b/crypto/src/crypto/signers/PssSigner.cs @@ -152,22 +152,18 @@ namespace Org.BouncyCastle.Crypto.Signers get { return mgfDigest.AlgorithmName + "withRSAandMGF1"; } } - public virtual void Init( - bool forSigning, - ICipherParameters parameters) + public virtual void Init(bool forSigning, ICipherParameters parameters) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - ParametersWithRandom p = (ParametersWithRandom) parameters; - - parameters = p.Parameters; - random = p.Random; + parameters = withRandom.Parameters; + random = withRandom.Random; } else { if (forSigning) { - random = new SecureRandom(); + random = CryptoServicesRegistrar.GetSecureRandom(); } } @@ -176,11 +172,11 @@ namespace Org.BouncyCastle.Crypto.Signers RsaKeyParameters kParam; if (parameters is RsaBlindingParameters) { - kParam = ((RsaBlindingParameters) parameters).PublicKey; + kParam = ((RsaBlindingParameters)parameters).PublicKey; } else { - kParam = (RsaKeyParameters) parameters; + kParam = (RsaKeyParameters)parameters; } emBits = kParam.Modulus.BitLength - 1; diff --git a/crypto/src/crypto/signers/SM2Signer.cs b/crypto/src/crypto/signers/SM2Signer.cs index 24aedd970..07b41bd30 100644 --- a/crypto/src/crypto/signers/SM2Signer.cs +++ b/crypto/src/crypto/signers/SM2Signer.cs @@ -72,10 +72,8 @@ namespace Org.BouncyCastle.Crypto.Signers if (forSigning) { - if (baseParam is ParametersWithRandom) + if (baseParam is ParametersWithRandom rParam) { - ParametersWithRandom rParam = (ParametersWithRandom)baseParam; - ecKey = (ECKeyParameters)rParam.Parameters; ecParams = ecKey.Parameters; kCalculator.Init(ecParams.N, rParam.Random); @@ -84,7 +82,7 @@ namespace Org.BouncyCastle.Crypto.Signers { ecKey = (ECKeyParameters)baseParam; ecParams = ecKey.Parameters; - kCalculator.Init(ecParams.N, new SecureRandom()); + kCalculator.Init(ecParams.N, CryptoServicesRegistrar.GetSecureRandom()); } pubPoint = CreateBasePointMultiplier().Multiply(ecParams.G, ((ECPrivateKeyParameters)ecKey).D).Normalize(); } diff --git a/crypto/src/crypto/util/Pack.cs b/crypto/src/crypto/util/Pack.cs index 98504a605..a12253e59 100644 --- a/crypto/src/crypto/util/Pack.cs +++ b/crypto/src/crypto/util/Pack.cs @@ -7,12 +7,8 @@ using System.Runtime.CompilerServices; namespace Org.BouncyCastle.Crypto.Utilities { - internal sealed class Pack + internal static class Pack { - private Pack() - { - } - internal static void UInt16_To_BE(ushort n, byte[] bs) { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER diff --git a/crypto/src/math/BigInteger.cs b/crypto/src/math/BigInteger.cs index dd8b3a85b..caf78843e 100644 --- a/crypto/src/math/BigInteger.cs +++ b/crypto/src/math/BigInteger.cs @@ -7,7 +7,7 @@ using System.Runtime.Intrinsics.X86; #endif using System.Runtime.Serialization; using System.Text; - +using Org.BouncyCastle.Crypto.Prng; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; @@ -163,8 +163,6 @@ namespace Org.BouncyCastle.Math private const int chunk2 = 1, chunk8 = 1, chunk10 = 19, chunk16 = 16; private static readonly BigInteger radix2, radix2E, radix8, radix8E, radix10, radix10E, radix16, radix16E; - private static readonly SecureRandom RandomSource = new SecureRandom(); - /* * These are the threshold bit-lengths (of an exponent) where we increase the window size. * They are calculated according to the expected savings in multiplications. @@ -244,7 +242,7 @@ namespace Org.BouncyCastle.Math public static BigInteger Arbitrary(int sizeInBits) { - return new BigInteger(sizeInBits, RandomSource); + return new BigInteger(sizeInBits, SecureRandom.ArbitraryRandom); } private BigInteger( @@ -1460,7 +1458,7 @@ namespace Org.BouncyCastle.Math if (n.Equals(One)) return false; - return n.CheckProbablePrime(certainty, RandomSource, randomlySelected); + return n.CheckProbablePrime(certainty, SecureRandom.ArbitraryRandom, randomlySelected); } private bool CheckProbablePrime(int certainty, Random random, bool randomlySelected) @@ -2633,7 +2631,7 @@ namespace Org.BouncyCastle.Math BigInteger n = Inc().SetBit(0); - while (!n.CheckProbablePrime(100, RandomSource, false)) + while (!n.CheckProbablePrime(100, SecureRandom.ArbitraryRandom, false)) { n = n.Add(Two); } diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs index d17c6b1c1..b37d62721 100644 --- a/crypto/src/math/ec/ECCurve.cs +++ b/crypto/src/math/ec/ECCurve.cs @@ -737,7 +737,6 @@ namespace Org.BouncyCastle.Math.EC private const int FP_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; private static readonly HashSet<BigInteger> KnownQs = new HashSet<BigInteger>(); - private static readonly SecureRandom random = new SecureRandom(); protected readonly BigInteger m_q, m_r; protected readonly FpPoint m_infinity; @@ -771,7 +770,8 @@ namespace Org.BouncyCastle.Math.EC throw new ArgumentException("Fp q value out of range"); if (Primes.HasAnySmallFactors(q) || - !Primes.IsMRProbablePrime(q, random, GetNumberOfIterations(qBitLength, certainty))) + !Primes.IsMRProbablePrime(q, SecureRandom.ArbitraryRandom, + GetNumberOfIterations(qBitLength, certainty))) { throw new ArgumentException("Fp q value not prime"); } diff --git a/crypto/src/math/ec/ECPoint.cs b/crypto/src/math/ec/ECPoint.cs index fc0ddf035..ee7cf9a92 100644 --- a/crypto/src/math/ec/ECPoint.cs +++ b/crypto/src/math/ec/ECPoint.cs @@ -12,8 +12,6 @@ namespace Org.BouncyCastle.Math.EC */ public abstract class ECPoint { - private static readonly SecureRandom Random = new SecureRandom(); - protected static ECFieldElement[] EMPTY_ZS = new ECFieldElement[0]; protected static ECFieldElement[] GetInitialZCoords(ECCurve curve) @@ -246,10 +244,7 @@ namespace Org.BouncyCastle.Math.EC * Any side-channel in the implementation of 'inverse' now only leaks information about * the value (z * b), and no longer reveals information about 'z' itself. */ - // TODO Add CryptoServicesRegistrar class and use here - //SecureRandom r = CryptoServicesRegistrar.GetSecureRandom(); - SecureRandom r = Random; - ECFieldElement b = m_curve.RandomFieldElementMult(r); + ECFieldElement b = m_curve.RandomFieldElementMult(SecureRandom.ArbitraryRandom); ECFieldElement zInv = z.Multiply(b).Invert().Multiply(b); return Normalize(zInv); } diff --git a/crypto/src/math/ec/custom/gm/SM2P256V1FieldElement.cs b/crypto/src/math/ec/custom/gm/SM2P256V1FieldElement.cs index 25cb24932..e3de6c594 100644 --- a/crypto/src/math/ec/custom/gm/SM2P256V1FieldElement.cs +++ b/crypto/src/math/ec/custom/gm/SM2P256V1FieldElement.cs @@ -115,7 +115,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.GM public override ECFieldElement Invert() { - //return new SM2P256V1FieldElement(ToBigInteger().ModInverse(Q)); uint[] z = Nat256.Create(); SM2P256V1Field.Inv(x, z); return new SM2P256V1FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecP128R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP128R1FieldElement.cs index e9235c2f3..1db449442 100644 --- a/crypto/src/math/ec/custom/sec/SecP128R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP128R1FieldElement.cs @@ -115,7 +115,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - // return new SecP128R1FieldElement(toBigInteger().modInverse(Q)); uint[] z = Nat128.Create(); SecP128R1Field.Inv(x, z); return new SecP128R1FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecP160R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP160R1FieldElement.cs index 4876fafa9..a4307cbaf 100644 --- a/crypto/src/math/ec/custom/sec/SecP160R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP160R1FieldElement.cs @@ -115,7 +115,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - // return new SecP160R1FieldElement(ToBigInteger().modInverse(Q)); uint[] z = Nat160.Create(); SecP160R1Field.Inv(x, z); return new SecP160R1FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecP160R2FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP160R2FieldElement.cs index 795fe3b2e..9237c0778 100644 --- a/crypto/src/math/ec/custom/sec/SecP160R2FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP160R2FieldElement.cs @@ -115,7 +115,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - // return new SecP160R2FieldElement(ToBigInteger().modInverse(Q)); uint[] z = Nat160.Create(); SecP160R2Field.Inv(x, z); return new SecP160R2FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecP192K1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP192K1FieldElement.cs index c933ffc8d..a37bc1539 100644 --- a/crypto/src/math/ec/custom/sec/SecP192K1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP192K1FieldElement.cs @@ -116,7 +116,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - //return new SecP192K1FieldElement(ToBigInteger().ModInverse(Q)); uint[] z = Nat192.Create(); SecP192K1Field.Inv(x, z); return new SecP192K1FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecP192R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP192R1FieldElement.cs index e61c2251b..a8c7ae83c 100644 --- a/crypto/src/math/ec/custom/sec/SecP192R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP192R1FieldElement.cs @@ -115,7 +115,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - //return new SecP192R1FieldElement(ToBigInteger().ModInverse(Q)); uint[] z = Nat192.Create(); SecP192R1Field.Inv(x, z); return new SecP192R1FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecP224K1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP224K1FieldElement.cs index eb740419f..24de7112a 100644 --- a/crypto/src/math/ec/custom/sec/SecP224K1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP224K1FieldElement.cs @@ -120,7 +120,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - //return new SecP224K1FieldElement(ToBigInteger().ModInverse(Q)); uint[] z = Nat224.Create(); SecP224K1Field.Inv(x, z); return new SecP224K1FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs index bb60edaf6..e53f44164 100644 --- a/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Encoders; @@ -115,7 +116,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - //return new SecP224R1FieldElement(ToBigInteger().ModInverse(Q)); uint[] z = Nat224.Create(); SecP224R1Field.Inv(x, z); return new SecP224R1FieldElement(z); @@ -134,7 +134,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec uint[] nc = Nat224.Create(); SecP224R1Field.Negate(c, nc); - uint[] r = Mod.Random(SecP224R1Field.P); + uint[] r = Mod.Random(SecureRandom.ArbitraryRandom, SecP224R1Field.P); uint[] t = Nat224.Create(); if (!IsSquare(c)) diff --git a/crypto/src/math/ec/custom/sec/SecP256K1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP256K1FieldElement.cs index 2bb83d5e9..055df0d06 100644 --- a/crypto/src/math/ec/custom/sec/SecP256K1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP256K1FieldElement.cs @@ -115,7 +115,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - //return new SecP256K1FieldElement(ToBigInteger().ModInverse(Q)); uint[] z = Nat256.Create(); SecP256K1Field.Inv(x, z); return new SecP256K1FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecP256R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP256R1FieldElement.cs index 928461ec6..e09cd8c8d 100644 --- a/crypto/src/math/ec/custom/sec/SecP256R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP256R1FieldElement.cs @@ -115,7 +115,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - //return new SecP256R1FieldElement(ToBigInteger().ModInverse(Q)); uint[] z = Nat256.Create(); SecP256R1Field.Inv(x, z); return new SecP256R1FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecP384R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP384R1FieldElement.cs index d190c4ae9..33f251b76 100644 --- a/crypto/src/math/ec/custom/sec/SecP384R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP384R1FieldElement.cs @@ -115,7 +115,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - //return new SecP384R1FieldElement(ToBigInteger().ModInverse(Q)); uint[] z = Nat.Create(12); SecP384R1Field.Inv(x, z); return new SecP384R1FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecP521R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP521R1FieldElement.cs index 409352586..1169d41a9 100644 --- a/crypto/src/math/ec/custom/sec/SecP521R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP521R1FieldElement.cs @@ -115,7 +115,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public override ECFieldElement Invert() { - //return new SecP521R1FieldElement(ToBigInteger().ModInverse(Q)); uint[] z = Nat.Create(17); SecP521R1Field.Inv(x, z); return new SecP521R1FieldElement(z); diff --git a/crypto/src/math/ec/custom/sec/SecT571Field.cs b/crypto/src/math/ec/custom/sec/SecT571Field.cs index 5a393409a..49eaae2d4 100644 --- a/crypto/src/math/ec/custom/sec/SecT571Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT571Field.cs @@ -19,18 +19,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static void Add(ulong[] x, ulong[] y, ulong[] z) { - for (int i = 0; i < 9; ++i) - { - z[i] = x[i] ^ y[i]; - } + Nat.Xor64(9, x, y, z); } private static void Add(ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) { - for (int i = 0; i < 9; ++i) - { - z[zOff + i] = x[xOff + i] ^ y[yOff + i]; - } + Nat.Xor64(9, x, xOff, y, yOff, z, zOff); } public static void AddBothTo(ulong[] x, ulong[] y, ulong[] z) @@ -51,10 +45,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) { - for (int i = 0; i < 18; ++i) - { - zz[i] = xx[i] ^ yy[i]; - } + Nat.Xor64(18, xx, yy, zz); } public static void AddOne(ulong[] x, ulong[] z) @@ -68,10 +59,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec private static void AddTo(ulong[] x, ulong[] z) { - for (int i = 0; i < 9; ++i) - { - z[i] ^= x[i]; - } + Nat.XorTo64(9, x, z); } public static ulong[] FromBigInteger(BigInteger x) diff --git a/crypto/src/math/raw/Mod.cs b/crypto/src/math/raw/Mod.cs index ea61bdd83..721134b0c 100644 --- a/crypto/src/math/raw/Mod.cs +++ b/crypto/src/math/raw/Mod.cs @@ -12,10 +12,8 @@ namespace Org.BouncyCastle.Math.Raw * computation and modular inversion" by Daniel J. Bernstein and Bo-Yin Yang. */ - internal abstract class Mod + internal static class Mod { - private static readonly SecureRandom RandomSource = new SecureRandom(); - private const int M30 = 0x3FFFFFFF; private const ulong M32UL = 0xFFFFFFFFUL; @@ -41,7 +39,7 @@ namespace Org.BouncyCastle.Math.Raw public static uint Inverse32(uint d) { - Debug.Assert((d & 1) == 1); + Debug.Assert((d & 1U) == 1U); //int x = d + (((d + 1) & 4) << 1); // d.x == 1 mod 2**4 uint x = d; // d.x == 1 mod 2**3 @@ -53,6 +51,21 @@ namespace Org.BouncyCastle.Math.Raw return x; } + public static ulong Inverse64(ulong d) + { + Debug.Assert((d & 1UL) == 1UL); + + //ulong x = d + (((d + 1) & 4) << 1); // d.x == 1 mod 2**4 + ulong x = d; // d.x == 1 mod 2**3 + x *= 2 - d * x; // d.x == 1 mod 2**6 + x *= 2 - d * x; // d.x == 1 mod 2**12 + x *= 2 - d * x; // d.x == 1 mod 2**24 + x *= 2 - d * x; // d.x == 1 mod 2**48 + x *= 2 - d * x; // d.x == 1 mod 2**96 + Debug.Assert(d * x == 1UL); + return x; + } + public static uint ModOddInverse(uint[] m, uint[] x, uint[] z) { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -349,7 +362,7 @@ namespace Org.BouncyCastle.Math.Raw } #endif - public static uint[] Random(uint[] p) + public static uint[] Random(SecureRandom random, uint[] p) { int len = p.Length; uint[] s = Nat.Create(len); @@ -364,7 +377,7 @@ namespace Org.BouncyCastle.Math.Raw byte[] bytes = new byte[len << 2]; do { - RandomSource.NextBytes(bytes); + random.NextBytes(bytes); Pack.BE_To_UInt32(bytes, 0, s); s[len - 1] &= m; } @@ -374,7 +387,7 @@ namespace Org.BouncyCastle.Math.Raw } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static void Random(ReadOnlySpan<uint> p, Span<uint> z) + public static void Random(SecureRandom random, ReadOnlySpan<uint> p, Span<uint> z) { int len = p.Length; if (z.Length < len) @@ -395,7 +408,7 @@ namespace Org.BouncyCastle.Math.Raw do { - RandomSource.NextBytes(bytes); + random.NextBytes(bytes); Pack.BE_To_UInt32(bytes, s); s[len - 1] &= m; } diff --git a/crypto/src/math/raw/Nat.cs b/crypto/src/math/raw/Nat.cs index 09c263f4d..3bc983430 100644 --- a/crypto/src/math/raw/Nat.cs +++ b/crypto/src/math/raw/Nat.cs @@ -1580,34 +1580,87 @@ namespace Org.BouncyCastle.Math.Raw public static uint ShiftUpBit(int len, uint[] z, uint c) { - for (int i = 0; i < len; ++i) +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBit(len, z.AsSpan(0, len), c); +#else + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = z[i + 0]; + uint next1 = z[i + 1]; + uint next2 = z[i + 2]; + uint next3 = z[i + 3]; + z[i + 0] = (next0 << 1) | (c >> 31); + z[i + 1] = (next1 << 1) | (next0 >> 31); + z[i + 2] = (next2 << 1) | (next1 >> 31); + z[i + 3] = (next3 << 1) | (next2 >> 31); + c = next3; + i += 4; + } + while (i < len) { uint next = z[i]; z[i] = (next << 1) | (c >> 31); c = next; + ++i; } return c >> 31; +#endif } public static uint ShiftUpBit(int len, uint[] z, int zOff, uint c) { - for (int i = 0; i < len; ++i) +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBit(len, z.AsSpan(zOff, len), c); +#else + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = z[zOff + i + 0]; + uint next1 = z[zOff + i + 1]; + uint next2 = z[zOff + i + 2]; + uint next3 = z[zOff + i + 3]; + z[zOff + i + 0] = (next0 << 1) | (c >> 31); + z[zOff + i + 1] = (next1 << 1) | (next0 >> 31); + z[zOff + i + 2] = (next2 << 1) | (next1 >> 31); + z[zOff + i + 3] = (next3 << 1) | (next2 >> 31); + c = next3; + i += 4; + } + while (i < len) { uint next = z[zOff + i]; z[zOff + i] = (next << 1) | (c >> 31); c = next; + ++i; } return c >> 31; +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint ShiftUpBit(int len, Span<uint> z, uint c) { - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = z[i + 0]; + uint next1 = z[i + 1]; + uint next2 = z[i + 2]; + uint next3 = z[i + 3]; + z[i + 0] = (next0 << 1) | (c >> 31); + z[i + 1] = (next1 << 1) | (next0 >> 31); + z[i + 2] = (next2 << 1) | (next1 >> 31); + z[i + 3] = (next3 << 1) | (next2 >> 31); + c = next3; + i += 4; + } + while (i < len) { uint next = z[i]; z[i] = (next << 1) | (c >> 31); c = next; + ++i; } return c >> 31; } @@ -1615,34 +1668,87 @@ namespace Org.BouncyCastle.Math.Raw public static uint ShiftUpBit(int len, uint[] x, uint c, uint[] z) { - for (int i = 0; i < len; ++i) +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBit(len, x.AsSpan(0, len), c, z.AsSpan(0, len)); +#else + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = x[i + 0]; + uint next1 = x[i + 1]; + uint next2 = x[i + 2]; + uint next3 = x[i + 3]; + z[i + 0] = (next0 << 1) | (c >> 31); + z[i + 1] = (next1 << 1) | (next0 >> 31); + z[i + 2] = (next2 << 1) | (next1 >> 31); + z[i + 3] = (next3 << 1) | (next2 >> 31); + c = next3; + i += 4; + } + while (i < len) { uint next = x[i]; z[i] = (next << 1) | (c >> 31); c = next; + ++i; } return c >> 31; +#endif } public static uint ShiftUpBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff) { - for (int i = 0; i < len; ++i) +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBit(len, x.AsSpan(xOff, len), c, z.AsSpan(zOff, len)); +#else + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = x[xOff + i + 0]; + uint next1 = x[xOff + i + 1]; + uint next2 = x[xOff + i + 2]; + uint next3 = x[xOff + i + 3]; + z[zOff + i + 0] = (next0 << 1) | (c >> 31); + z[zOff + i + 1] = (next1 << 1) | (next0 >> 31); + z[zOff + i + 2] = (next2 << 1) | (next1 >> 31); + z[zOff + i + 3] = (next3 << 1) | (next2 >> 31); + c = next3; + i += 4; + } + while (i < len) { uint next = x[xOff + i]; z[zOff + i] = (next << 1) | (c >> 31); c = next; + ++i; } return c >> 31; +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint ShiftUpBit(int len, ReadOnlySpan<uint> x, uint c, Span<uint> z) { - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = x[i + 0]; + uint next1 = x[i + 1]; + uint next2 = x[i + 2]; + uint next3 = x[i + 3]; + z[i + 0] = (next0 << 1) | (c >> 31); + z[i + 1] = (next1 << 1) | (next0 >> 31); + z[i + 2] = (next2 << 1) | (next1 >> 31); + z[i + 3] = (next3 << 1) | (next2 >> 31); + c = next3; + i += 4; + } + while (i < len) { uint next = x[i]; z[i] = (next << 1) | (c >> 31); c = next; + ++i; } return c >> 31; } @@ -1650,34 +1756,87 @@ namespace Org.BouncyCastle.Math.Raw public static ulong ShiftUpBit64(int len, ulong[] x, ulong c, ulong[] z) { - for (int i = 0; i < len; ++i) +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBit64(len, x.AsSpan(0, len), c, z.AsSpan(0, len)); +#else + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + ulong next0 = x[i + 0]; + ulong next1 = x[i + 1]; + ulong next2 = x[i + 2]; + ulong next3 = x[i + 3]; + z[i + 0] = (next0 << 1) | (c >> 63); + z[i + 1] = (next1 << 1) | (next0 >> 63); + z[i + 2] = (next2 << 1) | (next1 >> 63); + z[i + 3] = (next3 << 1) | (next2 >> 63); + c = next3; + i += 4; + } + while (i < len) { ulong next = x[i]; z[i] = (next << 1) | (c >> 63); c = next; + ++i; } return c >> 63; +#endif } public static ulong ShiftUpBit64(int len, ulong[] x, int xOff, ulong c, ulong[] z, int zOff) { - for (int i = 0; i < len; ++i) +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBit64(len, x.AsSpan(xOff, len), c, z.AsSpan(zOff, len)); +#else + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + ulong next0 = x[xOff + i + 0]; + ulong next1 = x[xOff + i + 1]; + ulong next2 = x[xOff + i + 2]; + ulong next3 = x[xOff + i + 3]; + z[zOff + i + 0] = (next0 << 1) | (c >> 63); + z[zOff + i + 1] = (next1 << 1) | (next0 >> 63); + z[zOff + i + 2] = (next2 << 1) | (next1 >> 63); + z[zOff + i + 3] = (next3 << 1) | (next2 >> 63); + c = next3; + i += 4; + } + while (i < len) { ulong next = x[xOff + i]; z[zOff + i] = (next << 1) | (c >> 63); c = next; + ++i; } return c >> 63; +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static ulong ShiftUpBit64(int len, ReadOnlySpan<ulong> x, ulong c, Span<ulong> z) { - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + ulong next0 = x[i + 0]; + ulong next1 = x[i + 1]; + ulong next2 = x[i + 2]; + ulong next3 = x[i + 3]; + z[i + 0] = (next0 << 1) | (c >> 63); + z[i + 1] = (next1 << 1) | (next0 >> 63); + z[i + 2] = (next2 << 1) | (next1 >> 63); + z[i + 3] = (next3 << 1) | (next2 >> 63); + c = next3; + i += 4; + } + while (i < len) { ulong next = x[i]; z[i] = (next << 1) | (c >> 63); c = next; + ++i; } return c >> 63; } @@ -1685,37 +1844,90 @@ namespace Org.BouncyCastle.Math.Raw public static uint ShiftUpBits(int len, uint[] z, int bits, uint c) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBits(len, z.AsSpan(0, len), bits, c); +#else Debug.Assert(bits > 0 && bits < 32); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = z[i + 0]; + uint next1 = z[i + 1]; + uint next2 = z[i + 2]; + uint next3 = z[i + 3]; + z[i + 0] = (next0 << bits) | (c >> -bits); + z[i + 1] = (next1 << bits) | (next0 >> -bits); + z[i + 2] = (next2 << bits) | (next1 >> -bits); + z[i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { uint next = z[i]; z[i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; +#endif } public static uint ShiftUpBits(int len, uint[] z, int zOff, int bits, uint c) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBits(len, z.AsSpan(zOff, len), bits, c); +#else Debug.Assert(bits > 0 && bits < 32); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = z[zOff + i + 0]; + uint next1 = z[zOff + i + 1]; + uint next2 = z[zOff + i + 2]; + uint next3 = z[zOff + i + 3]; + z[zOff + i + 0] = (next0 << bits) | (c >> -bits); + z[zOff + i + 1] = (next1 << bits) | (next0 >> -bits); + z[zOff + i + 2] = (next2 << bits) | (next1 >> -bits); + z[zOff + i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { uint next = z[zOff + i]; z[zOff + i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint ShiftUpBits(int len, Span<uint> z, int bits, uint c) { Debug.Assert(bits > 0 && bits < 32); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = z[i + 0]; + uint next1 = z[i + 1]; + uint next2 = z[i + 2]; + uint next3 = z[i + 3]; + z[i + 0] = (next0 << bits) | (c >> -bits); + z[i + 1] = (next1 << bits) | (next0 >> -bits); + z[i + 2] = (next2 << bits) | (next1 >> -bits); + z[i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { uint next = z[i]; z[i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; } @@ -1723,37 +1935,90 @@ namespace Org.BouncyCastle.Math.Raw public static uint ShiftUpBits(int len, uint[] x, int bits, uint c, uint[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBits(len, x.AsSpan(0, len), bits, c, z.AsSpan(0, len)); +#else Debug.Assert(bits > 0 && bits < 32); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = x[i + 0]; + uint next1 = x[i + 1]; + uint next2 = x[i + 2]; + uint next3 = x[i + 3]; + z[i + 0] = (next0 << bits) | (c >> -bits); + z[i + 1] = (next1 << bits) | (next0 >> -bits); + z[i + 2] = (next2 << bits) | (next1 >> -bits); + z[i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { uint next = x[i]; z[i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; +#endif } public static uint ShiftUpBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBits(len, x.AsSpan(xOff, len), bits, c, z.AsSpan(zOff, len)); +#else Debug.Assert(bits > 0 && bits < 32); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = x[xOff + i + 0]; + uint next1 = x[xOff + i + 1]; + uint next2 = x[xOff + i + 2]; + uint next3 = x[xOff + i + 3]; + z[zOff + i + 0] = (next0 << bits) | (c >> -bits); + z[zOff + i + 1] = (next1 << bits) | (next0 >> -bits); + z[zOff + i + 2] = (next2 << bits) | (next1 >> -bits); + z[zOff + i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { uint next = x[xOff + i]; z[zOff + i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint ShiftUpBits(int len, ReadOnlySpan<uint> x, int bits, uint c, Span<uint> z) { Debug.Assert(bits > 0 && bits < 32); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + uint next0 = x[i + 0]; + uint next1 = x[i + 1]; + uint next2 = x[i + 2]; + uint next3 = x[i + 3]; + z[i + 0] = (next0 << bits) | (c >> -bits); + z[i + 1] = (next1 << bits) | (next0 >> -bits); + z[i + 2] = (next2 << bits) | (next1 >> -bits); + z[i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { uint next = x[i]; z[i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; } @@ -1761,37 +2026,90 @@ namespace Org.BouncyCastle.Math.Raw public static ulong ShiftUpBits64(int len, ulong[] z, int bits, ulong c) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBits64(len, z.AsSpan(0, len), bits, c); +#else Debug.Assert(bits > 0 && bits < 64); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + ulong next0 = z[i + 0]; + ulong next1 = z[i + 1]; + ulong next2 = z[i + 2]; + ulong next3 = z[i + 3]; + z[i + 0] = (next0 << bits) | (c >> -bits); + z[i + 1] = (next1 << bits) | (next0 >> -bits); + z[i + 2] = (next2 << bits) | (next1 >> -bits); + z[i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { ulong next = z[i]; z[i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; +#endif } public static ulong ShiftUpBits64(int len, ulong[] z, int zOff, int bits, ulong c) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBits64(len, z.AsSpan(zOff, len), bits, c); +#else Debug.Assert(bits > 0 && bits < 64); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + ulong next0 = z[zOff + i + 0]; + ulong next1 = z[zOff + i + 1]; + ulong next2 = z[zOff + i + 2]; + ulong next3 = z[zOff + i + 3]; + z[zOff + i + 0] = (next0 << bits) | (c >> -bits); + z[zOff + i + 1] = (next1 << bits) | (next0 >> -bits); + z[zOff + i + 2] = (next2 << bits) | (next1 >> -bits); + z[zOff + i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { ulong next = z[zOff + i]; z[zOff + i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static ulong ShiftUpBits64(int len, Span<ulong> z, int bits, ulong c) { Debug.Assert(bits > 0 && bits < 64); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + ulong next0 = z[i + 0]; + ulong next1 = z[i + 1]; + ulong next2 = z[i + 2]; + ulong next3 = z[i + 3]; + z[i + 0] = (next0 << bits) | (c >> -bits); + z[i + 1] = (next1 << bits) | (next0 >> -bits); + z[i + 2] = (next2 << bits) | (next1 >> -bits); + z[i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { ulong next = z[i]; z[i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; } @@ -1799,37 +2117,90 @@ namespace Org.BouncyCastle.Math.Raw public static ulong ShiftUpBits64(int len, ulong[] x, int bits, ulong c, ulong[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBits64(len, x.AsSpan(0, len), bits, c, z.AsSpan(0, len)); +#else Debug.Assert(bits > 0 && bits < 64); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + ulong next0 = x[i + 0]; + ulong next1 = x[i + 1]; + ulong next2 = x[i + 2]; + ulong next3 = x[i + 3]; + z[i + 0] = (next0 << bits) | (c >> -bits); + z[i + 1] = (next1 << bits) | (next0 >> -bits); + z[i + 2] = (next2 << bits) | (next1 >> -bits); + z[i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { ulong next = x[i]; z[i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; +#endif } public static ulong ShiftUpBits64(int len, ulong[] x, int xOff, int bits, ulong c, ulong[] z, int zOff) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return ShiftUpBits64(len, x.AsSpan(xOff, len), bits, c, z.AsSpan(zOff, len)); +#else Debug.Assert(bits > 0 && bits < 64); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + ulong next0 = x[xOff + i + 0]; + ulong next1 = x[xOff + i + 1]; + ulong next2 = x[xOff + i + 2]; + ulong next3 = x[xOff + i + 3]; + z[zOff + i + 0] = (next0 << bits) | (c >> -bits); + z[zOff + i + 1] = (next1 << bits) | (next0 >> -bits); + z[zOff + i + 2] = (next2 << bits) | (next1 >> -bits); + z[zOff + i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { ulong next = x[xOff + i]; z[zOff + i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static ulong ShiftUpBits64(int len, ReadOnlySpan<ulong> x, int bits, ulong c, Span<ulong> z) { Debug.Assert(bits > 0 && bits < 64); - for (int i = 0; i < len; ++i) + int i = 0, limit4 = len - 4; + while (i <= limit4) + { + ulong next0 = x[i + 0]; + ulong next1 = x[i + 1]; + ulong next2 = x[i + 2]; + ulong next3 = x[i + 3]; + z[i + 0] = (next0 << bits) | (c >> -bits); + z[i + 1] = (next1 << bits) | (next0 >> -bits); + z[i + 2] = (next2 << bits) | (next1 >> -bits); + z[i + 3] = (next3 << bits) | (next2 >> -bits); + c = next3; + i += 4; + } + while (i < len) { ulong next = x[i]; z[i] = (next << bits) | (c >> -bits); c = next; + ++i; } return c >> -bits; } @@ -2325,39 +2696,205 @@ namespace Org.BouncyCastle.Math.Raw } #endif - public static void Zero(int len, uint[] z) + public static void Xor(int len, uint[] x, uint[] y, uint[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Xor(len, x.AsSpan(0, len), y.AsSpan(0, len), z.AsSpan(0, len)); +#else for (int i = 0; i < len; ++i) { - z[i] = 0U; + z[i] = x[i] ^ y[i]; } +#endif } + public static void Xor(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static void Zero(int len, Span<uint> z) + Xor(len, x.AsSpan(xOff, len), y.AsSpan(yOff, len), z.AsSpan(zOff, len)); +#else + for (int i = 0; i < len; ++i) + { + z[zOff + i] = x[xOff + i] ^ y[yOff + i]; + } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Xor(int len, ReadOnlySpan<uint> x, ReadOnlySpan<uint> y, Span<uint> z) + { + int i = 0, limit16 = len - 16; + while (i <= limit16) + { + Nat512.Xor(x[i..], y[i..], z[i..]); + i += 16; + } + while (i < len) + { + z[i] = x[i] ^ y[i]; + ++i; + } + } +#endif + + public static void Xor64(int len, ulong[] x, ulong[] y, ulong[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Xor64(len, x.AsSpan(0, len), y.AsSpan(0, len), z.AsSpan(0, len)); +#else for (int i = 0; i < len; ++i) { - z[i] = 0U; + z[i] = x[i] ^ y[i]; + } +#endif + } + + public static void Xor64(int len, ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Xor64(len, x.AsSpan(xOff, len), y.AsSpan(yOff, len), z.AsSpan(zOff, len)); +#else + for (int i = 0; i < len; ++i) + { + z[zOff + i] = x[xOff + i] ^ y[yOff + i]; + } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Xor64(int len, ReadOnlySpan<ulong> x, ReadOnlySpan<ulong> y, Span<ulong> z) + { + int i = 0, limit8 = len - 8; + while (i <= limit8) + { + Nat512.Xor64(x[i..], y[i..], z[i..]); + i += 8; + } + while (i < len) + { + z[i] = x[i] ^ y[i]; + ++i; } } #endif - public static void Zero64(int len, ulong[] z) + public static void XorTo(int len, uint[] x, uint[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + XorTo(len, x.AsSpan(0, len), z.AsSpan(0, len)); +#else for (int i = 0; i < len; ++i) { - z[i] = 0UL; + z[i] ^= x[i]; } +#endif } + public static void XorTo(int len, uint[] x, int xOff, uint[] z, int zOff) + { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static void Zero64(int len, Span<ulong> z) + XorTo(len, x.AsSpan(xOff, len), z.AsSpan(zOff, len)); +#else + for (int i = 0; i < len; ++i) + { + z[zOff + i] ^= x[xOff + i]; + } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void XorTo(int len, ReadOnlySpan<uint> x, Span<uint> z) + { + int i = 0, limit16 = len - 16; + while (i <= limit16) + { + Nat512.XorTo(x[i..], z[i..]); + i += 16; + } + while (i < len) + { + z[i] ^= x[i]; + ++i; + } + } +#endif + + public static void XorTo64(int len, ulong[] x, ulong[] z) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + XorTo64(len, x.AsSpan(0, len), z.AsSpan(0, len)); +#else + for (int i = 0; i < len; ++i) + { + z[i] ^= x[i]; + } +#endif + } + + public static void XorTo64(int len, ulong[] x, int xOff, ulong[] z, int zOff) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + XorTo64(len, x.AsSpan(xOff, len), z.AsSpan(zOff, len)); +#else + for (int i = 0; i < len; ++i) + { + z[zOff + i] ^= x[xOff + i]; + } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void XorTo64(int len, ReadOnlySpan<ulong> x, Span<ulong> z) + { + int i = 0, limit8 = len - 8; + while (i <= limit8) + { + Nat512.XorTo64(x[i..], z[i..]); + i += 8; + } + while (i < len) + { + z[i] ^= x[i]; + ++i; + } + } +#endif + + public static void Zero(int len, uint[] z) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + z.AsSpan(0, len).Fill(0U); +#else + for (int i = 0; i < len; ++i) + { + z[i] = 0U; + } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Zero(int len, Span<uint> z) + { + z[..len].Fill(0U); + } +#endif + + public static void Zero64(int len, ulong[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + z.AsSpan(0, len).Fill(0UL); +#else for (int i = 0; i < len; ++i) { z[i] = 0UL; } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Zero64(int len, Span<ulong> z) + { + z[..len].Fill(0UL); } #endif } diff --git a/crypto/src/math/raw/Nat256.cs b/crypto/src/math/raw/Nat256.cs index 710060bee..47e0644f6 100644 --- a/crypto/src/math/raw/Nat256.cs +++ b/crypto/src/math/raw/Nat256.cs @@ -1,5 +1,11 @@ using System; using System.Diagnostics; +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Crypto.Utilities; @@ -1364,6 +1370,71 @@ namespace Org.BouncyCastle.Math.Raw return new BigInteger(1, bs); } + public static void Xor(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Xor(x.AsSpan(xOff), y.AsSpan(yOff), z.AsSpan(zOff)); +#else + for (int i = 0; i < 8; i += 4) + { + z[zOff + i + 0] = x[xOff + i + 0] ^ y[yOff + i + 0]; + z[zOff + i + 1] = x[xOff + i + 1] ^ y[yOff + i + 1]; + z[zOff + i + 2] = x[xOff + i + 2] ^ y[yOff + i + 2]; + z[zOff + i + 3] = x[xOff + i + 3] ^ y[yOff + i + 3]; + } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Xor(ReadOnlySpan<uint> x, ReadOnlySpan<uint> y, Span<uint> z) + { +#if NETCOREAPP3_0_OR_GREATER + if (Avx2.IsSupported && Unsafe.SizeOf<Vector256<byte>>() == 32) + { + var X = MemoryMarshal.AsBytes(x[..8]); + var Y = MemoryMarshal.AsBytes(y[..8]); + var Z = MemoryMarshal.AsBytes(z[..8]); + + var X0 = MemoryMarshal.Read<Vector256<byte>>(X[0x00..0x20]); + var Y0 = MemoryMarshal.Read<Vector256<byte>>(Y[0x00..0x20]); + + var Z0 = Avx2.Xor(X0, Y0); + + MemoryMarshal.Write(Z[0x00..0x20], ref Z0); + return; + } + + if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == 16) + { + var X = MemoryMarshal.AsBytes(x[..8]); + var Y = MemoryMarshal.AsBytes(y[..8]); + var Z = MemoryMarshal.AsBytes(z[..8]); + + var X0 = MemoryMarshal.Read<Vector128<byte>>(X[0x00..0x10]); + var X1 = MemoryMarshal.Read<Vector128<byte>>(X[0x10..0x20]); + + var Y0 = MemoryMarshal.Read<Vector128<byte>>(Y[0x00..0x10]); + var Y1 = MemoryMarshal.Read<Vector128<byte>>(Y[0x10..0x20]); + + var Z0 = Sse2.Xor(X0, Y0); + var Z1 = Sse2.Xor(X1, Y1); + + MemoryMarshal.Write(Z[0x00..0x10], ref Z0); + MemoryMarshal.Write(Z[0x10..0x20], ref Z1); + return; + } +#endif + + for (int i = 0; i < 8; i += 4) + { + z[i + 0] = x[i + 0] ^ y[i + 0]; + z[i + 1] = x[i + 1] ^ y[i + 1]; + z[i + 2] = x[i + 2] ^ y[i + 2]; + z[i + 3] = x[i + 3] ^ y[i + 3]; + } + } +#endif + public static void Zero(uint[] z) { z[0] = 0; diff --git a/crypto/src/math/raw/Nat512.cs b/crypto/src/math/raw/Nat512.cs index a9ef2b3b6..2312e1cf2 100644 --- a/crypto/src/math/raw/Nat512.cs +++ b/crypto/src/math/raw/Nat512.cs @@ -1,5 +1,10 @@ using System; -using System.Diagnostics; +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif namespace Org.BouncyCastle.Math.Raw { @@ -42,5 +47,313 @@ namespace Org.BouncyCastle.Math.Raw c24 += (uint)Nat.SubFrom(16, m, 0, zz, 8); Nat.AddWordAt(32, c24, zz, 24); } + + public static void Xor(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Xor(x.AsSpan(xOff), y.AsSpan(yOff), z.AsSpan(zOff)); +#else + for (int i = 0; i < 16; i += 4) + { + z[zOff + i + 0] = x[xOff + i + 0] ^ y[yOff + i + 0]; + z[zOff + i + 1] = x[xOff + i + 1] ^ y[yOff + i + 1]; + z[zOff + i + 2] = x[xOff + i + 2] ^ y[yOff + i + 2]; + z[zOff + i + 3] = x[xOff + i + 3] ^ y[yOff + i + 3]; + } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Xor(ReadOnlySpan<uint> x, ReadOnlySpan<uint> y, Span<uint> z) + { +#if NETCOREAPP3_0_OR_GREATER + if (Avx2.IsSupported && Unsafe.SizeOf<Vector256<byte>>() == 32) + { + var X = MemoryMarshal.AsBytes(x[..16]); + var Y = MemoryMarshal.AsBytes(y[..16]); + var Z = MemoryMarshal.AsBytes(z[..16]); + + var X0 = MemoryMarshal.Read<Vector256<byte>>(X[0x00..0x20]); + var X1 = MemoryMarshal.Read<Vector256<byte>>(X[0x20..0x40]); + + var Y0 = MemoryMarshal.Read<Vector256<byte>>(Y[0x00..0x20]); + var Y1 = MemoryMarshal.Read<Vector256<byte>>(Y[0x20..0x40]); + + var Z0 = Avx2.Xor(X0, Y0); + var Z1 = Avx2.Xor(X1, Y1); + + MemoryMarshal.Write(Z[0x00..0x20], ref Z0); + MemoryMarshal.Write(Z[0x20..0x40], ref Z1); + return; + } + + if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == 16) + { + var X = MemoryMarshal.AsBytes(x[..16]); + var Y = MemoryMarshal.AsBytes(y[..16]); + var Z = MemoryMarshal.AsBytes(z[..16]); + + var X0 = MemoryMarshal.Read<Vector128<byte>>(X[0x00..0x10]); + var X1 = MemoryMarshal.Read<Vector128<byte>>(X[0x10..0x20]); + var X2 = MemoryMarshal.Read<Vector128<byte>>(X[0x20..0x30]); + var X3 = MemoryMarshal.Read<Vector128<byte>>(X[0x30..0x40]); + + var Y0 = MemoryMarshal.Read<Vector128<byte>>(Y[0x00..0x10]); + var Y1 = MemoryMarshal.Read<Vector128<byte>>(Y[0x10..0x20]); + var Y2 = MemoryMarshal.Read<Vector128<byte>>(Y[0x20..0x30]); + var Y3 = MemoryMarshal.Read<Vector128<byte>>(Y[0x30..0x40]); + + var Z0 = Sse2.Xor(X0, Y0); + var Z1 = Sse2.Xor(X1, Y1); + var Z2 = Sse2.Xor(X2, Y2); + var Z3 = Sse2.Xor(X3, Y3); + + MemoryMarshal.Write(Z[0x00..0x10], ref Z0); + MemoryMarshal.Write(Z[0x10..0x20], ref Z1); + MemoryMarshal.Write(Z[0x20..0x30], ref Z2); + MemoryMarshal.Write(Z[0x30..0x40], ref Z3); + return; + } +#endif + + for (int i = 0; i < 16; i += 4) + { + z[i + 0] = x[i + 0] ^ y[i + 0]; + z[i + 1] = x[i + 1] ^ y[i + 1]; + z[i + 2] = x[i + 2] ^ y[i + 2]; + z[i + 3] = x[i + 3] ^ y[i + 3]; + } + } +#endif + + public static void XorTo(uint[] x, int xOff, uint[] z, int zOff) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + XorTo(x.AsSpan(xOff), z.AsSpan(zOff)); +#else + for (int i = 0; i < 16; i += 4) + { + z[zOff + i + 0] ^= x[xOff + i + 0]; + z[zOff + i + 1] ^= x[xOff + i + 1]; + z[zOff + i + 2] ^= x[xOff + i + 2]; + z[zOff + i + 3] ^= x[xOff + i + 3]; + } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void XorTo(ReadOnlySpan<uint> x, Span<uint> z) + { +#if NETCOREAPP3_0_OR_GREATER + if (Avx2.IsSupported && Unsafe.SizeOf<Vector256<byte>>() == 32) + { + var X = MemoryMarshal.AsBytes(x[..16]); + var Z = MemoryMarshal.AsBytes(z[..16]); + + var X0 = MemoryMarshal.Read<Vector256<byte>>(X[0x00..0x20]); + var X1 = MemoryMarshal.Read<Vector256<byte>>(X[0x20..0x40]); + + var Y0 = MemoryMarshal.Read<Vector256<byte>>(Z[0x00..0x20]); + var Y1 = MemoryMarshal.Read<Vector256<byte>>(Z[0x20..0x40]); + + var Z0 = Avx2.Xor(X0, Y0); + var Z1 = Avx2.Xor(X1, Y1); + + MemoryMarshal.Write(Z[0x00..0x20], ref Z0); + MemoryMarshal.Write(Z[0x20..0x40], ref Z1); + return; + } + + if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == 16) + { + var X = MemoryMarshal.AsBytes(x[..16]); + var Z = MemoryMarshal.AsBytes(z[..16]); + + var X0 = MemoryMarshal.Read<Vector128<byte>>(X[0x00..0x10]); + var X1 = MemoryMarshal.Read<Vector128<byte>>(X[0x10..0x20]); + var X2 = MemoryMarshal.Read<Vector128<byte>>(X[0x20..0x30]); + var X3 = MemoryMarshal.Read<Vector128<byte>>(X[0x30..0x40]); + + var Y0 = MemoryMarshal.Read<Vector128<byte>>(Z[0x00..0x10]); + var Y1 = MemoryMarshal.Read<Vector128<byte>>(Z[0x10..0x20]); + var Y2 = MemoryMarshal.Read<Vector128<byte>>(Z[0x20..0x30]); + var Y3 = MemoryMarshal.Read<Vector128<byte>>(Z[0x30..0x40]); + + var Z0 = Sse2.Xor(X0, Y0); + var Z1 = Sse2.Xor(X1, Y1); + var Z2 = Sse2.Xor(X2, Y2); + var Z3 = Sse2.Xor(X3, Y3); + + MemoryMarshal.Write(Z[0x00..0x10], ref Z0); + MemoryMarshal.Write(Z[0x10..0x20], ref Z1); + MemoryMarshal.Write(Z[0x20..0x30], ref Z2); + MemoryMarshal.Write(Z[0x30..0x40], ref Z3); + return; + } +#endif + + for (int i = 0; i < 16; i += 4) + { + z[i + 0] ^= x[i + 0]; + z[i + 1] ^= x[i + 1]; + z[i + 2] ^= x[i + 2]; + z[i + 3] ^= x[i + 3]; + } + } +#endif + + public static void Xor64(ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Xor64(x.AsSpan(xOff), y.AsSpan(yOff), z.AsSpan(zOff)); +#else + for (int i = 0; i < 8; i += 4) + { + z[zOff + i + 0] = x[xOff + i + 0] ^ y[yOff + i + 0]; + z[zOff + i + 1] = x[xOff + i + 1] ^ y[yOff + i + 1]; + z[zOff + i + 2] = x[xOff + i + 2] ^ y[yOff + i + 2]; + z[zOff + i + 3] = x[xOff + i + 3] ^ y[yOff + i + 3]; + } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Xor64(ReadOnlySpan<ulong> x, ReadOnlySpan<ulong> y, Span<ulong> z) + { +#if NETCOREAPP3_0_OR_GREATER + if (Avx2.IsSupported && Unsafe.SizeOf<Vector256<byte>>() == 32) + { + var X = MemoryMarshal.AsBytes(x[..8]); + var Y = MemoryMarshal.AsBytes(y[..8]); + var Z = MemoryMarshal.AsBytes(z[..8]); + + var X0 = MemoryMarshal.Read<Vector256<byte>>(X[0x00..0x20]); + var X1 = MemoryMarshal.Read<Vector256<byte>>(X[0x20..0x40]); + + var Y0 = MemoryMarshal.Read<Vector256<byte>>(Y[0x00..0x20]); + var Y1 = MemoryMarshal.Read<Vector256<byte>>(Y[0x20..0x40]); + + var Z0 = Avx2.Xor(X0, Y0); + var Z1 = Avx2.Xor(X1, Y1); + + MemoryMarshal.Write(Z[0x00..0x20], ref Z0); + MemoryMarshal.Write(Z[0x20..0x40], ref Z1); + return; + } + + if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == 16) + { + var X = MemoryMarshal.AsBytes(x[..8]); + var Y = MemoryMarshal.AsBytes(y[..8]); + var Z = MemoryMarshal.AsBytes(z[..8]); + + var X0 = MemoryMarshal.Read<Vector128<byte>>(X[0x00..0x10]); + var X1 = MemoryMarshal.Read<Vector128<byte>>(X[0x10..0x20]); + var X2 = MemoryMarshal.Read<Vector128<byte>>(X[0x20..0x30]); + var X3 = MemoryMarshal.Read<Vector128<byte>>(X[0x30..0x40]); + + var Y0 = MemoryMarshal.Read<Vector128<byte>>(Y[0x00..0x10]); + var Y1 = MemoryMarshal.Read<Vector128<byte>>(Y[0x10..0x20]); + var Y2 = MemoryMarshal.Read<Vector128<byte>>(Y[0x20..0x30]); + var Y3 = MemoryMarshal.Read<Vector128<byte>>(Y[0x30..0x40]); + + var Z0 = Sse2.Xor(X0, Y0); + var Z1 = Sse2.Xor(X1, Y1); + var Z2 = Sse2.Xor(X2, Y2); + var Z3 = Sse2.Xor(X3, Y3); + + MemoryMarshal.Write(Z[0x00..0x10], ref Z0); + MemoryMarshal.Write(Z[0x10..0x20], ref Z1); + MemoryMarshal.Write(Z[0x20..0x30], ref Z2); + MemoryMarshal.Write(Z[0x30..0x40], ref Z3); + return; + } +#endif + + for (int i = 0; i < 8; i += 4) + { + z[i + 0] = x[i + 0] ^ y[i + 0]; + z[i + 1] = x[i + 1] ^ y[i + 1]; + z[i + 2] = x[i + 2] ^ y[i + 2]; + z[i + 3] = x[i + 3] ^ y[i + 3]; + } + } +#endif + + public static void XorTo64(ulong[] x, int xOff, ulong[] z, int zOff) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + XorTo64(x.AsSpan(xOff), z.AsSpan(zOff)); +#else + for (int i = 0; i < 8; i += 4) + { + z[zOff + i + 0] ^= x[xOff + i + 0]; + z[zOff + i + 1] ^= x[xOff + i + 1]; + z[zOff + i + 2] ^= x[xOff + i + 2]; + z[zOff + i + 3] ^= x[xOff + i + 3]; + } +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void XorTo64(ReadOnlySpan<ulong> x, Span<ulong> z) + { +#if NETCOREAPP3_0_OR_GREATER + if (Avx2.IsSupported && Unsafe.SizeOf<Vector256<byte>>() == 32) + { + var X = MemoryMarshal.AsBytes(x[..8]); + var Z = MemoryMarshal.AsBytes(z[..8]); + + var X0 = MemoryMarshal.Read<Vector256<byte>>(X[0x00..0x20]); + var X1 = MemoryMarshal.Read<Vector256<byte>>(X[0x20..0x40]); + + var Y0 = MemoryMarshal.Read<Vector256<byte>>(Z[0x00..0x20]); + var Y1 = MemoryMarshal.Read<Vector256<byte>>(Z[0x20..0x40]); + + var Z0 = Avx2.Xor(X0, Y0); + var Z1 = Avx2.Xor(X1, Y1); + + MemoryMarshal.Write(Z[0x00..0x20], ref Z0); + MemoryMarshal.Write(Z[0x20..0x40], ref Z1); + return; + } + + if (Sse2.IsSupported && Unsafe.SizeOf<Vector128<byte>>() == 16) + { + var X = MemoryMarshal.AsBytes(x[..8]); + var Z = MemoryMarshal.AsBytes(z[..8]); + + var X0 = MemoryMarshal.Read<Vector128<byte>>(X[0x00..0x10]); + var X1 = MemoryMarshal.Read<Vector128<byte>>(X[0x10..0x20]); + var X2 = MemoryMarshal.Read<Vector128<byte>>(X[0x20..0x30]); + var X3 = MemoryMarshal.Read<Vector128<byte>>(X[0x30..0x40]); + + var Y0 = MemoryMarshal.Read<Vector128<byte>>(Z[0x00..0x10]); + var Y1 = MemoryMarshal.Read<Vector128<byte>>(Z[0x10..0x20]); + var Y2 = MemoryMarshal.Read<Vector128<byte>>(Z[0x20..0x30]); + var Y3 = MemoryMarshal.Read<Vector128<byte>>(Z[0x30..0x40]); + + var Z0 = Sse2.Xor(X0, Y0); + var Z1 = Sse2.Xor(X1, Y1); + var Z2 = Sse2.Xor(X2, Y2); + var Z3 = Sse2.Xor(X3, Y3); + + MemoryMarshal.Write(Z[0x00..0x10], ref Z0); + MemoryMarshal.Write(Z[0x10..0x20], ref Z1); + MemoryMarshal.Write(Z[0x20..0x30], ref Z2); + MemoryMarshal.Write(Z[0x30..0x40], ref Z3); + return; + } +#endif + + for (int i = 0; i < 8; i += 4) + { + z[i + 0] ^= x[i + 0]; + z[i + 1] ^= x[i + 1]; + z[i + 2] ^= x[i + 2]; + z[i + 3] ^= x[i + 3]; + } + } +#endif } } diff --git a/crypto/src/ocsp/BasicOCSPRespGenerator.cs b/crypto/src/ocsp/BasicOCSPRespGenerator.cs index 6cbba997d..ff7ae33d3 100644 --- a/crypto/src/ocsp/BasicOCSPRespGenerator.cs +++ b/crypto/src/ocsp/BasicOCSPRespGenerator.cs @@ -9,7 +9,6 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Operators; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; -using Org.BouncyCastle.Utilities; using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Ocsp @@ -28,8 +27,8 @@ namespace Org.BouncyCastle.Ocsp { internal CertificateID certId; internal CertStatus certStatus; - internal DerGeneralizedTime thisUpdate; - internal DerGeneralizedTime nextUpdate; + internal Asn1GeneralizedTime thisUpdate; + internal Asn1GeneralizedTime nextUpdate; internal X509Extensions extensions; internal ResponseObject( @@ -57,7 +56,7 @@ namespace Org.BouncyCastle.Ocsp : null; this.certStatus = new CertStatus( - new RevokedInfo(new DerGeneralizedTime(rs.RevocationTime), revocationReason)); + new RevokedInfo(new Asn1GeneralizedTime(rs.RevocationTime), revocationReason)); } this.thisUpdate = new DerGeneralizedTime(thisUpdate); @@ -187,7 +186,7 @@ namespace Org.BouncyCastle.Ocsp } } - ResponseData tbsResp = new ResponseData(responderID.ToAsn1Object(), new DerGeneralizedTime(producedAt), + ResponseData tbsResp = new ResponseData(responderID.ToAsn1Object(), new Asn1GeneralizedTime(producedAt), new DerSequence(responses), responseExtensions); DerBitString bitSig; diff --git a/crypto/src/ocsp/RevokedStatus.cs b/crypto/src/ocsp/RevokedStatus.cs index edbeb57da..903e50ef5 100644 --- a/crypto/src/ocsp/RevokedStatus.cs +++ b/crypto/src/ocsp/RevokedStatus.cs @@ -24,7 +24,7 @@ namespace Org.BouncyCastle.Ocsp DateTime revocationDate, int reason) { - this.info = new RevokedInfo(new DerGeneralizedTime(revocationDate), new CrlReason(reason)); + this.info = new RevokedInfo(new Asn1GeneralizedTime(revocationDate), new CrlReason(reason)); } public DateTime RevocationTime diff --git a/crypto/src/openpgp/PgpCompressedData.cs b/crypto/src/openpgp/PgpCompressedData.cs index fc7d200d0..346b0b1a1 100644 --- a/crypto/src/openpgp/PgpCompressedData.cs +++ b/crypto/src/openpgp/PgpCompressedData.cs @@ -1,7 +1,6 @@ using System.IO; -using Org.BouncyCastle.Bzip2; -using Org.BouncyCastle.Utilities.Zlib; +using Org.BouncyCastle.Utilities.IO.Compression; namespace Org.BouncyCastle.Bcpg.OpenPgp { @@ -38,16 +37,16 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp { switch (Algorithm) { - case CompressionAlgorithmTag.Uncompressed: - return GetInputStream(); - case CompressionAlgorithmTag.Zip: - return new ZInputStream(GetInputStream(), true); - case CompressionAlgorithmTag.ZLib: - return new ZInputStream(GetInputStream()); - case CompressionAlgorithmTag.BZip2: - return new CBZip2InputStream(GetInputStream()); - default: - throw new PgpException("can't recognise compression algorithm: " + Algorithm); + case CompressionAlgorithmTag.Uncompressed: + return GetInputStream(); + case CompressionAlgorithmTag.Zip: + return Zip.DecompressInput(GetInputStream()); + case CompressionAlgorithmTag.ZLib: + return ZLib.DecompressInput(GetInputStream()); + case CompressionAlgorithmTag.BZip2: + return Bzip2.DecompressInput(GetInputStream()); + default: + throw new PgpException("can't recognise compression algorithm: " + Algorithm); } } } diff --git a/crypto/src/openpgp/PgpCompressedDataGenerator.cs b/crypto/src/openpgp/PgpCompressedDataGenerator.cs index 791aac0bf..d13d7402b 100644 --- a/crypto/src/openpgp/PgpCompressedDataGenerator.cs +++ b/crypto/src/openpgp/PgpCompressedDataGenerator.cs @@ -1,8 +1,8 @@ using System; using System.IO; -using Org.BouncyCastle.Bzip2; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO.Compression; using Org.BouncyCastle.Utilities.Zlib; namespace Org.BouncyCastle.Bcpg.OpenPgp @@ -131,21 +131,21 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp switch (algorithm) { - case CompressionAlgorithmTag.Uncompressed: - dOut = pkOut; - break; - case CompressionAlgorithmTag.Zip: - dOut = new SafeZOutputStream(pkOut, compression, true); - break; - case CompressionAlgorithmTag.ZLib: - dOut = new SafeZOutputStream(pkOut, compression, false); - break; - case CompressionAlgorithmTag.BZip2: - dOut = new SafeCBZip2OutputStream(pkOut); - break; - default: - // Constructor should guard against this possibility - throw new InvalidOperationException(); + case CompressionAlgorithmTag.Uncompressed: + dOut = pkOut; + break; + case CompressionAlgorithmTag.Zip: + dOut = Zip.CompressOutput(pkOut, compression, true); + break; + case CompressionAlgorithmTag.ZLib: + dOut = ZLib.CompressOutput(pkOut, compression, true); + break; + case CompressionAlgorithmTag.BZip2: + dOut = Bzip2.CompressOutput(pkOut, true); + break; + default: + // Constructor should guard against this possibility + throw new InvalidOperationException(); } } @@ -165,31 +165,5 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp pkOut = null; } } - - private class SafeCBZip2OutputStream : CBZip2OutputStream - { - public SafeCBZip2OutputStream(Stream output) - : base(output) - { - } - - protected override void Dispose(bool disposing) - { - Detach(disposing); - } - } - - private class SafeZOutputStream : ZOutputStream - { - public SafeZOutputStream(Stream output, int level, bool nowrap) - : base(output, level, nowrap) - { - } - - protected override void Dispose(bool disposing) - { - Detach(disposing); - } - } } } diff --git a/crypto/src/openpgp/PgpEncryptedDataGenerator.cs b/crypto/src/openpgp/PgpEncryptedDataGenerator.cs index a86dce42d..589895522 100644 --- a/crypto/src/openpgp/PgpEncryptedDataGenerator.cs +++ b/crypto/src/openpgp/PgpEncryptedDataGenerator.cs @@ -219,7 +219,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp SymmetricKeyAlgorithmTag encAlgorithm) { this.defAlgorithm = encAlgorithm; - this.rand = new SecureRandom(); + this.rand = CryptoServicesRegistrar.GetSecureRandom(); } public PgpEncryptedDataGenerator( @@ -228,42 +228,51 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp { this.defAlgorithm = encAlgorithm; this.withIntegrityPacket = withIntegrityPacket; - this.rand = new SecureRandom(); - } + this.rand = CryptoServicesRegistrar.GetSecureRandom(); + } - /// <summary>Existing SecureRandom constructor.</summary> - /// <param name="encAlgorithm">The symmetric algorithm to use.</param> - /// <param name="rand">Source of randomness.</param> + /// <summary>Existing SecureRandom constructor.</summary> + /// <param name="encAlgorithm">The symmetric algorithm to use.</param> + /// <param name="random">Source of randomness.</param> public PgpEncryptedDataGenerator( SymmetricKeyAlgorithmTag encAlgorithm, - SecureRandom rand) + SecureRandom random) { + if (random == null) + throw new ArgumentNullException(nameof(random)); + this.defAlgorithm = encAlgorithm; - this.rand = rand; + this.rand = random; } /// <summary>Creates a cipher stream which will have an integrity packet associated with it.</summary> public PgpEncryptedDataGenerator( SymmetricKeyAlgorithmTag encAlgorithm, bool withIntegrityPacket, - SecureRandom rand) + SecureRandom random) { + if (random == null) + throw new ArgumentNullException(nameof(random)); + this.defAlgorithm = encAlgorithm; - this.rand = rand; + this.rand = random; this.withIntegrityPacket = withIntegrityPacket; } - /// <summary>Base constructor.</summary> - /// <param name="encAlgorithm">The symmetric algorithm to use.</param> - /// <param name="rand">Source of randomness.</param> - /// <param name="oldFormat">PGP 2.6.x compatibility required.</param> + /// <summary>Base constructor.</summary> + /// <param name="encAlgorithm">The symmetric algorithm to use.</param> + /// <param name="random">Source of randomness.</param> + /// <param name="oldFormat">PGP 2.6.x compatibility required.</param> public PgpEncryptedDataGenerator( SymmetricKeyAlgorithmTag encAlgorithm, - SecureRandom rand, + SecureRandom random, bool oldFormat) { + if (random == null) + throw new ArgumentNullException(nameof(random)); + this.defAlgorithm = encAlgorithm; - this.rand = rand; + this.rand = random; this.oldFormat = oldFormat; } diff --git a/crypto/src/openssl/Pkcs8Generator.cs b/crypto/src/openssl/Pkcs8Generator.cs index 0674cce15..242c966d0 100644 --- a/crypto/src/openssl/Pkcs8Generator.cs +++ b/crypto/src/openssl/Pkcs8Generator.cs @@ -83,10 +83,7 @@ namespace Org.BouncyCastle.OpenSsl // TODO Theoretically, the amount of salt needed depends on the algorithm byte[] salt = new byte[20]; - if (random == null) - { - random = new SecureRandom(); - } + random = CryptoServicesRegistrar.GetSecureRandom(random); random.NextBytes(salt); try diff --git a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs index a1c3ce734..88affe53d 100644 --- a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs +++ b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs @@ -630,11 +630,11 @@ namespace Org.BouncyCastle.Pkix if (index - 1 == 0) { - DerGeneralizedTime dateOfCertgen; + Asn1GeneralizedTime dateOfCertgen; try { Asn1OctetString extVal = cert.GetExtensionValue(IsisMttObjectIdentifiers.IdIsisMttATDateOfCertGen); - dateOfCertgen = DerGeneralizedTime.GetInstance(extVal); + dateOfCertgen = Asn1GeneralizedTime.GetInstance(extVal); } catch (ArgumentException) { diff --git a/crypto/src/pqc/crypto/bike/BikeEngine.cs b/crypto/src/pqc/crypto/bike/BikeEngine.cs index 94f073bbb..f7c126c66 100644 --- a/crypto/src/pqc/crypto/bike/BikeEngine.cs +++ b/crypto/src/pqc/crypto/bike/BikeEngine.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; + using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Security; @@ -22,7 +23,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike private readonly int t; //the shared secret size - private readonly int l; + //private readonly int l; // number of iterations in BGF decoder private readonly int nbIter; @@ -39,7 +40,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike this.r = r; this.w = w; this.t = t; - this.l = l; + //this.l = l; this.nbIter = nbIter; this.tau = tau; this.hw = this.w / 2; diff --git a/crypto/src/pqc/crypto/bike/BikeKeyPairGenerator.cs b/crypto/src/pqc/crypto/bike/BikeKeyPairGenerator.cs index 5636458fd..f621306bc 100644 --- a/crypto/src/pqc/crypto/bike/BikeKeyPairGenerator.cs +++ b/crypto/src/pqc/crypto/bike/BikeKeyPairGenerator.cs @@ -12,22 +12,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike private int r; // the row weight - private int w; + //private int w; // Hamming weight of h0, h1 - private int hw; + //private int hw; // the error weight - private int t; + //private int t; //the shared secret size private int l; // number of iterations in BGF decoder - private int nbIter; + //private int nbIter; // tau - private int tau; + //private int tau; private int L_BYTE; private int R_BYTE; @@ -40,12 +40,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike // get parameters this.r = this.bikeKeyGenerationParameters.Parameters.R; - this.w = this.bikeKeyGenerationParameters.Parameters.W; + //this.w = this.bikeKeyGenerationParameters.Parameters.W; this.l = this.bikeKeyGenerationParameters.Parameters.L; - this.t = this.bikeKeyGenerationParameters.Parameters.T; - this.nbIter = this.bikeKeyGenerationParameters.Parameters.NbIter; - this.tau = this.bikeKeyGenerationParameters.Parameters.Tau; - this.hw = w / 2; + //this.t = this.bikeKeyGenerationParameters.Parameters.T; + //this.nbIter = this.bikeKeyGenerationParameters.Parameters.NbIter; + //this.tau = this.bikeKeyGenerationParameters.Parameters.Tau; + //this.hw = w / 2; this.L_BYTE = l / 8; this.R_BYTE = (r + 7) / 8; } diff --git a/crypto/src/pqc/crypto/bike/BikeRing.cs b/crypto/src/pqc/crypto/bike/BikeRing.cs index c2b2102b8..a519595af 100644 --- a/crypto/src/pqc/crypto/bike/BikeRing.cs +++ b/crypto/src/pqc/crypto/bike/BikeRing.cs @@ -30,10 +30,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike internal void Add(ulong[] x, ulong[] y, ulong[] z) { - for (int i = 0; i < Size; ++i) - { - z[i] = x[i] ^ y[i]; - } + Nat.Xor64(Size, x, y, z); + } + + internal void AddTo(ulong[] x, ulong[] z) + { + Nat.XorTo64(Size, x, z); } internal void Copy(ulong[] x, ulong[] z) @@ -54,23 +56,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike return new ulong[SizeExt]; } - internal ulong[] DecodeBits(byte[] bs) - { - if (bs.Length > m_bits) - throw new ArgumentException(); - - ulong[] z = Create(); - for (int i = 0; i < bs.Length; ++i) - { - ulong bit = bs[i]; - if ((bit >> 1) != 0UL) - throw new ArgumentException(); - - z[i >> 6] |= bit << (i & 63); - } - return z; - } - internal void DecodeBytes(byte[] bs, ulong[] z) { int partialBits = m_bits & 63; @@ -78,7 +63,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike byte[] last = new byte[8]; Array.Copy(bs, (Size - 1) << 3, last, 0, (partialBits + 7) >> 3); z[Size - 1] = Pack.LE_To_UInt64(last); - Debug.Assert((z[Size - 1] >> partialBits) == 0); + Debug.Assert((z[Size - 1] >> partialBits) == 0UL); } internal byte[] EncodeBits(ulong[] x) @@ -94,7 +79,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike internal void EncodeBytes(ulong[] x, byte[] bs) { int partialBits = m_bits & 63; - Debug.Assert((x[Size - 1] >> partialBits) == 0); + Debug.Assert((x[Size - 1] >> partialBits) == 0UL); Pack.UInt64_To_LE(x, 0, Size - 1, bs, 0); byte[] last = new byte[8]; Pack.UInt64_To_LE(x[Size - 1], last); @@ -170,12 +155,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike ulong c = Nat.ShiftUpBits64(Size, tt, Size, excessBits, tt[Size - 1], z, 0); Debug.Assert(c == 0UL); - - for (int i = 0; i < Size; ++i) - { - z[i] ^= tt[i]; - } - + AddTo(tt, z); z[Size - 1] &= partialMask; } @@ -192,6 +172,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike internal void SquareN(ulong[] x, int n, ulong[] z) { + /* + * TODO In these polynomial rings, 'squareN' for some 'n' is equivalent to a fixed permutation of the + * coefficients. For 'squareN' with 'n' above some cutoff value, this permutation could be precomputed + * and then applied in place of explicit squaring for that 'n'. This is particularly relevant to the + * calls generated by 'inv'. + */ + Debug.Assert(n > 0); ulong[] tt = CreateExt(); diff --git a/crypto/src/pqc/crypto/cmce/CmceEngine.cs b/crypto/src/pqc/crypto/cmce/CmceEngine.cs index 7dd404427..10b08e708 100644 --- a/crypto/src/pqc/crypto/cmce/CmceEngine.cs +++ b/crypto/src/pqc/crypto/cmce/CmceEngine.cs @@ -1,4 +1,7 @@ using System; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +using System.Runtime.InteropServices; +#endif using Org.BouncyCastle.Asn1.Nist; using Org.BouncyCastle.Crypto; @@ -1460,9 +1463,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce row = i * 8 + j; if (row >= PK_NROWS) - { break; - } + + byte[] mat_row = mat[row]; if (usePivots) { @@ -1470,7 +1473,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce { if (MovColumns(mat, pi, pivots) != 0) { - // System.out.println("failed mov column!"); + //System.out.println("failed mov column!"); return -1; } } @@ -1478,21 +1481,37 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce for (k = row + 1; k < PK_NROWS; k++) { - mask = (byte)(mat[row][i] ^ mat[k][i]); + byte[] mat_k = mat[k]; + mask = (byte)(mat_row[i] ^ mat_k[i]); mask >>= j; mask &= 1; - mask = (byte)-mask; - for (c = 0; c < SYS_N / 8; c++) + c = 0; + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + ulong mask64 = 0UL - mask; + int limit64 = (SYS_N / 8) - 8; + while (c <= limit64) { - mat[row][c] ^= (byte)(mat[k][c] & mask); + ulong t0 = MemoryMarshal.Read<ulong>(mat_k.AsSpan(c)) & mask64; + ulong t1 = MemoryMarshal.Read<ulong>(mat_row.AsSpan(c)) ^ t0; + MemoryMarshal.Write(mat_row.AsSpan(c), ref t1); + c += 8; + } +#endif + byte maskByte = (byte)-mask; + while (c < SYS_N / 8) + { + mat_row[c] ^= (byte)(mat_k[c] & maskByte); + ++c; } } + // 7. Compute (T,cn−k−μ+1,...,cn−k,Γ′) ← MatGen(Γ). If this fails, set δ ← δ′ and // restart the algorithm. - if (((mat[row][i] >> j) & 1) == 0) // return if not systematic + if (((mat_row[i] >> j) & 1) == 0) // return if not systematic { - // System.out.println("FAIL 2\n"); + //System.out.println("FAIL 2\n"); return -1; } @@ -1500,14 +1519,35 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce { if (k != row) { - mask = (byte)(mat[k][i] >> j); + byte[] mat_k = mat[k]; + mask = (byte)(mat_k[i] >> j); mask &= 1; - mask = (byte)-mask; - for (c = 0; c < SYS_N / 8; c++) - { - mat[k][c] ^= (byte)(mat[row][c] & mask); + //mask = (byte)-mask; + + //for (c = 0; c < SYS_N / 8; c++) + //{ + // mat_k[c] ^= (byte)(mat_row[c] & mask); + //} + c = 0; + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + ulong mask64 = 0UL - mask; + int limit64 = (SYS_N / 8) - 8; + while (c <= limit64) + { + ulong t0 = MemoryMarshal.Read<ulong>(mat_row.AsSpan(c)) & mask64; + ulong t1 = MemoryMarshal.Read<ulong>(mat_k.AsSpan(c)) ^ t0; + MemoryMarshal.Write(mat_k.AsSpan(c), ref t1); + c += 8; + } +#endif + byte maskByte = (byte)-mask; + while (c < SYS_N / 8) + { + mat_k[c] ^= (byte)(mat_row[c] & maskByte); + ++c; } } } @@ -1546,7 +1586,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce return 0; } - private ushort Eval(ushort[] f, ushort a) { ushort r; diff --git a/crypto/src/pqc/crypto/falcon/FalconFPR.cs b/crypto/src/pqc/crypto/falcon/FalconFPR.cs index b3f99f944..bab3d8fcb 100644 --- a/crypto/src/pqc/crypto/falcon/FalconFPR.cs +++ b/crypto/src/pqc/crypto/falcon/FalconFPR.cs @@ -2,11 +2,12 @@ using System; namespace Org.BouncyCastle.Pqc.Crypto.Falcon { - class FalconFPR + internal struct FalconFPR { internal double v; - internal FalconFPR(double v) { + internal FalconFPR(double v) + { this.v = v; } } diff --git a/crypto/src/pqc/crypto/falcon/FalconSigner.cs b/crypto/src/pqc/crypto/falcon/FalconSigner.cs index 4c2362503..f581386ee 100644 --- a/crypto/src/pqc/crypto/falcon/FalconSigner.cs +++ b/crypto/src/pqc/crypto/falcon/FalconSigner.cs @@ -1,9 +1,7 @@ using System; + using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Pqc.Crypto; -using Org.BouncyCastle.Security; using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Falcon { @@ -17,12 +15,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon { if (forSigning) { - if (param is ParametersWithRandom) + if (param is ParametersWithRandom withRandom) { - FalconPrivateKeyParameters skparam = ((FalconPrivateKeyParameters)((ParametersWithRandom)param).Parameters); + FalconPrivateKeyParameters skparam = (FalconPrivateKeyParameters)withRandom.Parameters; encodedkey = skparam.GetEncoded(); nist = new FalconNIST( - ((ParametersWithRandom)param).Random, + withRandom.Random, skparam.Parameters.LogN, skparam.Parameters.NonceLength); } @@ -31,13 +29,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon FalconPrivateKeyParameters skparam = (FalconPrivateKeyParameters)param; encodedkey = ((FalconPrivateKeyParameters)param).GetEncoded(); nist = new FalconNIST( - new SecureRandom(), - // CryptoServicesRegistrar.GetSecureRandom(), + CryptoServicesRegistrar.GetSecureRandom(), skparam.Parameters.LogN, - skparam.Parameters.NonceLength - ); - // TODO when CryptoServicesRegistrar has been implemented, use that instead - + skparam.Parameters.NonceLength); } } else @@ -45,8 +39,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon FalconPublicKeyParameters pkparam = (FalconPublicKeyParameters)param; encodedkey = pkparam.GetEncoded(); nist = new FalconNIST( - new SecureRandom(), - // CryptoServicesRegistrar.GetSecureRandom() + CryptoServicesRegistrar.GetSecureRandom(), pkparam.Parameters.LogN, pkparam.Parameters.NonceLength); } diff --git a/crypto/src/pqc/crypto/hqc/FastFourierTransform.cs b/crypto/src/pqc/crypto/hqc/FastFourierTransform.cs new file mode 100644 index 000000000..be7e822d0 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/FastFourierTransform.cs @@ -0,0 +1,279 @@ +using System; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + internal class FastFourierTransform + { + internal static void FFT(int[] output, int[] elements, int noCoefs, int fft) + { + int m = HqcParameters.PARAM_M; + int mSize = 1 << (HqcParameters.PARAM_M - 1); + + int fftSize = 1 << fft; + + int[] f0 = new int[fftSize]; + int[] f1 = new int[fftSize]; + int[] deltas = new int[m - 1]; + int[] u = new int[mSize]; + int[] v = new int[mSize]; + + // Step 1: Compute betas + int[] betas = new int[m - 1]; + int[] betaSum = new int[mSize]; + + ComputeFFTBetas(betas, m); + ComputeSubsetSum(betaSum, betas, m - 1); + + // Step 2: Compute radix + ComputeRadix(f0, f1, elements, fft, fft); + + // Step 3: Compute deltas + for (int i = 0; i < m - 1; i++) + { + deltas[i] = GFCalculator.mult(betas[i], betas[i]) ^ betas[i]; + } + + // Step 5: + ComputeFFTRec(u, f0, (noCoefs + 1) / 2, m - 1, fft - 1, deltas, fft, m); + ComputeFFTRec(v, f1, noCoefs / 2, m - 1, fft - 1, deltas, fft, m); + + // Step 6.7 + int k = 1; + k = 1 << (m - 1); + + Array.Copy(v, 0, output, k, k); + + output[0] = u[0]; + output[k] ^= u[0]; + + for (int i = 1; i < k; i++) + { + output[i] = u[i] ^ GFCalculator.mult(betaSum[i], v[i]); + output[k + i] ^= output[i]; + } + } + + internal static void ComputeFFTBetas(int[] betas, int m) + { + for (int i = 0; i < m - 1; i++) + { + betas[i] = 1 << (m - 1 - i); + } + } + + internal static void ComputeSubsetSum(int[] subsetSum, int[] set, int size) + { + subsetSum[0] = 0; + + for (int i = 0; i < size; i++) + { + for (int j = 0; j < (1 << i); j++) + { + subsetSum[(1 << i) + j] = set[i] ^ subsetSum[j]; + } + } + } + + internal static void ComputeRadix(int[] f0, int[] f1, int[] f, int mf, int fft) + { + switch (mf) + { + case 4: + f0[4] = f[8] ^ f[12]; + f0[6] = f[12] ^ f[14]; + f0[7] = f[14] ^ f[15]; + f1[5] = f[11] ^ f[13]; + f1[6] = f[13] ^ f[14]; + f1[7] = f[15]; + f0[5] = f[10] ^ f[12] ^ f1[5]; + f1[4] = f[9] ^ f[13] ^ f0[5]; + + f0[0] = f[0]; + f1[3] = f[7] ^ f[11] ^ f[15]; + f0[3] = f[6] ^ f[10] ^ f[14] ^ f1[3]; + f0[2] = f[4] ^ f0[4] ^ f0[3] ^ f1[3]; + f1[1] = f[3] ^ f[5] ^ f[9] ^ f[13] ^ f1[3]; + f1[2] = f[3] ^ f1[1] ^ f0[3]; + f0[1] = f[2] ^ f0[2] ^ f1[1]; + f1[0] = f[1] ^ f0[1]; + return; + + case 3: + f0[0] = f[0]; + f0[2] = f[4] ^ f[6]; + f0[3] = f[6] ^ f[7]; + f1[1] = f[3] ^ f[5] ^ f[7]; + f1[2] = f[5] ^ f[6]; + f1[3] = f[7]; + f0[1] = f[2] ^ f0[2] ^ f1[1]; + f1[0] = f[1] ^ f0[1]; + return; + + case 2: + f0[0] = f[0]; + f0[1] = f[2] ^ f[3]; + f1[0] = f[1] ^ f0[1]; + f1[1] = f[3]; + return; + + case 1: + f0[0] = f[0]; + f1[0] = f[1]; + return; + + default: + ComputeRadixBig(f0, f1, f, mf, fft); + break; + } + } + + internal static void ComputeRadixBig(int[] f0, int[] f1, int[] f, int mf, int fft) + { + int n = 1; + n <<= (mf - 2); + int fftSize = 1 << (fft - 2); + + int[] Q = new int[2 * fftSize]; + int[] R = new int[2 * fftSize]; + + int[] Q0 = new int[fftSize]; + int[] Q1 = new int[fftSize]; + int[] R0 = new int[fftSize]; + int[] R1 = new int[fftSize]; + + + Utils.CopyBytes(f, 3 * n, Q, 0, 2 * n); + Utils.CopyBytes(f, 3 * n, Q, n, 2 * n); + Utils.CopyBytes(f, 0, R, 0, 4 * n); + + for (int i = 0; i < n; ++i) + { + Q[i] ^= f[2 * n + i]; + R[n + i] ^= Q[i]; + } + + ComputeRadix(Q0, Q1, Q, mf - 1, fft); + ComputeRadix(R0, R1, R, mf - 1, fft); + + Utils.CopyBytes(R0, 0, f0, 0, 2 * n); + Utils.CopyBytes(Q0, 0, f0, n, 2 * n); + Utils.CopyBytes(R1, 0, f1, 0, 2 * n); + Utils.CopyBytes(Q1, 0, f1, n, 2 * n); + } + + internal static void ComputeFFTRec(int[] output, int[] func, int noCoeffs, int noOfBetas, int noCoeffsPlus, int[] betaSet, int fft, int m) + { + int fftSize = 1 << (fft - 2); + int mSize = 1 << (m - 2); + + int[] fx0 = new int[fftSize]; + int[] fx1 = new int[fftSize]; + int[] gammaSet = new int[m - 2]; + int[] deltaSet = new int[m - 2]; + int k = 1; + int[] gammaSumSet = new int[mSize]; + int[] uSet = new int[mSize]; + int[] vSet = new int[mSize]; + int[] tempSet = new int[m - fft + 1]; + + int x = 0; + if (noCoeffsPlus == 1) + { + for (int i = 0; i < noOfBetas; i++) + { + tempSet[i] = GFCalculator.mult(betaSet[i], func[1]); + } + + output[0] = func[0]; + x = 1; + for (int j = 0; j < noOfBetas; j++) + { + for (int t = 0; t < x; t++) + { + output[x + t] = output[t] ^ tempSet[j]; + } + x <<= 1; + } + return; + } + + if (betaSet[noOfBetas - 1] != 1) + { + int betaMPow = 1; + x = 1; + x <<= noCoeffsPlus; + for (int i = 1; i < x; i++) + { + betaMPow = GFCalculator.mult(betaMPow, betaSet[noOfBetas - 1]); + func[i] = GFCalculator.mult(betaMPow, func[i]); + } + } + + ComputeRadix(fx0, fx1, func, noCoeffsPlus, fft); + + for (int i = 0; i < noOfBetas - 1; i++) + { + gammaSet[i] = GFCalculator.mult(betaSet[i], GFCalculator.inverse(betaSet[noOfBetas - 1])); + deltaSet[i] = GFCalculator.mult(gammaSet[i], gammaSet[i]) ^ gammaSet[i]; + } + + ComputeSubsetSum(gammaSumSet, gammaSet, noOfBetas - 1); + + ComputeFFTRec(uSet, fx0, (noCoeffs + 1) / 2, noOfBetas - 1, noCoeffsPlus - 1, deltaSet, fft, m); + + k = 1; + k <<= ((noOfBetas - 1) & 0xf); + if (noCoeffs <= 3) + { + output[0] = uSet[0]; + output[k] = uSet[0] ^ fx1[0]; + for (int i = 1; i < k; i++) + { + output[i] = uSet[i] ^ GFCalculator.mult(gammaSumSet[i], fx1[0]); + output[k + i] = output[i] ^ fx1[0]; + } + } + else + { + ComputeFFTRec(vSet, fx1, noCoeffs / 2, noOfBetas - 1, noCoeffsPlus - 1, deltaSet, fft, m); + + Array.Copy(vSet, 0, output, k, k); + + output[0] = uSet[0]; + output[k] ^= uSet[0]; + for (int i = 1; i < k; i++) + { + output[i] = uSet[i] ^ GFCalculator.mult(gammaSumSet[i], vSet[i]); + output[k + i] ^= output[i]; + } + + + } + } + + internal static void FastFourierTransformGetError(byte[] errorSet, int[] input, int mSize, int[] logArrays) + { + int m = HqcParameters.PARAM_M; + int gfMulOrder = HqcParameters.GF_MUL_ORDER; + + int[] gammaSet = new int[m - 1]; + int[] gammaSumSet = new int[mSize]; + int k = mSize; + + ComputeFFTBetas(gammaSet, m); + ComputeSubsetSum(gammaSumSet, gammaSet, m - 1); + + errorSet[0] ^= (byte) (1 ^ Utils.ToUnsigned16Bits(-input[0] >> 15)); + errorSet[0] ^= (byte) (1 ^ Utils.ToUnsigned16Bits(-input[k] >> 15)); + + for (int i = 1; i < k; i++) + { + int tmp = gfMulOrder - logArrays[gammaSumSet[i]]; + errorSet[tmp] ^= (byte) (1 ^ System.Math.Abs(-input[i] >> 15)); + + tmp = gfMulOrder - logArrays[gammaSumSet[i] ^ 1]; + errorSet[tmp] ^= (byte) (1 ^ System.Math.Abs(-input[k + i] >> 15)); + } + } + } +} diff --git a/crypto/src/pqc/crypto/hqc/GF2PolynomialCalculator.cs b/crypto/src/pqc/crypto/hqc/GF2PolynomialCalculator.cs new file mode 100644 index 000000000..0c01ade96 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/GF2PolynomialCalculator.cs @@ -0,0 +1,134 @@ +using System; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +using System.Buffers.Binary; +using System.Runtime.InteropServices; +#endif + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + internal class GF2PolynomialCalculator + { + private const int TABLE = 16; + + static void Mod(ulong[] res, ulong[] a, int n, int nByte64) + { + for (int i = 0; i < nByte64; i++) + { + ulong r = a[i + nByte64 - 1] >> (n & 0x3F); + ulong carry = a[i + nByte64] << (64 - (n & 0x3F)); + res[i] = a[i] ^ r ^ carry; + } + res[nByte64 - 1] &= Utils.BitMask((ulong)n, 64); + } + + static void Swap(int[] table, int firstIndex, int secondIndex) + { + int tmp = table[firstIndex]; + table[firstIndex] = table[secondIndex]; + table[secondIndex] = tmp; + } + + static void FastConvolutionMult(ulong[] res, int[] a, ulong[] b, int weight, int nByte64, int we, + HqcKeccakRandomGenerator random) + { + int[] permutedTable = new int[TABLE]; + for (int i = 0; i < 16; i++) + { + permutedTable[i] = i; + } + + byte[] permutationTableByte = new byte[TABLE*2]; + random.ExpandSeed(permutationTableByte, TABLE << 1); + + int[] permutationTable = new int[TABLE]; + Utils.FromByteArrayToByte16Array(permutationTable, permutationTableByte); + + for (int i = 0; i < TABLE - 1; i++) + { + Swap(permutedTable, i, i + permutationTable[i] % (TABLE - i)); + } + + ulong[] table = new ulong[TABLE * (nByte64 + 1)]; + int idx = permutedTable[0] * (nByte64 + 1); + Array.Copy(b, 0, table, idx, nByte64); + table[idx + nByte64] = 0UL; + + for (int i = 1; i < TABLE; i++) + { + idx = permutedTable[i] * (nByte64 + 1); + table[idx + nByte64] = Nat.ShiftUpBits64(nByte64, b, 0, i, 0UL, table, idx); + } + + int[] permutedSparseVect = new int[we]; + for (int i = 0; i < weight; i++) + { + permutedSparseVect[i] = i; + } + + byte[] permutationSparseVectBytes = new byte[we * 2]; + random.ExpandSeed(permutationSparseVectBytes, weight << 1); + + int[] permutationSparseVect = new int[we]; + Utils.FromByteArrayToByte16Array(permutationSparseVect, permutationSparseVectBytes); + + for (int i = 0; i < (weight - 1); i++) + { + Swap(permutedSparseVect, i, i + permutationSparseVect[i] % (weight - i)); + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Span<byte> resBytes = MemoryMarshal.AsBytes(res.AsSpan()); + for (int i = 0; i < weight; i++) + { + int dec = a[permutedSparseVect[i]] & 0xf; + int s = a[permutedSparseVect[i]] >> 4; + + idx = permutedTable[dec] * (nByte64 + 1); + + int count = s * 2 + nByte64 * 8; + for (int j = nByte64; j >= 0; --j) + { + ulong tmp = BinaryPrimitives.ReadUInt64LittleEndian(resBytes[count..]); + BinaryPrimitives.WriteUInt64LittleEndian(resBytes[count..], tmp ^ table[idx + j]); + count -= 8; + } + } +#else + ushort[] resByte16 = new ushort[res.Length * 4]; + for (int i = 0; i < weight; i++) + { + int dec = a[permutedSparseVect[i]] & 0xf; + int s = a[permutedSparseVect[i]] >> 4; + + idx = permutedTable[dec] * (nByte64 + 1); + + int count = s; + for (int j = 0; j <= nByte64; j++) + { + Utils.XorULongToByte16Array(resByte16, count, table[idx + j]); + count += 4; + } + } + Utils.FromByte16ArrayToULongArray(res, resByte16); +#endif + } + + internal static void ModMult(ulong[] res, int[] a, ulong[] b, int weight,int n, int nByte64, int we, + HqcKeccakRandomGenerator random) + { + ulong[] tmp = new ulong[(nByte64 << 1) + 1]; + FastConvolutionMult(tmp, a, b, weight, nByte64, we, random); + Mod(res, tmp, n, nByte64); + } + + internal static void AddULongs(ulong[] res, ulong[] a, ulong[] b) + { + for (int i = 0; i < a.Length; i++) + { + res[i] = a[i] ^ b[i]; + } + } + } +} diff --git a/crypto/src/pqc/crypto/hqc/GFCalculator.cs b/crypto/src/pqc/crypto/hqc/GFCalculator.cs new file mode 100644 index 000000000..d63e70513 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/GFCalculator.cs @@ -0,0 +1,29 @@ +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + internal class GFCalculator + { + static int[] exp = new int[] { 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1, 2, 4 }; + static int[] log = new int[] { 0, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175 }; + + internal static int mult(int a, int b) + { + int mask; + mask = Utils.ToUnsigned16Bits(-a >> 31); // a != 0 + mask &= Utils.ToUnsigned16Bits(-b >> 31); // b != 0 + return Utils.ToUnsigned16Bits(mask & exp[mod(log[a] + log[b])]); + } + + internal static int mod(int a) + { + int tmp = Utils.ToUnsigned16Bits(a - HqcParameters.GF_MUL_ORDER); + int mask = Utils.ToUnsigned8bits(-(tmp >> 15)); + return Utils.ToUnsigned16Bits(tmp + (mask & HqcParameters.GF_MUL_ORDER)); + } + + internal static int inverse(int a) + { + int mask = Utils.ToUnsigned16Bits(-a >> 31); + return mask & exp[HqcParameters.GF_MUL_ORDER - log[a]]; + } + } +} diff --git a/crypto/src/pqc/crypto/hqc/HqcEngine.cs b/crypto/src/pqc/crypto/hqc/HqcEngine.cs new file mode 100644 index 000000000..ac1a96f00 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/HqcEngine.cs @@ -0,0 +1,436 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + internal class HqcEngine + { + private int n; + private int n1; + private int n2; + private int k; + private int delta; + private int w; + private int wr; + private int we; + private int g; + private int rejectionThreshold; + private int fft; + private int mulParam; + + private int SEED_SIZE = 40; + private byte G_FCT_DOMAIN = 3; + private byte H_FCT_DOMAIN = 4; + private byte K_FCT_DOMAIN = 5; + + private int N_BYTE; + private int n1n2; + private int N_BYTE_64; + private int K_BYTE; + private int K_BYTE_64; + private int N1_BYTE_64; + private int N1N2_BYTE_64; + private int N1N2_BYTE; + private int N1_BYTE; + + private int[] generatorPoly; + private int SHA512_BYTES = 512 / 8; + + public HqcEngine(int n, int n1, int n2, int k, int g, int delta, int w, int wr, int we, int rejectionThreshold, int fft, int[] generatorPoly) + { + this.n = n; + this.k = k; + this.delta = delta; + this.w = w; + this.wr = wr; + this.we = we; + this.n1 = n1; + this.n2 = n2; + this.n1n2 = n1 * n2; + this.generatorPoly = generatorPoly; + this.g = g; + this.rejectionThreshold = rejectionThreshold; + this.fft = fft; + + this.mulParam = (n2 + 127) / 128; + this.N_BYTE = Utils.GetByteSizeFromBitSize(n); + this.K_BYTE = k; + this.N_BYTE_64 = Utils.GetByte64SizeFromBitSize(n); + this.K_BYTE_64 = Utils.GetByteSizeFromBitSize(k); + this.N1_BYTE_64 = Utils.GetByteSizeFromBitSize(n1); + this.N1N2_BYTE_64 = Utils.GetByte64SizeFromBitSize(n1 * n2); + this.N1N2_BYTE = Utils.GetByteSizeFromBitSize(n1 * n2); + this.N1_BYTE = Utils.GetByteSizeFromBitSize(n1); + } + + /** + * Generate key pairs + * - Secret key : (x,y) + * - Public key: (h,s) + * @param pk output pk = (publicSeed||s) + * + **/ + public void GenKeyPair(byte[] pk, byte[] sk, byte[] seed) + { + // Randomly generate seeds for secret keys and public keys + byte[] secretKeySeed = new byte[SEED_SIZE]; + + HqcKeccakRandomGenerator randomGenerator = new HqcKeccakRandomGenerator(256); + randomGenerator.RandomGeneratorInit(seed, null, seed.Length, 0); + randomGenerator.Squeeze(secretKeySeed, 40); + + // 1. Randomly generate secret keys x, y + HqcKeccakRandomGenerator secretKeySeedExpander = new HqcKeccakRandomGenerator(256); + secretKeySeedExpander.SeedExpanderInit(secretKeySeed, secretKeySeed.Length); + + ulong[] xLongBytes = new ulong[N_BYTE_64]; + int[] yPos = new int[this.w]; + + GenerateSecretKey(xLongBytes, secretKeySeedExpander, w); + GenerateSecretKeyByCoordinates(yPos, secretKeySeedExpander, w); + + // 2. Randomly generate h + byte[] publicKeySeed = new byte[SEED_SIZE]; + randomGenerator.Squeeze(publicKeySeed, 40); + + HqcKeccakRandomGenerator randomPublic = new HqcKeccakRandomGenerator(256); + randomPublic.SeedExpanderInit(publicKeySeed, publicKeySeed.Length); + + ulong[] hLongBytes = new ulong[N_BYTE_64]; + GeneratePublicKeyH(hLongBytes, randomPublic); + + // 3. Compute s + ulong[] s = new ulong[N_BYTE_64]; + GF2PolynomialCalculator.ModMult(s, yPos, hLongBytes, w, n, N_BYTE_64, we, secretKeySeedExpander); + GF2PolynomialCalculator.AddULongs(s, s, xLongBytes); + byte[] sBytes = new byte[N_BYTE]; + Utils.FromULongArrayToByteArray(sBytes, s); + + byte[] tmpPk = Arrays.Concatenate(publicKeySeed, sBytes); + byte[] tmpSk = Arrays.Concatenate(secretKeySeed, tmpPk); + + Array.Copy(tmpPk, 0, pk, 0, tmpPk.Length); + Array.Copy(tmpSk, 0, sk, 0, tmpSk.Length); + } + + /** + * HQC Encapsulation + * - Input: pk, seed + * - Output: c = (u,v,d), K + * + * @param u u + * @param v v + * @param d d + * @param K session key + * @param pk public key + * @param seed seed + **/ + public void Encaps(byte[] u, byte[] v, byte[] K, byte[] d, byte[] pk, byte[] seed) + { + // 1. Randomly generate m + byte[] m = new byte[K_BYTE]; + + // TODO: no way to gen m without seed and gen skseed, pkseed. In reference implementation they use the same + byte[] secretKeySeed = new byte[SEED_SIZE]; + HqcKeccakRandomGenerator randomGenerator = new HqcKeccakRandomGenerator(256); + randomGenerator.RandomGeneratorInit(seed, null, seed.Length, 0); + randomGenerator.Squeeze(secretKeySeed, 40); + + byte[] publicKeySeed = new byte[SEED_SIZE]; + randomGenerator.Squeeze(publicKeySeed, 40); + + // gen m + randomGenerator.Squeeze(m, K_BYTE); + + // 2. Generate theta + byte[] theta = new byte[SHA512_BYTES]; + HqcKeccakRandomGenerator shakeDigest = new HqcKeccakRandomGenerator(256); + shakeDigest.SHAKE256_512_ds(theta, m, m.Length, new byte[] { G_FCT_DOMAIN }); + + // 3. Generate ciphertext c = (u,v) + // Extract public keys + ulong[] h = new ulong[N_BYTE_64]; + byte[] s = new byte[N_BYTE]; + ExtractPublicKeys(h, s, pk); + + ulong[] vTmp = new ulong[N1N2_BYTE_64]; + Encrypt(u, vTmp, h, s, m, theta); + Utils.FromULongArrayToByteArray(v, vTmp); + + // 4. Compute d + shakeDigest.SHAKE256_512_ds(d, m, m.Length, new byte[] { H_FCT_DOMAIN }); + + // 5. Compute session key K + byte[] hashInputK = new byte[K_BYTE + N_BYTE + N1N2_BYTE]; + hashInputK = Arrays.Concatenate(m, u); + hashInputK = Arrays.Concatenate(hashInputK, v); + shakeDigest.SHAKE256_512_ds(K, hashInputK, hashInputK.Length, new byte[] { K_FCT_DOMAIN }); + } + + /** + * HQC Decapsulation + * - Input: ct, sk + * - Output: ss + * + * @param ss session key + * @param ct ciphertext + * @param sk secret key + **/ + public void Decaps(byte[] ss, byte[] ct, byte[] sk) + { + //Extract Y and Public Keys from sk + int[] yPos = new int[this.w]; + byte[] pk = new byte[40 + N_BYTE]; + ExtractKeysFromSecretKeys(yPos, pk, sk); + + // Extract u, v, d from ciphertext + byte[] u = new byte[N_BYTE]; + byte[] v = new byte[N1N2_BYTE]; + byte[] d = new byte[SHA512_BYTES]; + HqcEngine.ExtractCiphertexts(u, v, d, ct); + + // 1. Decrypt -> m' + byte[] mPrimeBytes = new byte[k]; + Decrypt(mPrimeBytes, mPrimeBytes, u, v, yPos); + + // 2. Compute theta' + byte[] theta = new byte[SHA512_BYTES]; + HqcKeccakRandomGenerator shakeDigest = new HqcKeccakRandomGenerator(256); + shakeDigest.SHAKE256_512_ds(theta, mPrimeBytes, mPrimeBytes.Length, new byte[] { G_FCT_DOMAIN }); + + // 3. Compute c' = Enc(pk, m', theta') + // Extract public keys + ulong[] h = new ulong[N_BYTE_64]; + byte[] s = new byte[N_BYTE]; + ExtractPublicKeys(h, s, pk); + + byte[] u2Bytes = new byte[N_BYTE]; + byte[] v2Bytes = new byte[N1N2_BYTE]; + ulong[] vTmp = new ulong[N1N2_BYTE_64]; + Encrypt(u2Bytes, vTmp, h, s, mPrimeBytes, theta); + Utils.FromULongArrayToByteArray(v2Bytes, vTmp); + + // 4. Compute d' = H(m') + byte[] dPrime = new byte[SHA512_BYTES]; + shakeDigest.SHAKE256_512_ds(dPrime, mPrimeBytes, mPrimeBytes.Length, new byte[] { H_FCT_DOMAIN }); + + // 5. Compute session key KPrime + byte[] hashInputK = new byte[K_BYTE + N_BYTE + N1N2_BYTE]; + hashInputK = Arrays.Concatenate(mPrimeBytes, u); + hashInputK = Arrays.Concatenate(hashInputK, v); + shakeDigest.SHAKE256_512_ds(ss, hashInputK, hashInputK.Length, new byte[] { K_FCT_DOMAIN }); + + int result = 1; + // Compare u, v, d + if (!Arrays.AreEqual(u, u2Bytes)) + { + result = 0; + } + + if (!Arrays.AreEqual(v, v2Bytes)) + { + result = 0; + } + + if (!Arrays.AreEqual(d, dPrime)) + { + result = 0; + } + + if (result == 0) + { //abort + for (int i = 0; i < GetSessionKeySize(); i++) + { + ss[i] = 0; + } + } + } + + internal int GetSessionKeySize() + { + return SHA512_BYTES; + } + + /** + * HQC Encryption + * - Input: (h,s, m) + * - Output: (u,v) = c + * + * @param h public key + * @param s public key + * @param m message + * @param u ciphertext + * @param v ciphertext + **/ + private void Encrypt(byte[] u, ulong[] v, ulong[] h, byte[] s, byte[] m, byte[] theta) + { + // Randomly generate e, r1, r2 + HqcKeccakRandomGenerator randomGenerator = new HqcKeccakRandomGenerator(256); + randomGenerator.SeedExpanderInit(theta, SEED_SIZE); + ulong[] e = new ulong[N_BYTE_64]; + ulong[] r1 = new ulong[N_BYTE_64]; + int[] r2 = new int[wr]; + GenerateSecretKey(r1, randomGenerator, wr); + GenerateSecretKeyByCoordinates(r2, randomGenerator, wr); + GenerateSecretKey(e, randomGenerator, we); + + // Calculate u + ulong[] uLong = new ulong[N_BYTE_64]; + GF2PolynomialCalculator.ModMult(uLong, r2, h, wr, n, N_BYTE_64, we, randomGenerator); + GF2PolynomialCalculator.AddULongs(uLong, uLong, r1); + Utils.FromULongArrayToByteArray(u, uLong); + + // Calculate v + // encode m + byte[] res = new byte[n1]; + ulong[] vLong = new ulong[N1N2_BYTE_64]; + ulong[] tmpVLong = new ulong[N_BYTE_64]; + ReedSolomon.Encode(res, m, K_BYTE * 8, n1, k, g, generatorPoly); + ReedMuller.Encode(vLong, res, n1, mulParam); + Array.Copy(vLong, 0, tmpVLong, 0, vLong.Length); + + //Compute v + ulong[] sLong = new ulong[N_BYTE_64]; + Utils.FromByteArrayToULongArray(sLong, s); + + ulong[] tmpLong = new ulong[N_BYTE_64]; + GF2PolynomialCalculator.ModMult(tmpLong, r2, sLong, wr, n, N_BYTE_64, we, randomGenerator); + GF2PolynomialCalculator.AddULongs(tmpLong, tmpLong, tmpVLong); + GF2PolynomialCalculator.AddULongs(tmpLong, tmpLong, e); + + Utils.ResizeArray(v, n1n2, tmpLong, n, N1N2_BYTE_64, N1N2_BYTE_64); + } + + private void Decrypt(byte[] output, byte[] m, byte[] u, byte[] v, int[] y) + { + byte[] tmpSeed = new byte[SEED_SIZE]; + HqcKeccakRandomGenerator randomGenerator = new HqcKeccakRandomGenerator(256); + randomGenerator.SeedExpanderInit(tmpSeed, SEED_SIZE); + + ulong[] uLongs = new ulong[N_BYTE_64]; + Utils.FromByteArrayToULongArray(uLongs, u); + + ulong[] vLongs = new ulong[N1N2_BYTE_64]; + Utils.FromByteArrayToULongArray(vLongs, v); + + ulong[] tmpV = new ulong[N_BYTE_64]; + Array.Copy(vLongs, 0, tmpV, 0, vLongs.Length); + + ulong[] tmpLong = new ulong[N_BYTE_64]; + GF2PolynomialCalculator.ModMult(tmpLong, y, uLongs, w, n, N_BYTE_64, we, randomGenerator); + GF2PolynomialCalculator.AddULongs(tmpLong, tmpLong, tmpV); + + // Decode res + byte[] tmp = new byte[n1]; + ReedMuller.Decode(tmp, tmpLong, n1, mulParam); + ReedSolomon.Decode(m, tmp, n1, fft, delta, k, g); + + Array.Copy(m, 0, output, 0, output.Length); + } + + private void GenerateSecretKey(ulong[] output, HqcKeccakRandomGenerator random, int w) + { + int[] tmp = new int[w]; + GenerateSecretKeyByCoordinates(tmp, random, w); + + for (int i = 0; i < w; ++i) + { + int index = tmp[i] / 64; + int pos = tmp[i] % 64; + ulong t = 1UL << pos; + output[index] |= t; + } + } + + private void GenerateSecretKeyByCoordinates(int[] output, HqcKeccakRandomGenerator random, int w) + { + int randomByteSize = 3 * w; + byte[] randomBytes = new byte[3 * this.wr]; + int inc; + + int i = 0; + int j = randomByteSize; + while (i < w) + { + do + { + if (j == randomByteSize) + { + random.ExpandSeed(randomBytes, randomByteSize); + + j = 0; + } + + output[i] = (randomBytes[j++] & 0xff) << 16; + output[i] |= (randomBytes[j++] & 0xff) << 8; + output[i] |= (randomBytes[j++] & 0xff); + + } + while (output[i] >= this.rejectionThreshold); + + output[i] = output[i] % this.n; + inc = 1; + for (int k = 0; k < i; k++) + { + if (output[k] == output[i]) + { + inc = 0; + } + } + i += inc; + } + } + + void GeneratePublicKeyH(ulong[] output, HqcKeccakRandomGenerator random) + { + byte[] randBytes = new byte[N_BYTE]; + random.ExpandSeed(randBytes, N_BYTE); + ulong[] tmp = new ulong[N_BYTE_64]; + Utils.FromByteArrayToULongArray(tmp, randBytes); + tmp[N_BYTE_64 - 1] &= Utils.BitMask((ulong)n, 64); + Array.Copy(tmp, 0, output, 0, output.Length); + } + + private void ExtractPublicKeys(ulong[] h, byte[] s, byte[] pk) + { + byte[] publicKeySeed = new byte[SEED_SIZE]; + Array.Copy(pk, 0, publicKeySeed, 0, publicKeySeed.Length); + + HqcKeccakRandomGenerator randomPublic = new HqcKeccakRandomGenerator(256); + randomPublic.SeedExpanderInit(publicKeySeed, publicKeySeed.Length); + + ulong[] hLongBytes = new ulong[N_BYTE_64]; + GeneratePublicKeyH(hLongBytes, randomPublic); + + Array.Copy(hLongBytes, 0, h, 0, h.Length); + Array.Copy(pk, 40, s, 0, s.Length); + } + + private void ExtractKeysFromSecretKeys(int[] y, byte[] pk, byte[] sk) + { + byte[] secretKeySeed = new byte[SEED_SIZE]; + Array.Copy(sk, 0, secretKeySeed, 0, secretKeySeed.Length); + + // Randomly generate secret keys x, y + HqcKeccakRandomGenerator secretKeySeedExpander = new HqcKeccakRandomGenerator(256); + secretKeySeedExpander.SeedExpanderInit(secretKeySeed, secretKeySeed.Length); + + ulong[] xLongBytes = new ulong[N_BYTE_64]; + int[] yPos = new int[this.w]; + + GenerateSecretKey(xLongBytes, secretKeySeedExpander, w); + GenerateSecretKeyByCoordinates(yPos, secretKeySeedExpander, w); + + Array.Copy(yPos, 0, y, 0, yPos.Length); + Array.Copy(sk, SEED_SIZE, pk, 0, pk.Length); + } + + private static void ExtractCiphertexts(byte[] u, byte[] v, byte[] d, byte[] ct) + { + Array.Copy(ct, 0, u, 0, u.Length); + Array.Copy(ct, u.Length, v, 0, v.Length); + Array.Copy(ct, u.Length + v.Length, d, 0, d.Length); + } + } +} diff --git a/crypto/src/pqc/crypto/hqc/HqcKeccakRandomGenerator.cs b/crypto/src/pqc/crypto/hqc/HqcKeccakRandomGenerator.cs new file mode 100644 index 000000000..090f5a9c0 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/HqcKeccakRandomGenerator.cs @@ -0,0 +1,321 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + internal class HqcKeccakRandomGenerator + { + private static readonly ulong[] KeccakRoundConstants = + { + 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808aL, 0x8000000080008000L, + 0x000000000000808bL, 0x0000000080000001L, 0x8000000080008081L, 0x8000000000008009L, + 0x000000000000008aL, 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000aL, + 0x000000008000808bL, 0x800000000000008bL, 0x8000000000008089L, 0x8000000000008003L, + 0x8000000000008002L, 0x8000000000000080L, 0x000000000000800aL, 0x800000008000000aL, + 0x8000000080008081L, 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L + }; + + protected long[] state = new long[26]; + protected byte[] dataQueue = new byte[192]; + protected int rate; + protected int bitsInQueue; + protected int fixedOutputLength; + protected bool squeezing; + + public HqcKeccakRandomGenerator() + { + Init(288); + } + + public HqcKeccakRandomGenerator(int bitLength) + { + Init(bitLength); + } + + private void Init(int bitLength) + { + switch (bitLength) + { + case 128: + case 224: + case 256: + case 288: + case 384: + case 512: + InitSponge(1600 - (bitLength << 1)); + break; + default: + throw new ArgumentException("bitLength must be one of 128, 224, 256, 288, 384, or 512."); + } + } + + private void InitSponge(int rate) + { + if ((rate <= 0) || (rate >= 1600) || ((rate % 64) != 0)) + throw new InvalidOperationException("invalid rate value"); + + this.rate = rate; + for (int i = 0; i < state.Length; ++i) + { + state[i] = 0L; + } + Arrays.Fill(this.dataQueue, 0); + this.bitsInQueue = 0; + this.squeezing = false; + this.fixedOutputLength = (1600 - rate) / 2; + } + + private void KeccakPermutation() + { + long[] A = state; + + long a00 = A[ 0], a01 = A[ 1], a02 = A[ 2], a03 = A[ 3], a04 = A[ 4]; + long a05 = A[ 5], a06 = A[ 6], a07 = A[ 7], a08 = A[ 8], a09 = A[ 9]; + long a10 = A[10], a11 = A[11], a12 = A[12], a13 = A[13], a14 = A[14]; + long a15 = A[15], a16 = A[16], a17 = A[17], a18 = A[18], a19 = A[19]; + long a20 = A[20], a21 = A[21], a22 = A[22], a23 = A[23], a24 = A[24]; + + for (int i = 0; i < 24; i++) + { + // theta + long c0 = a00 ^ a05 ^ a10 ^ a15 ^ a20; + long c1 = a01 ^ a06 ^ a11 ^ a16 ^ a21; + long c2 = a02 ^ a07 ^ a12 ^ a17 ^ a22; + long c3 = a03 ^ a08 ^ a13 ^ a18 ^ a23; + long c4 = a04 ^ a09 ^ a14 ^ a19 ^ a24; + + long d1 = Longs.RotateLeft(c1, 1) ^ c4; + long d2 = Longs.RotateLeft(c2, 1) ^ c0; + long d3 = Longs.RotateLeft(c3, 1) ^ c1; + long d4 = Longs.RotateLeft(c4, 1) ^ c2; + long d0 = Longs.RotateLeft(c0, 1) ^ c3; + + a00 ^= d1; a05 ^= d1; a10 ^= d1; a15 ^= d1; a20 ^= d1; + a01 ^= d2; a06 ^= d2; a11 ^= d2; a16 ^= d2; a21 ^= d2; + a02 ^= d3; a07 ^= d3; a12 ^= d3; a17 ^= d3; a22 ^= d3; + a03 ^= d4; a08 ^= d4; a13 ^= d4; a18 ^= d4; a23 ^= d4; + a04 ^= d0; a09 ^= d0; a14 ^= d0; a19 ^= d0; a24 ^= d0; + + // rho/pi + c1 = Longs.RotateLeft(a01, 1); + a01 = Longs.RotateLeft(a06, 44); + a06 = Longs.RotateLeft(a09, 20); + a09 = Longs.RotateLeft(a22, 61); + a22 = Longs.RotateLeft(a14, 39); + a14 = Longs.RotateLeft(a20, 18); + a20 = Longs.RotateLeft(a02, 62); + a02 = Longs.RotateLeft(a12, 43); + a12 = Longs.RotateLeft(a13, 25); + a13 = Longs.RotateLeft(a19, 8); + a19 = Longs.RotateLeft(a23, 56); + a23 = Longs.RotateLeft(a15, 41); + a15 = Longs.RotateLeft(a04, 27); + a04 = Longs.RotateLeft(a24, 14); + a24 = Longs.RotateLeft(a21, 2); + a21 = Longs.RotateLeft(a08, 55); + a08 = Longs.RotateLeft(a16, 45); + a16 = Longs.RotateLeft(a05, 36); + a05 = Longs.RotateLeft(a03, 28); + a03 = Longs.RotateLeft(a18, 21); + a18 = Longs.RotateLeft(a17, 15); + a17 = Longs.RotateLeft(a11, 10); + a11 = Longs.RotateLeft(a07, 6); + a07 = Longs.RotateLeft(a10, 3); + a10 = c1; + + // chi + c0 = a00 ^ (~a01 & a02); + c1 = a01 ^ (~a02 & a03); + a02 ^= ~a03 & a04; + a03 ^= ~a04 & a00; + a04 ^= ~a00 & a01; + a00 = c0; + a01 = c1; + + c0 = a05 ^ (~a06 & a07); + c1 = a06 ^ (~a07 & a08); + a07 ^= ~a08 & a09; + a08 ^= ~a09 & a05; + a09 ^= ~a05 & a06; + a05 = c0; + a06 = c1; + + c0 = a10 ^ (~a11 & a12); + c1 = a11 ^ (~a12 & a13); + a12 ^= ~a13 & a14; + a13 ^= ~a14 & a10; + a14 ^= ~a10 & a11; + a10 = c0; + a11 = c1; + + c0 = a15 ^ (~a16 & a17); + c1 = a16 ^ (~a17 & a18); + a17 ^= ~a18 & a19; + a18 ^= ~a19 & a15; + a19 ^= ~a15 & a16; + a15 = c0; + a16 = c1; + + c0 = a20 ^ (~a21 & a22); + c1 = a21 ^ (~a22 & a23); + a22 ^= ~a23 & a24; + a23 ^= ~a24 & a20; + a24 ^= ~a20 & a21; + a20 = c0; + a21 = c1; + + // iota + a00 ^= (long) KeccakRoundConstants[i]; + } + + A[0] = a00; + A[1] = a01; + A[2] = a02; + A[3] = a03; + A[4] = a04; + A[5] = a05; + A[6] = a06; + A[7] = a07; + A[8] = a08; + A[9] = a09; + A[10] = a10; + A[11] = a11; + A[12] = a12; + A[13] = a13; + A[14] = a14; + A[15] = a15; + A[16] = a16; + A[17] = a17; + A[18] = a18; + A[19] = a19; + A[20] = a20; + A[21] = a21; + A[22] = a22; + A[23] = a23; + A[24] = a24; + } + + private void KeccakIncAbsorb(byte[] input, int inputLen) + { + if (input == null) + { + return; + } + + int count = 0; + int rateBytes = rate >> 3; + while (inputLen + state[25] >= rateBytes) + { + for (int i = 0; i < rateBytes - state[25]; i++) + { + int tmp = (int)(state[25] + i) >> 3; + state[tmp] ^= (long) (((ulong) (input[i + count] & 0xff)) << (int) (8 * ((state[25] + i) & 0x07))); + } + inputLen -= (int) (rateBytes - state[25]); + count += (int) (rateBytes - state[25]); + state[25] = 0; + KeccakPermutation(); + } + + for (int i = 0; i < inputLen; i++) + { + int tmp = (int)(state[25] + i) >> 3; + state[tmp] ^= (long) (((ulong) (input[i + count] & 0xff)) << (int) (8 * ((state[25] + i) & 0x07))); + } + + state[25] += inputLen; + } + + private void KeccakIncFinalize(int p) + { + int rateBytes = rate >> 3; + + state[(int)state[25] >> 3] ^= (long) (((ulong) (p)) << (int) (8 * ((state[25]) & 0x07))); + state[(rateBytes - 1) >> 3] ^=((long) (128)) << (8 * ((rateBytes - 1) & 0x07)); + + + state[25] = 0; + } + + private void KeccakIncSqueeze(byte[] output, int outLen) + { + int rateBytes = rate >> 3; + int i; + for (i = 0; i < outLen && i < state[25]; i++) + { + output[i] = (byte)(state[(int)((rateBytes - state[25] + i) >> 3)] >> (int) (8 * ((rateBytes - state[25] + i) & 0x07))); + } + + int count = i; + outLen -= i; + state[25] -= i; + + while (outLen > 0) + { + KeccakPermutation(); + + for (i = 0; i < outLen && i < rateBytes; i++) + { + byte t = (byte)(state[i >> 3] >> (8 * (i & 0x07))); + output[count + i] = (byte)(state[i >> 3] >> (8 * (i & 0x07))); + } + count = count + i; + outLen -= i; + state[25] = rateBytes - i; + } + } + + public void Squeeze(byte[] output, int outLen) + { + KeccakIncSqueeze(output, outLen); + } + + public void RandomGeneratorInit(byte[] entropyInput, byte[] personalizationString, int entropyLen, int perLen) + { + byte[] domain = new byte[] { 1 }; + KeccakIncAbsorb(entropyInput, entropyLen); + KeccakIncAbsorb(personalizationString, perLen); + KeccakIncAbsorb(domain, domain.Length); + KeccakIncFinalize(0x1F); + } + + public void SeedExpanderInit(byte[] seed, int seedLen) + { + byte[] domain = new byte[] { 2 }; + KeccakIncAbsorb(seed, seedLen); + KeccakIncAbsorb(domain, 1); + KeccakIncFinalize(0x1F); + } + + public void ExpandSeed(byte[] output, int outLen) + { + int bSize = 8; + int r = outLen % bSize; + byte[] tmp = new byte[bSize]; + KeccakIncSqueeze(output, outLen - r); + + if (r != 0) + { + KeccakIncSqueeze(tmp, bSize); + int count = outLen - r; + for (int i = 0; i < r; i++) + { + output[count + i] = tmp[i]; + } + } + } + + public void SHAKE256_512_ds(byte[] output, byte[] input, int inLen, byte[] domain) + { + for (int i = 0; i < state.Length; i++) + { + state[i] = 0; + } + KeccakIncAbsorb(input, inLen); + KeccakIncAbsorb(domain, domain.Length); + KeccakIncFinalize(0x1F); + KeccakIncSqueeze(output, 512 / 8); + } + } +} diff --git a/crypto/src/pqc/crypto/hqc/HqcKemExtractor.cs b/crypto/src/pqc/crypto/hqc/HqcKemExtractor.cs new file mode 100644 index 000000000..32890f80b --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/HqcKemExtractor.cs @@ -0,0 +1,37 @@ +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + public class HqcKemExtractor : IEncapsulatedSecretExtractor + { + private HqcEngine engine; + + private HqcKeyParameters key; + + public HqcKemExtractor(HqcPrivateKeyParameters privParams) + { + this.key = privParams; + InitCipher(key.Parameters); + } + + private void InitCipher(HqcParameters param) + { + engine = param.Engine; + } + + + public byte[] ExtractSecret(byte[] encapsulation) + { + byte[] session_key = new byte[engine.GetSessionKeySize()]; + HqcPrivateKeyParameters secretKey = (HqcPrivateKeyParameters)key; + byte[] sk = secretKey.PrivateKey; + + engine.Decaps(session_key, encapsulation, sk); + + return session_key; + } + + public int EncapsulationLength => key.Parameters.NBytes + key.Parameters.N1n2Bytes + 64; + + } +} diff --git a/crypto/src/pqc/crypto/hqc/HqcKemGenerator.cs b/crypto/src/pqc/crypto/hqc/HqcKemGenerator.cs new file mode 100644 index 000000000..918dadd38 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/HqcKemGenerator.cs @@ -0,0 +1,89 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + public class HqcKemGenerator : IEncapsulatedSecretGenerator + { + private SecureRandom sr; + public HqcKemGenerator(SecureRandom random) + { + this.sr = random; + } + + public ISecretWithEncapsulation GenerateEncapsulated(AsymmetricKeyParameter recipientKey) + { + HqcPublicKeyParameters key = (HqcPublicKeyParameters)recipientKey; + HqcEngine engine = key.Parameters.Engine; + + byte[] K = new byte[key.Parameters.Sha512Bytes]; + byte[] u = new byte[key.Parameters.NBytes]; + byte[] v = new byte[key.Parameters.N1n2Bytes]; + byte[] d = new byte[key.Parameters.Sha512Bytes]; + byte[] pk = key.PublicKey; + byte[] seed = new byte[48]; + + sr.NextBytes(seed); + + engine.Encaps(u, v, K, d, pk, seed); + + byte[] cipherText = Arrays.Concatenate(u, v); + cipherText = Arrays.Concatenate(cipherText, d); + + return new HqcKemGenerator.SecretWithEncapsulationImpl(K, cipherText); + } + + private class SecretWithEncapsulationImpl : ISecretWithEncapsulation + { + private volatile bool hasBeenDestroyed = false; + + private byte[] sessionKey; + private byte[] cipher_text; + + public SecretWithEncapsulationImpl(byte[] sessionKey, byte[] cipher_text) + { + this.sessionKey = sessionKey; + this.cipher_text = cipher_text; + } + + public byte[] GetSecret() + { + CheckDestroyed(); + return Arrays.Clone(sessionKey); + } + + public byte[] GetEncapsulation() + { + CheckDestroyed(); + + return Arrays.Clone(cipher_text); + } + + public void Dispose() + { + if (!hasBeenDestroyed) + { + hasBeenDestroyed = true; + Arrays.Clear(sessionKey); + Arrays.Clear(cipher_text); + } + } + + public bool IsDestroyed() + { + return hasBeenDestroyed; + } + + void CheckDestroyed() + { + if (IsDestroyed()) + { + throw new Exception("data has been destroyed"); + } + } + } + } +} diff --git a/crypto/src/pqc/crypto/hqc/HqcKeyGenerationParameters.cs b/crypto/src/pqc/crypto/hqc/HqcKeyGenerationParameters.cs new file mode 100644 index 000000000..e548e1999 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/HqcKeyGenerationParameters.cs @@ -0,0 +1,19 @@ +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + public class HqcKeyGenerationParameters : KeyGenerationParameters + { + private HqcParameters param; + + public HqcKeyGenerationParameters( + SecureRandom random, + HqcParameters param) : base(random, 256) + { + this.param = param; + } + + public HqcParameters Parameters => param; + } +} diff --git a/crypto/src/pqc/crypto/hqc/HqcKeyPairGenerator.cs b/crypto/src/pqc/crypto/hqc/HqcKeyPairGenerator.cs new file mode 100644 index 000000000..243b0d850 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/HqcKeyPairGenerator.cs @@ -0,0 +1,69 @@ +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc + +{ + public class HqcKeyPairGenerator : IAsymmetricCipherKeyPairGenerator + { + private int n; + + private int k; + + private int delta; + + private int w; + + private int wr; + + private int we; + private int N_BYTE; + private HqcKeyGenerationParameters hqcKeyGenerationParameters; + + private SecureRandom random; + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + byte[] seed = new byte[48]; + random.NextBytes(seed); + return GenKeyPair(seed); + } + + public AsymmetricCipherKeyPair GenerateKeyPairWithSeed(byte[] seed) + { + return GenKeyPair(seed); + } + + public void Init(KeyGenerationParameters parameters) + { + this.hqcKeyGenerationParameters = (HqcKeyGenerationParameters)parameters; + this.random = parameters.Random; + + // get parameters + this.n = this.hqcKeyGenerationParameters.Parameters.N; + this.k = this.hqcKeyGenerationParameters.Parameters.K; + this.delta = this.hqcKeyGenerationParameters.Parameters.Delta; + this.w = this.hqcKeyGenerationParameters.Parameters.W; + this.wr = this.hqcKeyGenerationParameters.Parameters.Wr; + this.we = this.hqcKeyGenerationParameters.Parameters.We; + this.N_BYTE = (n + 7) / 8; + } + private AsymmetricCipherKeyPair GenKeyPair(byte[] seed) + { + HqcEngine engine = hqcKeyGenerationParameters.Parameters.Engine; + byte[] pk = new byte[40 + N_BYTE]; + byte[] sk = new byte[40 + 40 + N_BYTE]; + + engine.GenKeyPair(pk, sk, seed); + + // form keys + HqcPublicKeyParameters publicKey = new HqcPublicKeyParameters(hqcKeyGenerationParameters.Parameters, pk); + HqcPrivateKeyParameters privateKey = new HqcPrivateKeyParameters(hqcKeyGenerationParameters.Parameters, sk); + + return new AsymmetricCipherKeyPair(publicKey, privateKey); + } + + + + } +} diff --git a/crypto/src/pqc/crypto/hqc/HqcKeyParameters.cs b/crypto/src/pqc/crypto/hqc/HqcKeyParameters.cs new file mode 100644 index 000000000..8fc900a64 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/HqcKeyParameters.cs @@ -0,0 +1,19 @@ +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + public class HqcKeyParameters : AsymmetricKeyParameter + { + private HqcParameters param; + + public HqcKeyParameters( + bool isPrivate, + HqcParameters param) : base(isPrivate) + { + this.param = param; + } + + public HqcParameters Parameters => param; + + } +} diff --git a/crypto/src/pqc/crypto/hqc/HqcParameters.cs b/crypto/src/pqc/crypto/hqc/HqcParameters.cs new file mode 100644 index 000000000..da5948296 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/HqcParameters.cs @@ -0,0 +1,71 @@ +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc + +{ + public class HqcParameters : ICipherParameters + { + // 128 bits security + public static HqcParameters hqc128 = new HqcParameters("hqc128", 17669, 46, 384, 16, 31, 15, 66, 75, 75, 16767881, 4, new int[] { 89, 69, 153, 116, 176, 117, 111, 75, 73, 233, 242, 233, 65, 210, 21, 139, 103, 173, 67, 118, 105, 210, 174, 110, 74, 69, 228, 82, 255, 181, 1 }, 128); + + // 192 bits security + public static HqcParameters hqc192 = new HqcParameters("hqc192", 35851, 56, 640, 24, 33, 16, 100, 114, 114, 16742417, 5, new int[] { 45, 216, 239, 24, 253, 104, 27, 40, 107, 50, 163, 210, 227, 134, 224, 158, 119, 13, 158, 1, 238, 164, 82, 43, 15, 232, 246, 142, 50, 189, 29, 232, 1 }, 192); + + // 256 bits security + public static HqcParameters hqc256 = new HqcParameters("hqc256", 57637, 90, 640, 32, 59, 29, 131, 149, 149, 16772367, 5, new int[] { 49, 167, 49, 39, 200, 121, 124, 91, 240, 63, 148, 71, 150, 123, 87, 101, 32, 215, 159, 71, 201, 115, 97, 210, 186, 183, 141, 217, 123, 12, 31, 243, 180, 219, 152, 239, 99, 141, 4, 246, 191, 144, 8, 232, 47, 27, 141, 178, 130, 64, 124, 47, 39, 188, 216, 48, 199, 187, 1 }, 256); + + private string name; + private int n; + private int n1; + private int n2; + private int k; + private int g; + private int delta; + private int w; + private int wr; + private int we; + private int utilRejectionThreshold; + private int fft; + + private int[] generatorPoly; + private int defaultKeySize; + + internal const int PARAM_M = 8; + internal const int GF_MUL_ORDER = 255; + + private HqcEngine hqcEngine; + + private HqcParameters(string name, int n, int n1, int n2, int k, int g, int delta, int w, int wr, int we, int utilRejectionThreshold, int fft, int[] generatorPoly, int defaultKeySize) + { + this.name = name; + this.n = n; + this.n1 = n1; + this.n2 = n2; + this.k = k; + this.delta = delta; + this.w = w; + this.wr = wr; + this.we = we; + this.generatorPoly = generatorPoly; + this.g = g; + this.utilRejectionThreshold = utilRejectionThreshold; + this.fft = fft; + this.defaultKeySize = defaultKeySize; + hqcEngine = new HqcEngine(n, n1, n2, k, g, delta, w, wr, we, utilRejectionThreshold, fft, generatorPoly); + } + + public int N => n; + public int K => k; + public int Delta => delta; + public int W => w; + public int Wr => wr; + public int We => we; + public int N1 => n1; + public int N2 => n2; + public int Sha512Bytes => 512 / 8; + public int NBytes => (n + 7) / 8; + public int N1n2Bytes => (n1 * n2 + 7) / 8; + public int DefaultKeySize => defaultKeySize; + internal HqcEngine Engine => hqcEngine; + } +} diff --git a/crypto/src/pqc/crypto/hqc/HqcPrivateKeyParameters.cs b/crypto/src/pqc/crypto/hqc/HqcPrivateKeyParameters.cs new file mode 100644 index 000000000..96963e53c --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/HqcPrivateKeyParameters.cs @@ -0,0 +1,20 @@ +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + public class HqcPrivateKeyParameters : HqcKeyParameters + { + private byte[] sk; + + public HqcPrivateKeyParameters(HqcParameters param, byte[] sk) : base(true, param) + { + this.sk = Arrays.Clone(sk); + } + + public byte[] PrivateKey => Arrays.Clone(sk); + public byte[] GetEncoded() + { + return PrivateKey; + } + } +} diff --git a/crypto/src/pqc/crypto/hqc/HqcPublicKeyParameters.cs b/crypto/src/pqc/crypto/hqc/HqcPublicKeyParameters.cs new file mode 100644 index 000000000..a87d24704 --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/HqcPublicKeyParameters.cs @@ -0,0 +1,21 @@ +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + public class HqcPublicKeyParameters : HqcKeyParameters + { + private byte[] pk; + + public HqcPublicKeyParameters(HqcParameters param, byte[] pk) : base(false, param) + { + this.pk = Arrays.Clone(pk); + } + + public byte[] PublicKey => Arrays.Clone(pk); + + public byte[] GetEncoded() + { + return PublicKey; + } + } +} diff --git a/crypto/src/pqc/crypto/hqc/ReedMuller.cs b/crypto/src/pqc/crypto/hqc/ReedMuller.cs new file mode 100644 index 000000000..5f1f8e2bf --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/ReedMuller.cs @@ -0,0 +1,196 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + internal class ReedMuller + { + internal class Codeword + { + internal int[] type32; + internal int[] type8; + + public Codeword() + { + this.type32 = new int[4]; + this.type8 = new int[16]; + } + } + + static void EncodeSub(Codeword codeword, int m) + { + + int word1; + word1 = Bit0Mask(m >> 7); + + word1 ^= (int) (Bit0Mask(m >> 0) & 0xaaaaaaaa); + word1 ^= (int) (Bit0Mask(m >> 1) & 0xcccccccc); + word1 ^= (int) (Bit0Mask(m >> 2) & 0xf0f0f0f0); + word1 ^= (int) (Bit0Mask(m >> 3) & 0xff00ff00); + word1 ^= (int) (Bit0Mask(m >> 4) & 0xffff0000); + + codeword.type32[0] = word1; + + word1 ^= Bit0Mask(m >> 5); + codeword.type32[1] = word1; + + word1 ^= Bit0Mask(m >> 6); + codeword.type32[3] = word1; + + word1 ^= Bit0Mask(m >> 5); + codeword.type32[2] = word1; + } + + private static void HadamardTransform(int[] srcCode, int[] desCode) + { + int[] srcCodeCopy = Arrays.Clone(srcCode); + int[] desCodeCopy = Arrays.Clone(desCode); + + for (int i = 0; i < 7; i++) + { + for (int j = 0; j < 64; j++) + { + desCodeCopy[j] = srcCodeCopy[2 * j] + srcCodeCopy[2 * j + 1]; + desCodeCopy[j + 64] = srcCodeCopy[2 * j] - srcCodeCopy[2 * j + 1]; + } + + //swap srcCode and desCode + int[] tmp = srcCodeCopy; srcCodeCopy = desCodeCopy; desCodeCopy = tmp; + } + + // swap + Array.Copy(desCodeCopy, 0, srcCode, 0, srcCode.Length); + Array.Copy(srcCodeCopy, 0, desCode, 0, desCode.Length); + } + + + private static void ExpandThenSum(int[] desCode, Codeword[] srcCode, int off, int mulParam) + { + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 32; j++) + { + long ii = srcCode[0 + off].type32[i] >> j & 1; + desCode[i * 32 + j] = srcCode[0 + off].type32[i] >> j & 1; + } + } + + for (int i = 1; i < mulParam; i++) + { + for (int j = 0; j < 4; j++) + { + for (int k = 0; k < 32; k++) + { + desCode[j * 32 + k] += srcCode[i + off].type32[j] >> k & 1; + + } + } + } + + } + + private static int FindPeaks(int[] input) + { + int peakAbsVal = 0; + int peakVal = 0; + int peakPos = 0; + + for (int i = 0; i < 128; i++) + { + int t = input[i]; + int posMask = t > 0 ? -1 : 0; + int abs = (posMask & t) | (~posMask & -t); + + peakVal = abs > peakAbsVal ? t : peakVal; + peakPos = abs > peakAbsVal ? i : peakPos; + peakAbsVal = abs > peakAbsVal ? abs : peakAbsVal; + } + int tmp = peakVal > 0 ? 1 : 0; + peakPos |= 128 * tmp; + return peakPos; + } + + + private static int Bit0Mask(int b) + { + return (int) ((-(b & 1)) & 0xffffffff); + } + + public static void Encode(ulong[] codeword, byte[] m, int n1, int mulParam) + { + byte[] mBytes = Arrays.Clone(m); + + Codeword[] codewordCopy = new Codeword[n1 * mulParam]; + for (int i = 0; i < codewordCopy.Length; i++) + { + codewordCopy[i] = new Codeword(); + } + + for (int i = 0; i < n1; i++) + { + int pos = i * mulParam; + EncodeSub(codewordCopy[pos], mBytes[i]); + + for (int j = 1; j < mulParam; j++) + { + codewordCopy[pos + j] = codewordCopy[pos]; + } + } + + + int[] cwd64 = new int[codewordCopy.Length * 4]; + int off = 0; + for (int i = 0; i < codewordCopy.Length; i++) + { + Array.Copy(codewordCopy[i].type32, 0, cwd64, off, codewordCopy[i].type32.Length); + off += 4; + } + + Utils.FromByte32ArrayToULongArray(codeword, cwd64); + } + + public static void Decode(byte[] m, ulong[] codeword, int n1, int mulParam) + { + byte[] mBytes = Arrays.Clone(m); + + Codeword[] codewordCopy = new Codeword[codeword.Length / 2]; // because each codewordCopy has a 32 bit array size 4 + int[] byteCodeWords = new int[codeword.Length * 2]; + Utils.FromULongArrayToByte32Array(byteCodeWords, codeword); + + for (int i = 0; i < codewordCopy.Length; i++) + { + codewordCopy[i] = new Codeword(); + for (int j = 0; j < 4; j++) + { + codewordCopy[i].type32[j] = byteCodeWords[i * 4 + j]; + } + } + + int[] expandedCodeword = new int[128]; + + + for (int i = 0; i < n1; i++) + { + ExpandThenSum(expandedCodeword, codewordCopy, i * mulParam, mulParam); + + + int[] tmp = new int[128]; + HadamardTransform(expandedCodeword, tmp); + + tmp[0] -= 64 * mulParam; + mBytes[i] = (byte)FindPeaks(tmp); + } + + int[] cwd64 = new int[codewordCopy.Length * 4]; + int off = 0; + for (int i = 0; i < codewordCopy.Length; i++) + { + Array.Copy(codewordCopy[i].type32, 0, cwd64, off, codewordCopy[i].type32.Length); + off += 4; + } + Utils.FromByte32ArrayToULongArray(codeword, cwd64); + Array.Copy(mBytes, 0, m, 0, m.Length); + } + } +} diff --git a/crypto/src/pqc/crypto/hqc/ReedSolomon.cs b/crypto/src/pqc/crypto/hqc/ReedSolomon.cs new file mode 100644 index 000000000..8e7fc664d --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/ReedSolomon.cs @@ -0,0 +1,264 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + internal class ReedSolomon + { + static int[,] alpha128 = new int[30,45] { { 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193 }, { 4, 16, 64, 29, 116, 205, 19, 76, 45, 180, 234, 143, 6, 24, 96, 157, 78, 37, 148, 106, 181, 238, 159, 70, 5, 20, 80, 93, 105, 185, 222, 95, 97, 153, 94, 101, 137, 30, 120, 253, 211, 107, 177, 254, 223 }, { 8, 64, 58, 205, 38, 45, 117, 143, 12, 96, 39, 37, 53, 181, 193, 70, 10, 80, 186, 185, 161, 97, 47, 101, 15, 120, 231, 107, 127, 223, 182, 217, 134, 68, 26, 208, 206, 62, 237, 59, 197, 102, 23, 184, 169 }, { 16, 29, 205, 76, 180, 143, 24, 157, 37, 106, 238, 70, 20, 93, 185, 95, 153, 101, 30, 253, 107, 254, 91, 217, 17, 13, 208, 129, 248, 59, 151, 133, 184, 79, 132, 168, 82, 73, 228, 230, 198, 252, 123, 227, 150 }, { 32, 116, 38, 180, 3, 96, 156, 106, 193, 5, 160, 185, 190, 94, 15, 253, 214, 223, 226, 17, 26, 103, 124, 59, 51, 46, 169, 132, 77, 85, 114, 230, 145, 215, 255, 150, 55, 174, 100, 28, 167, 89, 239, 172, 36 }, { 64, 205, 45, 143, 96, 37, 181, 70, 80, 185, 97, 101, 120, 107, 223, 217, 68, 208, 62, 59, 102, 184, 33, 168, 85, 228, 191, 252, 241, 150, 110, 130, 7, 221, 89, 195, 138, 61, 251, 44, 207, 173, 8, 58, 38 }, { 128, 19, 117, 24, 156, 181, 140, 93, 161, 94, 60, 107, 163, 67, 26, 129, 147, 102, 109, 132, 41, 57, 209, 252, 255, 98, 87, 200, 224, 89, 155, 18, 245, 11, 233, 173, 16, 232, 45, 3, 157, 53, 159, 40, 185 }, { 29, 76, 143, 157, 106, 70, 93, 95, 101, 253, 254, 217, 13, 129, 59, 133, 79, 168, 73, 230, 252, 227, 149, 130, 28, 81, 195, 18, 247, 44, 27, 2, 58, 152, 3, 39, 212, 140, 186, 190, 202, 231, 225, 175, 26 }, { 58, 45, 12, 37, 193, 80, 161, 101, 231, 223, 134, 208, 237, 102, 169, 168, 146, 191, 179, 150, 87, 7, 166, 195, 36, 251, 125, 173, 64, 38, 143, 39, 181, 10, 185, 47, 120, 127, 217, 26, 62, 197, 184, 21, 85 }, { 116, 180, 96, 106, 5, 185, 94, 253, 223, 17, 103, 59, 46, 132, 85, 230, 215, 150, 174, 28, 89, 172, 244, 44, 108, 32, 38, 3, 156, 193, 160, 190, 15, 214, 226, 26, 124, 51, 169, 77, 114, 145, 255, 55, 100 }, { 232, 234, 39, 238, 160, 97, 60, 254, 134, 103, 118, 184, 84, 57, 145, 227, 220, 7, 162, 172, 245, 176, 71, 58, 180, 192, 181, 40, 95, 15, 177, 175, 208, 147, 46, 21, 73, 99, 241, 55, 200, 166, 43, 122, 44 }, { 205, 143, 37, 70, 185, 101, 107, 217, 208, 59, 184, 168, 228, 252, 150, 130, 221, 195, 61, 44, 173, 58, 117, 39, 193, 186, 47, 231, 182, 26, 237, 23, 21, 146, 145, 219, 87, 56, 242, 36, 139, 54, 64, 45, 96 }, { 135, 6, 53, 20, 190, 120, 163, 13, 237, 46, 84, 228, 229, 98, 100, 81, 69, 251, 131, 32, 45, 192, 238, 186, 94, 187, 217, 189, 236, 169, 82, 209, 241, 220, 28, 242, 72, 22, 173, 116, 201, 37, 140, 222, 15 }, { 19, 24, 181, 93, 94, 107, 67, 129, 102, 132, 57, 252, 98, 200, 89, 18, 11, 173, 232, 3, 53, 40, 194, 231, 226, 189, 197, 158, 170, 145, 75, 25, 166, 69, 235, 54, 29, 234, 37, 5, 95, 120, 91, 52, 59 }, { 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145, 150, 100, 89, 36, 44, 1, 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145, 150, 100, 89, 36, 44, 1, 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145 }, { 76, 157, 70, 95, 253, 217, 129, 133, 168, 230, 227, 130, 81, 18, 44, 2, 152, 39, 140, 190, 231, 175, 31, 23, 77, 209, 219, 25, 162, 36, 88, 4, 45, 78, 5, 97, 211, 67, 62, 46, 154, 191, 171, 50, 89 }, { 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1, 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1, 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1 }, { 45, 37, 80, 101, 223, 208, 102, 168, 191, 150, 7, 195, 251, 173, 38, 39, 10, 47, 127, 26, 197, 21, 115, 219, 100, 242, 245, 54, 205, 96, 70, 97, 107, 68, 59, 33, 228, 241, 130, 89, 61, 207, 58, 12, 193 }, { 90, 148, 186, 30, 226, 62, 109, 73, 179, 174, 162, 61, 131, 232, 96, 140, 153, 127, 52, 51, 168, 99, 98, 56, 172, 22, 8, 234, 212, 185, 240, 67, 237, 79, 114, 241, 25, 121, 245, 108, 19, 39, 20, 188, 223 }, { 180, 106, 185, 253, 17, 59, 132, 230, 150, 28, 172, 44, 32, 3, 193, 190, 214, 26, 51, 77, 145, 55, 167, 36, 233, 116, 96, 5, 94, 223, 103, 46, 85, 215, 174, 89, 244, 108, 38, 156, 160, 15, 226, 124, 169 }, { 117, 181, 161, 107, 26, 102, 41, 252, 87, 89, 245, 173, 45, 53, 185, 231, 68, 197, 168, 145, 110, 166, 61, 54, 38, 37, 186, 120, 134, 59, 21, 191, 196, 221, 36, 207, 205, 39, 80, 15, 217, 237, 33, 115, 150 }, { 234, 238, 97, 254, 103, 184, 57, 227, 7, 172, 176, 58, 192, 40, 15, 175, 147, 21, 99, 55, 166, 122, 216, 45, 106, 222, 107, 52, 133, 85, 123, 50, 195, 11, 32, 12, 140, 188, 182, 124, 158, 115, 49, 224, 36 }, { 201, 159, 47, 91, 124, 33, 209, 149, 166, 244, 71, 117, 238, 194, 223, 31, 79, 115, 98, 167, 61, 216, 90, 181, 190, 254, 206, 218, 213, 150, 224, 72, 54, 152, 106, 161, 177, 189, 184, 114, 171, 56, 18, 131, 38 }, { 143, 70, 101, 217, 59, 168, 252, 130, 195, 44, 58, 39, 186, 231, 26, 23, 146, 219, 56, 36, 54, 45, 181, 97, 223, 62, 33, 191, 110, 89, 251, 8, 12, 10, 15, 134, 197, 41, 179, 100, 86, 125, 205, 37, 185 }, { 3, 5, 15, 17, 51, 85, 255, 28, 36, 108, 180, 193, 94, 226, 59, 77, 215, 100, 172, 233, 38, 106, 190, 223, 124, 132, 145, 174, 239, 44, 116, 156, 185, 214, 103, 169, 230, 55, 89, 235, 32, 96, 160, 253, 26 }, { 6, 20, 120, 13, 46, 228, 98, 81, 251, 32, 192, 186, 187, 189, 169, 209, 220, 242, 22, 116, 37, 222, 254, 62, 132, 63, 130, 43, 250, 38, 212, 194, 182, 147, 77, 179, 141, 9, 54, 180, 159, 101, 67, 151, 85 }, { 12, 80, 231, 208, 169, 191, 87, 195, 125, 38, 181, 47, 217, 197, 85, 219, 221, 245, 8, 96, 186, 107, 206, 33, 145, 130, 86, 207, 45, 193, 101, 134, 102, 146, 150, 166, 251, 64, 39, 185, 127, 62, 21, 252, 100 }, { 24, 93, 107, 129, 132, 252, 200, 18, 173, 3, 40, 231, 189, 158, 145, 25, 69, 54, 234, 5, 120, 52, 218, 191, 174, 43, 207, 90, 35, 15, 136, 92, 115, 220, 239, 125, 76, 238, 101, 17, 133, 228, 149, 121, 44 }, { 48, 105, 127, 248, 77, 241, 224, 247, 64, 156, 95, 182, 236, 170, 150, 162, 11, 205, 212, 94, 134, 133, 213, 110, 239, 250, 45, 35, 30, 26, 218, 99, 130, 69, 108, 143, 40, 211, 206, 132, 229, 7, 144, 2, 96 }, { 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15, 26, 169, 145, 100, 36, 1, 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15, 26, 169, 145, 100, 36, 1, 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15 } }; + static int[,] alpha192 = new int[32,55] { { 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160 }, { 4, 16, 64, 29, 116, 205, 19, 76, 45, 180, 234, 143, 6, 24, 96, 157, 78, 37, 148, 106, 181, 238, 159, 70, 5, 20, 80, 93, 105, 185, 222, 95, 97, 153, 94, 101, 137, 30, 120, 253, 211, 107, 177, 254, 223, 91, 113, 217, 67, 17, 68, 13, 52, 208, 103 }, { 8, 64, 58, 205, 38, 45, 117, 143, 12, 96, 39, 37, 53, 181, 193, 70, 10, 80, 186, 185, 161, 97, 47, 101, 15, 120, 231, 107, 127, 223, 182, 217, 134, 68, 26, 208, 206, 62, 237, 59, 197, 102, 23, 184, 169, 33, 21, 168, 41, 85, 146, 228, 115, 191, 145 }, { 16, 29, 205, 76, 180, 143, 24, 157, 37, 106, 238, 70, 20, 93, 185, 95, 153, 101, 30, 253, 107, 254, 91, 217, 17, 13, 208, 129, 248, 59, 151, 133, 184, 79, 132, 168, 82, 73, 228, 230, 198, 252, 123, 227, 150, 149, 165, 130, 200, 28, 221, 81, 121, 195, 172 }, { 32, 116, 38, 180, 3, 96, 156, 106, 193, 5, 160, 185, 190, 94, 15, 253, 214, 223, 226, 17, 26, 103, 124, 59, 51, 46, 169, 132, 77, 85, 114, 230, 145, 215, 255, 150, 55, 174, 100, 28, 167, 89, 239, 172, 36, 244, 235, 44, 233, 108, 1, 32, 116, 38, 180 }, { 64, 205, 45, 143, 96, 37, 181, 70, 80, 185, 97, 101, 120, 107, 223, 217, 68, 208, 62, 59, 102, 184, 33, 168, 85, 228, 191, 252, 241, 150, 110, 130, 7, 221, 89, 195, 138, 61, 251, 44, 207, 173, 8, 58, 38, 117, 12, 39, 53, 193, 10, 186, 161, 47, 15 }, { 128, 19, 117, 24, 156, 181, 140, 93, 161, 94, 60, 107, 163, 67, 26, 129, 147, 102, 109, 132, 41, 57, 209, 252, 255, 98, 87, 200, 224, 89, 155, 18, 245, 11, 233, 173, 16, 232, 45, 3, 157, 53, 159, 40, 185, 194, 137, 231, 254, 226, 68, 189, 248, 197, 46 }, { 29, 76, 143, 157, 106, 70, 93, 95, 101, 253, 254, 217, 13, 129, 59, 133, 79, 168, 73, 230, 252, 227, 149, 130, 28, 81, 195, 18, 247, 44, 27, 2, 58, 152, 3, 39, 212, 140, 186, 190, 202, 231, 225, 175, 26, 31, 118, 23, 158, 77, 146, 209, 229, 219, 55 }, { 58, 45, 12, 37, 193, 80, 161, 101, 231, 223, 134, 208, 237, 102, 169, 168, 146, 191, 179, 150, 87, 7, 166, 195, 36, 251, 125, 173, 64, 38, 143, 39, 181, 10, 185, 47, 120, 127, 217, 26, 62, 197, 184, 21, 85, 115, 252, 219, 110, 100, 221, 242, 138, 245, 44 }, { 116, 180, 96, 106, 5, 185, 94, 253, 223, 17, 103, 59, 46, 132, 85, 230, 215, 150, 174, 28, 89, 172, 244, 44, 108, 32, 38, 3, 156, 193, 160, 190, 15, 214, 226, 26, 124, 51, 169, 77, 114, 145, 255, 55, 100, 167, 239, 36, 235, 233, 1, 116, 180, 96, 106 }, { 232, 234, 39, 238, 160, 97, 60, 254, 134, 103, 118, 184, 84, 57, 145, 227, 220, 7, 162, 172, 245, 176, 71, 58, 180, 192, 181, 40, 95, 15, 177, 175, 208, 147, 46, 21, 73, 99, 241, 55, 200, 166, 43, 122, 44, 216, 128, 45, 48, 106, 10, 222, 202, 107, 226 }, { 205, 143, 37, 70, 185, 101, 107, 217, 208, 59, 184, 168, 228, 252, 150, 130, 221, 195, 61, 44, 173, 58, 117, 39, 193, 186, 47, 231, 182, 26, 237, 23, 21, 146, 145, 219, 87, 56, 242, 36, 139, 54, 64, 45, 96, 181, 80, 97, 120, 223, 68, 62, 102, 33, 85 }, { 135, 6, 53, 20, 190, 120, 163, 13, 237, 46, 84, 228, 229, 98, 100, 81, 69, 251, 131, 32, 45, 192, 238, 186, 94, 187, 217, 189, 236, 169, 82, 209, 241, 220, 28, 242, 72, 22, 173, 116, 201, 37, 140, 222, 15, 254, 34, 62, 204, 132, 146, 63, 75, 130, 167 }, { 19, 24, 181, 93, 94, 107, 67, 129, 102, 132, 57, 252, 98, 200, 89, 18, 11, 173, 232, 3, 53, 40, 194, 231, 226, 189, 197, 158, 170, 145, 75, 25, 166, 69, 235, 54, 29, 234, 37, 5, 95, 120, 91, 52, 59, 218, 82, 191, 227, 174, 221, 43, 247, 207, 32 }, { 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145, 150, 100, 89, 36, 44, 1, 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145, 150, 100, 89, 36, 44, 1, 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145, 150, 100, 89, 36, 44, 1, 38, 96, 193, 185 }, { 76, 157, 70, 95, 253, 217, 129, 133, 168, 230, 227, 130, 81, 18, 44, 2, 152, 39, 140, 190, 231, 175, 31, 23, 77, 209, 219, 25, 162, 36, 88, 4, 45, 78, 5, 97, 211, 67, 62, 46, 154, 191, 171, 50, 89, 72, 176, 8, 90, 156, 10, 194, 187, 134, 124 }, { 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1, 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1, 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1, 152, 78, 10, 153, 214, 68, 147, 79, 146, 215 }, { 45, 37, 80, 101, 223, 208, 102, 168, 191, 150, 7, 195, 251, 173, 38, 39, 10, 47, 127, 26, 197, 21, 115, 219, 100, 242, 245, 54, 205, 96, 70, 97, 107, 68, 59, 33, 228, 241, 130, 89, 61, 207, 58, 12, 193, 161, 231, 134, 237, 169, 146, 179, 87, 166, 36 }, { 90, 148, 186, 30, 226, 62, 109, 73, 179, 174, 162, 61, 131, 232, 96, 140, 153, 127, 52, 51, 168, 99, 98, 56, 172, 22, 8, 234, 212, 185, 240, 67, 237, 79, 114, 241, 25, 121, 245, 108, 19, 39, 20, 188, 223, 189, 133, 41, 63, 55, 221, 9, 176, 64, 3 }, { 180, 106, 185, 253, 17, 59, 132, 230, 150, 28, 172, 44, 32, 3, 193, 190, 214, 26, 51, 77, 145, 55, 167, 36, 233, 116, 96, 5, 94, 223, 103, 46, 85, 215, 174, 89, 244, 108, 38, 156, 160, 15, 226, 124, 169, 114, 255, 100, 239, 235, 1, 180, 106, 185, 253 }, { 117, 181, 161, 107, 26, 102, 41, 252, 87, 89, 245, 173, 45, 53, 185, 231, 68, 197, 168, 145, 110, 166, 61, 54, 38, 37, 186, 120, 134, 59, 21, 191, 196, 221, 36, 207, 205, 39, 80, 15, 217, 237, 33, 115, 150, 56, 138, 125, 58, 96, 10, 101, 182, 62, 169 }, { 234, 238, 97, 254, 103, 184, 57, 227, 7, 172, 176, 58, 192, 40, 15, 175, 147, 21, 99, 55, 166, 122, 216, 45, 106, 222, 107, 52, 133, 85, 123, 50, 195, 11, 32, 12, 140, 188, 182, 124, 158, 115, 49, 224, 36, 131, 19, 37, 105, 253, 68, 151, 154, 252, 174 }, { 201, 159, 47, 91, 124, 33, 209, 149, 166, 244, 71, 117, 238, 194, 223, 31, 79, 115, 98, 167, 61, 216, 90, 181, 190, 254, 206, 218, 213, 150, 224, 72, 54, 152, 106, 161, 177, 189, 184, 114, 171, 56, 18, 131, 38, 148, 111, 107, 104, 46, 146, 227, 14, 138, 233 }, { 143, 70, 101, 217, 59, 168, 252, 130, 195, 44, 58, 39, 186, 231, 26, 23, 146, 219, 56, 36, 54, 45, 181, 97, 223, 62, 33, 191, 110, 89, 251, 8, 12, 10, 15, 134, 197, 41, 179, 100, 86, 125, 205, 37, 185, 107, 208, 184, 228, 150, 221, 61, 173, 117, 193 }, { 3, 5, 15, 17, 51, 85, 255, 28, 36, 108, 180, 193, 94, 226, 59, 77, 215, 100, 172, 233, 38, 106, 190, 223, 124, 132, 145, 174, 239, 44, 116, 156, 185, 214, 103, 169, 230, 55, 89, 235, 32, 96, 160, 253, 26, 46, 114, 150, 167, 244, 1, 3, 5, 15, 17 }, { 6, 20, 120, 13, 46, 228, 98, 81, 251, 32, 192, 186, 187, 189, 169, 209, 220, 242, 22, 116, 37, 222, 254, 62, 132, 63, 130, 43, 250, 38, 212, 194, 182, 147, 77, 179, 141, 9, 54, 180, 159, 101, 67, 151, 85, 227, 112, 61, 142, 3, 10, 60, 136, 23, 114 }, { 12, 80, 231, 208, 169, 191, 87, 195, 125, 38, 181, 47, 217, 197, 85, 219, 221, 245, 8, 96, 186, 107, 206, 33, 145, 130, 86, 207, 45, 193, 101, 134, 102, 146, 150, 166, 251, 64, 39, 185, 127, 62, 21, 252, 100, 138, 54, 117, 70, 15, 68, 23, 228, 196, 89 }, { 24, 93, 107, 129, 132, 252, 200, 18, 173, 3, 40, 231, 189, 158, 145, 25, 69, 54, 234, 5, 120, 52, 218, 191, 174, 43, 207, 90, 35, 15, 136, 92, 115, 220, 239, 125, 76, 238, 101, 17, 133, 228, 149, 121, 44, 135, 212, 47, 175, 51, 146, 49, 162, 139, 116 }, { 48, 105, 127, 248, 77, 241, 224, 247, 64, 156, 95, 182, 236, 170, 150, 162, 11, 205, 212, 94, 134, 133, 213, 110, 239, 250, 45, 35, 30, 26, 218, 99, 130, 69, 108, 143, 40, 211, 206, 132, 229, 7, 144, 2, 96, 210, 254, 237, 154, 255, 221, 243, 128, 37, 190 }, { 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15, 26, 169, 145, 100, 36, 1, 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15, 26, 169, 145, 100, 36, 1, 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15, 26, 169, 145, 100, 36, 1, 96, 185, 223, 59 }, { 192, 222, 182, 151, 114, 110, 155, 27, 143, 160, 177, 237, 82, 75, 89, 88, 152, 70, 240, 103, 21, 123, 224, 251, 116, 212, 101, 136, 218, 145, 200, 144, 8, 78, 190, 217, 204, 183, 87, 172, 216, 12, 105, 225, 59, 170, 98, 242, 250, 180, 10, 211, 31, 168, 255 }, { 157, 95, 217, 133, 230, 130, 18, 2, 39, 190, 175, 23, 209, 25, 36, 4, 78, 97, 67, 46, 191, 50, 72, 8, 156, 194, 134, 92, 99, 100, 144, 16, 37, 153, 17, 184, 198, 200, 61, 32, 74, 47, 34, 109, 145, 141, 122, 64, 148, 94, 68, 218, 63, 7, 244 } }; + static int[,] alpha256 = new int[58,89] { { 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225 }, { 4, 16, 64, 29, 116, 205, 19, 76, 45, 180, 234, 143, 6, 24, 96, 157, 78, 37, 148, 106, 181, 238, 159, 70, 5, 20, 80, 93, 105, 185, 222, 95, 97, 153, 94, 101, 137, 30, 120, 253, 211, 107, 177, 254, 223, 91, 113, 217, 67, 17, 68, 13, 52, 208, 103, 129, 62, 248, 199, 59, 236, 151, 102, 133, 46, 184, 218, 79, 33, 132, 42, 168, 154, 82, 85, 73, 57, 228, 183, 230, 191, 198, 63, 252, 215, 123, 241, 227, 171 }, { 8, 64, 58, 205, 38, 45, 117, 143, 12, 96, 39, 37, 53, 181, 193, 70, 10, 80, 186, 185, 161, 97, 47, 101, 15, 120, 231, 107, 127, 223, 182, 217, 134, 68, 26, 208, 206, 62, 237, 59, 197, 102, 23, 184, 169, 33, 21, 168, 41, 85, 146, 228, 115, 191, 145, 252, 179, 241, 219, 150, 196, 110, 87, 130, 100, 7, 56, 221, 166, 89, 242, 195, 86, 138, 36, 61, 245, 251, 139, 44, 125, 207, 54, 173, 1, 8, 64, 58, 205 }, { 16, 29, 205, 76, 180, 143, 24, 157, 37, 106, 238, 70, 20, 93, 185, 95, 153, 101, 30, 253, 107, 254, 91, 217, 17, 13, 208, 129, 248, 59, 151, 133, 184, 79, 132, 168, 82, 73, 228, 230, 198, 252, 123, 227, 150, 149, 165, 130, 200, 28, 221, 81, 121, 195, 172, 18, 61, 247, 203, 44, 250, 27, 173, 2, 32, 58, 135, 152, 117, 3, 48, 39, 74, 212, 193, 140, 40, 186, 111, 190, 47, 202, 60, 231, 214, 225, 182, 175, 34 }, { 32, 116, 38, 180, 3, 96, 156, 106, 193, 5, 160, 185, 190, 94, 15, 253, 214, 223, 226, 17, 26, 103, 124, 59, 51, 46, 169, 132, 77, 85, 114, 230, 145, 215, 255, 150, 55, 174, 100, 28, 167, 89, 239, 172, 36, 244, 235, 44, 233, 108, 1, 32, 116, 38, 180, 3, 96, 156, 106, 193, 5, 160, 185, 190, 94, 15, 253, 214, 223, 226, 17, 26, 103, 124, 59, 51, 46, 169, 132, 77, 85, 114, 230, 145, 215, 255, 150, 55, 174 }, { 64, 205, 45, 143, 96, 37, 181, 70, 80, 185, 97, 101, 120, 107, 223, 217, 68, 208, 62, 59, 102, 184, 33, 168, 85, 228, 191, 252, 241, 150, 110, 130, 7, 221, 89, 195, 138, 61, 251, 44, 207, 173, 8, 58, 38, 117, 12, 39, 53, 193, 10, 186, 161, 47, 15, 231, 127, 182, 134, 26, 206, 237, 197, 23, 169, 21, 41, 146, 115, 145, 179, 219, 196, 87, 100, 56, 166, 242, 86, 36, 245, 139, 125, 54, 1, 64, 205, 45, 143 }, { 128, 19, 117, 24, 156, 181, 140, 93, 161, 94, 60, 107, 163, 67, 26, 129, 147, 102, 109, 132, 41, 57, 209, 252, 255, 98, 87, 200, 224, 89, 155, 18, 245, 11, 233, 173, 16, 232, 45, 3, 157, 53, 159, 40, 185, 194, 137, 231, 254, 226, 68, 189, 248, 197, 46, 158, 168, 170, 183, 145, 123, 75, 110, 25, 28, 166, 249, 69, 61, 235, 176, 54, 2, 29, 38, 234, 48, 37, 119, 5, 186, 95, 188, 120, 214, 91, 134, 52, 31 }, { 29, 76, 143, 157, 106, 70, 93, 95, 101, 253, 254, 217, 13, 129, 59, 133, 79, 168, 73, 230, 252, 227, 149, 130, 28, 81, 195, 18, 247, 44, 27, 2, 58, 152, 3, 39, 212, 140, 186, 190, 202, 231, 225, 175, 26, 31, 118, 23, 158, 77, 146, 209, 229, 219, 55, 25, 56, 162, 155, 36, 243, 88, 54, 4, 116, 45, 6, 78, 181, 5, 105, 97, 137, 211, 223, 67, 52, 62, 236, 46, 33, 154, 57, 191, 215, 171, 110, 50, 112 }, { 58, 45, 12, 37, 193, 80, 161, 101, 231, 223, 134, 208, 237, 102, 169, 168, 146, 191, 179, 150, 87, 7, 166, 195, 36, 251, 125, 173, 64, 38, 143, 39, 181, 10, 185, 47, 120, 127, 217, 26, 62, 197, 184, 21, 85, 115, 252, 219, 110, 100, 221, 242, 138, 245, 44, 54, 8, 205, 117, 96, 53, 70, 186, 97, 15, 107, 182, 68, 206, 59, 23, 33, 41, 228, 145, 241, 196, 130, 56, 89, 86, 61, 139, 207, 1, 58, 45, 12, 37 }, { 116, 180, 96, 106, 5, 185, 94, 253, 223, 17, 103, 59, 46, 132, 85, 230, 215, 150, 174, 28, 89, 172, 244, 44, 108, 32, 38, 3, 156, 193, 160, 190, 15, 214, 226, 26, 124, 51, 169, 77, 114, 145, 255, 55, 100, 167, 239, 36, 235, 233, 1, 116, 180, 96, 106, 5, 185, 94, 253, 223, 17, 103, 59, 46, 132, 85, 230, 215, 150, 174, 28, 89, 172, 244, 44, 108, 32, 38, 3, 156, 193, 160, 190, 15, 214, 226, 26, 124, 51 }, { 232, 234, 39, 238, 160, 97, 60, 254, 134, 103, 118, 184, 84, 57, 145, 227, 220, 7, 162, 172, 245, 176, 71, 58, 180, 192, 181, 40, 95, 15, 177, 175, 208, 147, 46, 21, 73, 99, 241, 55, 200, 166, 43, 122, 44, 216, 128, 45, 48, 106, 10, 222, 202, 107, 226, 52, 237, 133, 66, 85, 209, 123, 196, 50, 167, 195, 144, 11, 54, 32, 76, 12, 148, 140, 185, 188, 211, 182, 13, 124, 102, 158, 82, 115, 215, 49, 130, 224, 249 }, { 205, 143, 37, 70, 185, 101, 107, 217, 208, 59, 184, 168, 228, 252, 150, 130, 221, 195, 61, 44, 173, 58, 117, 39, 193, 186, 47, 231, 182, 26, 237, 23, 21, 146, 145, 219, 87, 56, 242, 36, 139, 54, 64, 45, 96, 181, 80, 97, 120, 223, 68, 62, 102, 33, 85, 191, 241, 110, 7, 89, 138, 251, 207, 8, 38, 12, 53, 10, 161, 15, 127, 134, 206, 197, 169, 41, 115, 179, 196, 100, 166, 86, 245, 125, 1, 205, 143, 37, 70 }, { 135, 6, 53, 20, 190, 120, 163, 13, 237, 46, 84, 228, 229, 98, 100, 81, 69, 251, 131, 32, 45, 192, 238, 186, 94, 187, 217, 189, 236, 169, 82, 209, 241, 220, 28, 242, 72, 22, 173, 116, 201, 37, 140, 222, 15, 254, 34, 62, 204, 132, 146, 63, 75, 130, 167, 43, 245, 250, 4, 38, 24, 212, 80, 194, 253, 182, 52, 147, 184, 77, 183, 179, 149, 141, 89, 9, 203, 54, 128, 180, 39, 159, 210, 101, 214, 67, 206, 151, 158 }, { 19, 24, 181, 93, 94, 107, 67, 129, 102, 132, 57, 252, 98, 200, 89, 18, 11, 173, 232, 3, 53, 40, 194, 231, 226, 189, 197, 158, 170, 145, 75, 25, 166, 69, 235, 54, 29, 234, 37, 5, 95, 120, 91, 52, 59, 218, 82, 191, 227, 174, 221, 43, 247, 207, 32, 90, 39, 35, 111, 15, 225, 136, 237, 92, 77, 115, 246, 220, 56, 239, 122, 125, 4, 76, 96, 238, 105, 101, 177, 17, 62, 133, 42, 228, 215, 149, 7, 121, 72 }, { 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145, 150, 100, 89, 36, 44, 1, 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145, 150, 100, 89, 36, 44, 1, 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145, 150, 100, 89, 36, 44, 1, 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145, 150, 100, 89, 36, 44, 1, 38, 96, 193, 185, 15, 223, 26, 59, 169, 85, 145, 150, 100, 89, 36, 44, 1, 38, 96, 193, 185 }, { 76, 157, 70, 95, 253, 217, 129, 133, 168, 230, 227, 130, 81, 18, 44, 2, 152, 39, 140, 190, 231, 175, 31, 23, 77, 209, 219, 25, 162, 36, 88, 4, 45, 78, 5, 97, 211, 67, 62, 46, 154, 191, 171, 50, 89, 72, 176, 8, 90, 156, 10, 194, 187, 134, 124, 92, 41, 99, 75, 100, 178, 144, 125, 16, 180, 37, 20, 153, 107, 17, 248, 184, 82, 198, 150, 200, 121, 61, 250, 32, 117, 74, 40, 47, 214, 34, 237, 109, 164 }, { 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1, 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1, 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1, 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1, 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11, 1, 152, 78, 10, 153, 214, 68, 147, 79, 146, 215, 220, 221, 69, 11 }, { 45, 37, 80, 101, 223, 208, 102, 168, 191, 150, 7, 195, 251, 173, 38, 39, 10, 47, 127, 26, 197, 21, 115, 219, 100, 242, 245, 54, 205, 96, 70, 97, 107, 68, 59, 33, 228, 241, 130, 89, 61, 207, 58, 12, 193, 161, 231, 134, 237, 169, 146, 179, 87, 166, 36, 125, 64, 143, 181, 185, 120, 217, 62, 184, 85, 252, 110, 221, 138, 44, 8, 117, 53, 186, 15, 182, 206, 23, 41, 145, 196, 56, 86, 139, 1, 45, 37, 80, 101 }, { 90, 148, 186, 30, 226, 62, 109, 73, 179, 174, 162, 61, 131, 232, 96, 140, 153, 127, 52, 51, 168, 99, 98, 56, 172, 22, 8, 234, 212, 185, 240, 67, 237, 79, 114, 241, 25, 121, 245, 108, 19, 39, 20, 188, 223, 189, 133, 41, 63, 55, 221, 9, 176, 64, 3, 238, 161, 211, 34, 59, 66, 183, 219, 200, 239, 251, 71, 152, 37, 160, 137, 182, 129, 92, 85, 229, 165, 166, 72, 233, 58, 24, 35, 97, 214, 13, 197, 42, 209 }, { 180, 106, 185, 253, 17, 59, 132, 230, 150, 28, 172, 44, 32, 3, 193, 190, 214, 26, 51, 77, 145, 55, 167, 36, 233, 116, 96, 5, 94, 223, 103, 46, 85, 215, 174, 89, 244, 108, 38, 156, 160, 15, 226, 124, 169, 114, 255, 100, 239, 235, 1, 180, 106, 185, 253, 17, 59, 132, 230, 150, 28, 172, 44, 32, 3, 193, 190, 214, 26, 51, 77, 145, 55, 167, 36, 233, 116, 96, 5, 94, 223, 103, 46, 85, 215, 174, 89, 244, 108 }, { 117, 181, 161, 107, 26, 102, 41, 252, 87, 89, 245, 173, 45, 53, 185, 231, 68, 197, 168, 145, 110, 166, 61, 54, 38, 37, 186, 120, 134, 59, 21, 191, 196, 221, 36, 207, 205, 39, 80, 15, 217, 237, 33, 115, 150, 56, 138, 125, 58, 96, 10, 101, 182, 62, 169, 228, 219, 7, 86, 44, 64, 12, 70, 47, 223, 206, 184, 146, 241, 100, 195, 139, 8, 143, 193, 97, 127, 208, 23, 85, 179, 130, 242, 251, 1, 117, 181, 161, 107 }, { 234, 238, 97, 254, 103, 184, 57, 227, 7, 172, 176, 58, 192, 40, 15, 175, 147, 21, 99, 55, 166, 122, 216, 45, 106, 222, 107, 52, 133, 85, 123, 50, 195, 11, 32, 12, 140, 188, 182, 124, 158, 115, 49, 224, 36, 131, 19, 37, 105, 253, 68, 151, 154, 252, 174, 121, 251, 2, 201, 193, 194, 225, 206, 109, 114, 219, 14, 69, 125, 116, 157, 80, 30, 67, 59, 42, 198, 110, 81, 244, 173, 90, 212, 161, 214, 104, 23, 170, 246 }, { 201, 159, 47, 91, 124, 33, 209, 149, 166, 244, 71, 117, 238, 194, 223, 31, 79, 115, 98, 167, 61, 216, 90, 181, 190, 254, 206, 218, 213, 150, 224, 72, 54, 152, 106, 161, 177, 189, 184, 114, 171, 56, 18, 131, 38, 148, 111, 107, 104, 46, 146, 227, 14, 138, 233, 135, 37, 210, 211, 26, 133, 170, 241, 141, 172, 125, 232, 78, 186, 253, 136, 102, 164, 123, 100, 43, 88, 58, 157, 160, 120, 34, 151, 41, 215, 25, 195, 22, 128 }, { 143, 70, 101, 217, 59, 168, 252, 130, 195, 44, 58, 39, 186, 231, 26, 23, 146, 219, 56, 36, 54, 45, 181, 97, 223, 62, 33, 191, 110, 89, 251, 8, 12, 10, 15, 134, 197, 41, 179, 100, 86, 125, 205, 37, 185, 107, 208, 184, 228, 150, 221, 61, 173, 117, 193, 47, 182, 237, 21, 145, 87, 242, 139, 64, 96, 80, 120, 68, 102, 85, 241, 7, 138, 207, 38, 53, 161, 127, 206, 169, 115, 196, 166, 245, 1, 143, 70, 101, 217 }, { 3, 5, 15, 17, 51, 85, 255, 28, 36, 108, 180, 193, 94, 226, 59, 77, 215, 100, 172, 233, 38, 106, 190, 223, 124, 132, 145, 174, 239, 44, 116, 156, 185, 214, 103, 169, 230, 55, 89, 235, 32, 96, 160, 253, 26, 46, 114, 150, 167, 244, 1, 3, 5, 15, 17, 51, 85, 255, 28, 36, 108, 180, 193, 94, 226, 59, 77, 215, 100, 172, 233, 38, 106, 190, 223, 124, 132, 145, 174, 239, 44, 116, 156, 185, 214, 103, 169, 230, 55 }, { 6, 20, 120, 13, 46, 228, 98, 81, 251, 32, 192, 186, 187, 189, 169, 209, 220, 242, 22, 116, 37, 222, 254, 62, 132, 63, 130, 43, 250, 38, 212, 194, 182, 147, 77, 179, 141, 9, 54, 180, 159, 101, 67, 151, 85, 227, 112, 61, 142, 3, 10, 60, 136, 23, 114, 49, 166, 243, 16, 96, 93, 211, 208, 218, 230, 110, 121, 11, 58, 156, 111, 127, 31, 66, 145, 65, 155, 125, 19, 106, 97, 91, 199, 168, 215, 200, 138, 27, 90 }, { 12, 80, 231, 208, 169, 191, 87, 195, 125, 38, 181, 47, 217, 197, 85, 219, 221, 245, 8, 96, 186, 107, 206, 33, 145, 130, 86, 207, 45, 193, 101, 134, 102, 146, 150, 166, 251, 64, 39, 185, 127, 62, 21, 252, 100, 138, 54, 117, 70, 15, 68, 23, 228, 196, 89, 139, 58, 37, 161, 223, 237, 168, 179, 7, 36, 173, 143, 10, 120, 26, 184, 115, 110, 242, 44, 205, 53, 97, 182, 59, 41, 241, 56, 61, 1, 12, 80, 231, 208 }, { 24, 93, 107, 129, 132, 252, 200, 18, 173, 3, 40, 231, 189, 158, 145, 25, 69, 54, 234, 5, 120, 52, 218, 191, 174, 43, 207, 90, 35, 15, 136, 92, 115, 220, 239, 125, 76, 238, 101, 17, 133, 228, 149, 121, 44, 135, 212, 47, 175, 51, 146, 49, 162, 139, 116, 148, 97, 113, 236, 85, 171, 83, 251, 128, 156, 161, 163, 147, 41, 255, 224, 245, 16, 157, 185, 254, 248, 168, 123, 28, 61, 2, 48, 186, 214, 31, 21, 229, 141 }, { 48, 105, 127, 248, 77, 241, 224, 247, 64, 156, 95, 182, 236, 170, 150, 162, 11, 205, 212, 94, 134, 133, 213, 110, 239, 250, 45, 35, 30, 26, 218, 99, 130, 69, 108, 143, 40, 211, 206, 132, 229, 7, 144, 2, 96, 210, 254, 237, 154, 255, 221, 243, 128, 37, 190, 113, 197, 73, 49, 89, 22, 135, 181, 188, 17, 23, 183, 220, 195, 233, 90, 70, 60, 52, 169, 198, 25, 138, 216, 3, 80, 187, 129, 21, 215, 14, 61, 4, 192 }, { 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15, 26, 169, 145, 100, 36, 1, 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15, 26, 169, 145, 100, 36, 1, 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15, 26, 169, 145, 100, 36, 1, 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15, 26, 169, 145, 100, 36, 1, 96, 185, 223, 59, 85, 150, 89, 44, 38, 193, 15, 26, 169, 145, 100, 36, 1, 96, 185, 223, 59 }, { 192, 222, 182, 151, 114, 110, 155, 27, 143, 160, 177, 237, 82, 75, 89, 88, 152, 70, 240, 103, 21, 123, 224, 251, 116, 212, 101, 136, 218, 145, 200, 144, 8, 78, 190, 217, 204, 183, 87, 172, 216, 12, 105, 225, 59, 170, 98, 242, 250, 180, 10, 211, 31, 168, 255, 83, 139, 135, 238, 15, 52, 158, 252, 14, 244, 64, 74, 153, 134, 46, 209, 130, 9, 142, 96, 111, 91, 197, 57, 55, 195, 131, 201, 80, 214, 248, 41, 171, 162 }, { 157, 95, 217, 133, 230, 130, 18, 2, 39, 190, 175, 23, 209, 25, 36, 4, 78, 97, 67, 46, 191, 50, 72, 8, 156, 194, 134, 92, 99, 100, 144, 16, 37, 153, 17, 184, 198, 200, 61, 32, 74, 47, 34, 109, 145, 141, 122, 64, 148, 94, 68, 218, 63, 7, 244, 128, 53, 188, 136, 169, 126, 14, 245, 29, 106, 101, 13, 79, 252, 28, 247, 58, 212, 202, 26, 158, 229, 56, 243, 116, 181, 137, 52, 33, 215, 112, 251, 232, 119 }, { 39, 97, 134, 184, 145, 7, 245, 58, 181, 15, 208, 21, 241, 166, 44, 45, 10, 107, 237, 85, 196, 195, 54, 12, 185, 182, 102, 115, 130, 36, 8, 37, 47, 68, 169, 252, 56, 251, 205, 193, 120, 206, 168, 219, 89, 125, 117, 80, 127, 59, 146, 110, 86, 173, 96, 161, 217, 23, 191, 100, 61, 64, 53, 101, 26, 33, 179, 221, 139, 38, 70, 231, 62, 41, 150, 242, 207, 143, 186, 223, 197, 228, 87, 138, 1, 39, 97, 134, 184 }, { 78, 153, 68, 79, 215, 221, 11, 152, 10, 214, 147, 146, 220, 69, 1, 78, 153, 68, 79, 215, 221, 11, 152, 10, 214, 147, 146, 220, 69, 1, 78, 153, 68, 79, 215, 221, 11, 152, 10, 214, 147, 146, 220, 69, 1, 78, 153, 68, 79, 215, 221, 11, 152, 10, 214, 147, 146, 220, 69, 1, 78, 153, 68, 79, 215, 221, 11, 152, 10, 214, 147, 146, 220, 69, 1, 78, 153, 68, 79, 215, 221, 11, 152, 10, 214, 147, 146, 220, 69 }, { 156, 94, 26, 132, 255, 89, 233, 3, 185, 226, 46, 145, 28, 235, 38, 5, 214, 59, 114, 174, 36, 32, 106, 15, 103, 77, 150, 239, 108, 96, 190, 17, 169, 215, 167, 44, 180, 160, 223, 51, 230, 100, 244, 116, 193, 253, 124, 85, 55, 172, 1, 156, 94, 26, 132, 255, 89, 233, 3, 185, 226, 46, 145, 28, 235, 38, 5, 214, 59, 114, 174, 36, 32, 106, 15, 103, 77, 150, 239, 108, 96, 190, 17, 169, 215, 167, 44, 180, 160 }, { 37, 101, 208, 168, 150, 195, 173, 39, 47, 26, 21, 219, 242, 54, 96, 97, 68, 33, 241, 89, 207, 12, 161, 134, 169, 179, 166, 125, 143, 185, 217, 184, 252, 221, 44, 117, 186, 182, 23, 145, 56, 139, 45, 80, 223, 102, 191, 7, 251, 38, 10, 127, 197, 115, 100, 245, 205, 70, 107, 59, 228, 130, 61, 58, 193, 231, 237, 146, 87, 36, 64, 181, 120, 62, 85, 110, 138, 8, 53, 15, 206, 41, 196, 86, 1, 37, 101, 208, 168 }, { 74, 137, 206, 82, 55, 138, 16, 212, 120, 124, 73, 87, 72, 29, 193, 211, 147, 228, 25, 244, 205, 140, 177, 197, 230, 141, 251, 76, 40, 223, 204, 198, 56, 11, 180, 186, 113, 92, 252, 167, 176, 143, 111, 67, 169, 123, 162, 207, 24, 190, 68, 66, 227, 242, 108, 157, 47, 52, 84, 150, 155, 142, 37, 202, 103, 41, 149, 69, 8, 106, 60, 62, 170, 165, 36, 128, 238, 231, 199, 114, 130, 122, 232, 70, 214, 236, 115, 200, 243 }, { 148, 30, 62, 73, 174, 61, 232, 140, 127, 51, 99, 56, 22, 234, 185, 67, 79, 241, 121, 108, 39, 188, 189, 41, 55, 9, 64, 238, 211, 59, 183, 200, 251, 152, 160, 182, 92, 229, 166, 233, 24, 97, 13, 42, 150, 43, 2, 53, 60, 124, 146, 65, 122, 205, 5, 254, 102, 198, 112, 44, 201, 111, 134, 158, 255, 242, 216, 78, 101, 103, 82, 110, 18, 128, 193, 187, 118, 115, 141, 235, 45, 93, 113, 184, 215, 81, 207, 48, 194 }, { 53, 120, 237, 228, 100, 251, 45, 186, 217, 169, 241, 242, 173, 37, 15, 62, 146, 130, 245, 38, 80, 182, 184, 179, 89, 54, 39, 101, 206, 85, 87, 61, 205, 10, 223, 23, 252, 166, 207, 96, 47, 208, 41, 110, 36, 58, 70, 127, 102, 145, 221, 125, 12, 97, 26, 168, 196, 138, 64, 193, 107, 197, 191, 56, 44, 143, 161, 68, 21, 150, 86, 8, 181, 231, 59, 115, 7, 139, 117, 185, 134, 33, 219, 195, 1, 53, 120, 237, 228 }, { 106, 253, 59, 230, 28, 44, 3, 190, 26, 77, 55, 36, 116, 5, 223, 46, 215, 89, 108, 156, 15, 124, 114, 100, 235, 180, 185, 17, 132, 150, 172, 32, 193, 214, 51, 145, 167, 233, 96, 94, 103, 85, 174, 244, 38, 160, 226, 169, 255, 239, 1, 106, 253, 59, 230, 28, 44, 3, 190, 26, 77, 55, 36, 116, 5, 223, 46, 215, 89, 108, 156, 15, 124, 114, 100, 235, 180, 185, 17, 132, 150, 172, 32, 193, 214, 51, 145, 167, 233 }, { 212, 211, 197, 198, 167, 207, 157, 202, 62, 114, 200, 139, 201, 95, 26, 154, 220, 61, 19, 160, 217, 158, 171, 86, 32, 159, 127, 133, 229, 89, 216, 74, 120, 147, 230, 56, 176, 24, 47, 103, 170, 130, 243, 90, 185, 34, 42, 196, 18, 116, 10, 91, 109, 241, 239, 2, 181, 187, 151, 145, 83, 131, 39, 137, 124, 228, 141, 11, 143, 190, 52, 41, 165, 122, 38, 93, 175, 33, 75, 172, 64, 35, 254, 23, 215, 178, 173, 148, 240 }, { 181, 107, 102, 252, 89, 173, 53, 231, 197, 145, 166, 54, 37, 120, 59, 191, 221, 207, 39, 15, 237, 115, 56, 125, 96, 101, 62, 228, 7, 44, 12, 47, 206, 146, 100, 139, 143, 97, 208, 85, 130, 251, 117, 161, 26, 41, 87, 245, 45, 185, 68, 168, 110, 61, 38, 186, 134, 21, 196, 36, 205, 80, 217, 33, 150, 138, 58, 10, 182, 169, 219, 86, 64, 70, 223, 184, 241, 195, 8, 193, 127, 23, 179, 242, 1, 181, 107, 102, 252 }, { 119, 177, 23, 123, 239, 8, 159, 225, 184, 255, 43, 64, 140, 91, 169, 171, 69, 58, 20, 226, 33, 49, 18, 205, 160, 67, 21, 149, 144, 38, 105, 34, 168, 220, 244, 45, 111, 13, 41, 174, 243, 117, 95, 104, 85, 25, 203, 143, 194, 103, 146, 200, 22, 12, 94, 31, 228, 14, 176, 96, 202, 248, 115, 112, 233, 39, 30, 147, 191, 167, 27, 37, 240, 236, 145, 81, 216, 53, 211, 51, 252, 178, 142, 181, 214, 133, 179, 249, 4 }, { 238, 254, 184, 227, 172, 58, 40, 175, 21, 55, 122, 45, 222, 52, 85, 50, 11, 12, 188, 124, 115, 224, 131, 37, 253, 151, 252, 121, 2, 193, 225, 109, 219, 69, 116, 80, 67, 42, 110, 244, 90, 161, 104, 170, 100, 22, 24, 101, 248, 230, 221, 27, 74, 231, 51, 229, 242, 4, 159, 223, 218, 171, 138, 232, 160, 134, 84, 220, 245, 180, 95, 208, 73, 200, 44, 48, 202, 237, 209, 167, 54, 148, 211, 102, 215, 249, 8, 35, 163 }, { 193, 223, 169, 150, 36, 38, 185, 26, 85, 100, 44, 96, 15, 59, 145, 89, 1, 193, 223, 169, 150, 36, 38, 185, 26, 85, 100, 44, 96, 15, 59, 145, 89, 1, 193, 223, 169, 150, 36, 38, 185, 26, 85, 100, 44, 96, 15, 59, 145, 89, 1, 193, 223, 169, 150, 36, 38, 185, 26, 85, 100, 44, 96, 15, 59, 145, 89, 1, 193, 223, 169, 150, 36, 38, 185, 26, 85, 100, 44, 96, 15, 59, 145, 89, 1, 193, 223, 169, 150 }, { 159, 91, 33, 149, 244, 117, 194, 31, 115, 167, 216, 181, 254, 218, 150, 72, 152, 161, 189, 114, 56, 131, 148, 107, 46, 227, 138, 135, 210, 26, 170, 141, 125, 78, 253, 102, 123, 43, 58, 160, 34, 41, 25, 22, 96, 30, 236, 252, 249, 32, 10, 175, 84, 87, 235, 6, 101, 199, 198, 89, 2, 35, 182, 66, 55, 245, 234, 153, 62, 230, 83, 173, 119, 225, 169, 49, 144, 45, 95, 103, 228, 112, 27, 53, 214, 92, 219, 9, 19 }, { 35, 113, 21, 165, 235, 12, 137, 118, 252, 239, 128, 80, 34, 82, 100, 176, 78, 231, 133, 255, 138, 19, 111, 208, 114, 112, 54, 212, 254, 169, 98, 122, 117, 153, 124, 191, 162, 2, 70, 226, 42, 87, 203, 24, 15, 236, 229, 195, 29, 160, 68, 164, 200, 125, 156, 211, 23, 227, 9, 38, 222, 189, 228, 224, 108, 181, 225, 79, 196, 244, 234, 47, 248, 99, 89, 4, 140, 217, 84, 174, 139, 48, 30, 197, 215, 155, 58, 93, 136 }, { 70, 217, 168, 130, 44, 39, 231, 23, 219, 36, 45, 97, 62, 191, 89, 8, 10, 134, 41, 100, 125, 37, 107, 184, 150, 61, 117, 47, 237, 145, 242, 64, 80, 68, 85, 7, 207, 53, 127, 169, 196, 245, 143, 101, 59, 252, 195, 58, 186, 26, 146, 56, 54, 181, 223, 33, 110, 251, 12, 15, 197, 179, 86, 205, 185, 208, 228, 221, 173, 193, 182, 21, 87, 139, 96, 120, 102, 241, 138, 38, 161, 206, 115, 166, 1, 70, 217, 168, 130 }, { 140, 67, 41, 200, 233, 53, 254, 158, 110, 235, 48, 120, 204, 227, 36, 90, 153, 237, 63, 239, 58, 105, 104, 228, 167, 142, 70, 175, 154, 100, 250, 148, 127, 79, 55, 251, 24, 60, 102, 255, 18, 45, 194, 248, 145, 249, 29, 186, 52, 114, 221, 71, 35, 217, 77, 50, 125, 74, 177, 169, 149, 243, 12, 30, 51, 241, 9, 152, 97, 124, 198, 242, 128, 93, 26, 57, 224, 173, 159, 226, 168, 25, 176, 37, 214, 218, 196, 247, 6 }, { 5, 17, 85, 28, 108, 193, 226, 77, 100, 233, 106, 223, 132, 174, 44, 156, 214, 169, 55, 235, 96, 253, 46, 150, 244, 3, 15, 51, 255, 36, 180, 94, 59, 215, 172, 38, 190, 124, 145, 239, 116, 185, 103, 230, 89, 32, 160, 26, 114, 167, 1, 5, 17, 85, 28, 108, 193, 226, 77, 100, 233, 106, 223, 132, 174, 44, 156, 214, 169, 55, 235, 96, 253, 46, 150, 244, 3, 15, 51, 255, 36, 180, 94, 59, 215, 172, 38, 190, 124 }, { 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221, 1, 10, 68, 146, 221 }, { 20, 13, 228, 81, 32, 186, 189, 209, 242, 116, 222, 62, 63, 43, 38, 194, 147, 179, 9, 180, 101, 151, 227, 61, 3, 60, 23, 49, 243, 96, 211, 218, 110, 11, 156, 127, 66, 65, 125, 106, 91, 168, 200, 27, 193, 175, 164, 56, 71, 5, 68, 57, 83, 8, 160, 104, 115, 178, 29, 185, 129, 198, 195, 135, 190, 237, 229, 69, 45, 94, 236, 241, 72, 201, 15, 204, 75, 245, 24, 253, 184, 149, 203, 39, 214, 158, 87, 88, 148 }, { 40, 52, 115, 121, 116, 161, 248, 229, 138, 180, 202, 102, 75, 247, 96, 187, 79, 87, 176, 106, 182, 154, 14, 173, 5, 136, 228, 162, 128, 185, 31, 63, 86, 152, 94, 197, 227, 122, 12, 253, 109, 110, 22, 74, 223, 84, 200, 54, 35, 17, 146, 83, 16, 186, 103, 99, 195, 19, 194, 59, 246, 72, 143, 60, 46, 196, 203, 78, 127, 132, 25, 207, 238, 175, 85, 224, 2, 80, 104, 230, 242, 232, 95, 237, 215, 9, 117, 137, 204 }, { 80, 208, 191, 195, 38, 47, 197, 219, 245, 96, 107, 33, 130, 207, 193, 134, 146, 166, 64, 185, 62, 252, 138, 117, 15, 23, 196, 139, 37, 223, 168, 7, 173, 10, 26, 115, 242, 205, 97, 59, 241, 61, 12, 231, 169, 87, 125, 181, 217, 85, 221, 8, 186, 206, 145, 86, 45, 101, 102, 150, 251, 39, 127, 21, 100, 54, 70, 68, 228, 89, 58, 161, 237, 179, 36, 143, 120, 184, 110, 44, 53, 182, 41, 56, 1, 80, 208, 191, 195 }, { 160, 103, 145, 172, 180, 15, 46, 55, 44, 106, 226, 85, 167, 32, 185, 124, 215, 36, 3, 253, 169, 174, 233, 193, 17, 114, 89, 116, 190, 59, 255, 244, 96, 214, 132, 100, 108, 5, 26, 230, 239, 38, 94, 51, 150, 235, 156, 223, 77, 28, 1, 160, 103, 145, 172, 180, 15, 46, 55, 44, 106, 226, 85, 167, 32, 185, 124, 215, 36, 3, 253, 169, 174, 233, 193, 17, 114, 89, 116, 190, 59, 255, 244, 96, 214, 132, 100, 108, 5 }, { 93, 129, 252, 18, 3, 231, 158, 25, 54, 5, 52, 191, 43, 90, 15, 92, 220, 125, 238, 17, 228, 121, 135, 47, 51, 49, 139, 148, 113, 85, 83, 128, 161, 147, 255, 245, 157, 254, 168, 28, 2, 186, 31, 229, 36, 6, 211, 33, 50, 108, 10, 104, 99, 86, 180, 30, 184, 165, 250, 193, 34, 213, 242, 19, 94, 102, 98, 11, 53, 226, 170, 166, 29, 95, 59, 227, 247, 39, 225, 77, 56, 4, 105, 62, 215, 72, 12, 187, 66 }, { 186, 62, 179, 61, 96, 127, 168, 56, 8, 185, 237, 241, 245, 39, 223, 41, 221, 64, 161, 59, 219, 251, 37, 182, 85, 166, 58, 97, 197, 150, 139, 53, 217, 146, 89, 205, 47, 102, 196, 44, 181, 134, 228, 242, 38, 101, 23, 110, 125, 193, 68, 115, 195, 45, 15, 184, 87, 207, 70, 26, 191, 86, 117, 120, 169, 130, 54, 10, 208, 145, 138, 143, 231, 33, 100, 173, 80, 206, 252, 36, 12, 107, 21, 7, 1, 186, 62, 179, 61 }, { 105, 248, 241, 247, 156, 182, 170, 162, 205, 94, 133, 110, 250, 35, 26, 99, 69, 143, 211, 132, 7, 2, 210, 237, 255, 243, 37, 113, 73, 89, 135, 188, 23, 220, 233, 70, 52, 198, 138, 3, 187, 21, 14, 4, 185, 199, 227, 251, 74, 226, 146, 178, 19, 101, 46, 165, 207, 140, 104, 145, 9, 6, 107, 42, 28, 8, 111, 147, 219, 235, 148, 217, 57, 121, 38, 202, 92, 87, 131, 5, 208, 63, 18, 12, 214, 84, 56, 16, 222 } }; + static int[] logArrays = { 256, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175 }; + static int[] expArrays = { 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1, 2, 4 }; + + // Encode + internal static void Encode(byte[] codeWord, byte[] message, int mBitSize, int n1, int paramK, int paramG, int[] rsPoly) + { + int gateValue = 0; + byte[] encodedBytes = new byte[n1]; + int[] tmp = new int[paramG]; + + byte[] msgByte = Arrays.Clone(message); + + for (int i = 0; i < paramK; i++) + { + gateValue = Utils.ToUnsigned8bits(msgByte[paramK - 1 - i] ^ encodedBytes[n1 - paramK - 1]); + + for (int j = 0; j < paramG; j++) + { + tmp[j] = GFCalculator.mult(gateValue, rsPoly[j]); + int n = 1; + } + + for (int j = n1 - paramK - 1; j > 0; j--) + { + encodedBytes[j] = (byte)(encodedBytes[j - 1] ^ tmp[j]); + } + encodedBytes[0] = (byte)(tmp[0]); + } + + Array.Copy(msgByte, 0, encodedBytes, n1 - paramK, paramK); + Array.Copy(encodedBytes, 0, codeWord, 0, codeWord.Length); + } + + // Decode + internal static void Decode(byte[] message, byte[] codeWord, int n1, int fft, int delta, int paramK, int paramG) + { + int fftSize = 1 << fft; + int mSize = 1 << (HqcParameters.PARAM_M - 1); + + byte[] codeWordByte = Arrays.Clone(codeWord); + + int[] syndromes = new int[2 * delta]; + // Step 1: Compute syndromes + ComputeSyndromes(syndromes, codeWordByte, delta, n1); + + // Step 2: Compute the error locator polynomial sigma + int[] sigma = new int[fftSize]; + int degSigma = ComputeELP(sigma, syndromes, delta); + + // Step 3: Compute roots using FFT + int[] fftRes = new int[1 << HqcParameters.PARAM_M]; + byte[] errorSet = new byte[1 << HqcParameters.PARAM_M]; + FastFourierTransform.FFT(fftRes, sigma, delta + 1, fft); + FastFourierTransform.FastFourierTransformGetError(errorSet, fftRes, mSize, logArrays); + + // Step 4: Compute z(x) + int[] zx = new int[n1]; + ComputeZx(zx, sigma, degSigma, syndromes, delta); + + // Step 5: Compute errors + int[] errors = new int[n1]; + ComputeErrors(errors, zx, errorSet, delta, n1); + + // Step 6: Correct errors + for (int i = 0; i < n1; i++) + { + codeWordByte[i] ^= (byte) errors[i]; + } + byte[] mTmp = new byte[paramK]; + Array.Copy(codeWordByte, paramG - 1, mTmp, 0, paramK); + Array.Copy(mTmp, 0, message, 0, message.Length); + } + + private static void ComputeSyndromes(int[] syndromes, byte[] codeWord, int delta, int n1) + { + if (n1 == 46) + { + for (int i = 0; i < 2 * delta; i++) + { + for (int j = 1; j < n1; j++) + { + syndromes[i] ^= GFCalculator.mult(Utils.ToUnsigned8bits(codeWord[j]), alpha128[i, j - 1]); + } + syndromes[i] ^= Utils.ToUnsigned8bits(codeWord[0]); + } + } + else if (n1 == 56) + { + for (int i = 0; i < 2 * delta; i++) + { + for (int j = 1; j < n1; j++) + { + syndromes[i] ^= GFCalculator.mult(Utils.ToUnsigned8bits(codeWord[j]), alpha192[i, j - 1]); + } + syndromes[i] ^= Utils.ToUnsigned8bits(codeWord[0]); + } + } + else if (n1 == 90) + { + for (int i = 0; i < 2 * delta; i++) + { + for (int j = 1; j < n1; j++) + { + syndromes[i] ^= GFCalculator.mult(Utils.ToUnsigned8bits(codeWord[j]), alpha256[i, j - 1]); + } + syndromes[i] ^= Utils.ToUnsigned8bits(codeWord[0]); + } + } + } + + private static int ComputeELP(int[] sigma, int[] syndromes, int delta) + { + sigma[0] = 1; + int degSigma = 0; + int degSigmaP = 0; + int[] sigmaDup = new int[delta + 1]; + int[] sigmaP = new int[delta + 1]; + int degSigmaDup = 0; + int pp = Utils.ToUnsigned16Bits(-1); + int dp = 1; + int d = syndromes[0]; + + sigmaP[1] = 1; + + for (int i = 0; i < 2 * delta; i++) + { + Array.Copy(sigma, 0, sigmaDup, 0, delta + 1); + degSigmaDup = degSigma; + int dd = GFCalculator.mult(d, GFCalculator.inverse(dp)); + + for (int j = 1; j <= i + 1 && j <= delta; j++) + { + sigma[j] ^= GFCalculator.mult(dd, sigmaP[j]); + } + + int degX = Utils.ToUnsigned16Bits(i - pp); + int degXSigmaP = Utils.ToUnsigned16Bits(degX + degSigmaP); + + int firstMask = d != 0 ? 0xffff : 0; + int secondMask = degXSigmaP > degSigma ? 0xffff : 0; + + int mask = firstMask & secondMask; + degSigma ^= mask & (degXSigmaP ^ degSigma); + + if (i == (2 * delta - 1)) + { + break; + } + + pp ^= mask & (i ^ pp); + dp ^= mask & (d ^ dp); + + for (int k = delta; k > 0; k--) + { + sigmaP[k] = (mask & sigmaDup[k - 1]) ^ (~mask & sigmaP[k - 1]); + } + + degSigmaP ^= mask & (degSigmaDup ^ degSigmaP); + d = syndromes[i + 1]; + + for (int k = 1; k <= i + 1 && k <= delta; k++) + { + d ^= GFCalculator.mult(sigma[k], syndromes[i + 1 - k]); + } + } + return degSigma; + } + + private static void ComputeZx(int[] output, int[] sigma, int deg, int[] syndromes, int delta) + { + output[0] = 1; + + for (int i = 1; i < delta + 1; i++) + { + int mask = i - deg < 1 ? 0xffff : 0; + output[i] = mask & sigma[i]; + } + + output[1] ^= syndromes[0]; + + for (int i = 2; i <= delta; i++) + { + int mask = i - deg < 1 ? 0xffff : 0; + output[i] = mask & sigma[i - 1]; + + for (int j = 1; j < i; j++) + { + output[i] ^= (mask) & GFCalculator.mult(sigma[j], syndromes[i - j - 1]); + } + } + } + + private static void ComputeErrors(int[] res, int[] zx, byte[] errorCompactSet, int delta, int n1) + { + int[] betaSet = new int[delta]; + int[] eSet = new int[delta]; + + int deltaCount = 0; + int deltaVal = 0; + int mask1 = 0; + for (int i = 0; i < n1; i++) + { + int mark = 0; + int mask = errorCompactSet[i] != 0 ? 0xffff : 0; + for (int j = 0; j < delta; j++) + { + int iMask = j == deltaCount ? 0xffff : 0; + betaSet[j] += iMask & mask & expArrays[i]; + mark += iMask & mask & 1; + } + deltaCount += mark; + } + deltaVal = deltaCount; + + for (int i = 0; i < delta; i++) + { + int temp1 = 1; + int temp2 = 1; + int inv = GFCalculator.inverse(betaSet[i]); + int invPow = 1; + + for (int j = 1; j <= delta; j++) + { + invPow = GFCalculator.mult(invPow, inv); + temp1 ^= GFCalculator.mult(invPow, zx[j]); + } + + for (int j = 1; j < delta; j++) + { + temp2 = GFCalculator.mult(temp2, (1 ^ GFCalculator.mult(inv, betaSet[(i + j) % delta]))); + } + + mask1 = i < deltaVal ? 0xffff : 0; + eSet[i] = mask1 & GFCalculator.mult(temp1, GFCalculator.inverse(temp2)); + } + + deltaCount = 0; + for (int i = 0; i < n1; i++) + { + int mark = 0; + int mask = errorCompactSet[i] != 0 ? 0xffff : 0; + + for (int j = 0; j < delta; j++) + { + int iMask = j == deltaCount ? 0xffff : 0; + res[i] += iMask & mask & eSet[j]; + mark += iMask & mask & 1; + } + deltaCount += mark; + } + } + } +} diff --git a/crypto/src/pqc/crypto/hqc/Utils.cs b/crypto/src/pqc/crypto/hqc/Utils.cs new file mode 100644 index 000000000..4d44db07c --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/Utils.cs @@ -0,0 +1,155 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + internal class Utils + { + internal static void ResizeArray(ulong[] output, int sizeOutBits, ulong[] input, int sizeInBits, + int n1n2ByteSize, int n1n2Byte64Size) + { + ulong mask = 0x7FFFFFFFFFFFFFFFUL; + int val = 0; + if (sizeOutBits < sizeInBits) + { + if (sizeOutBits % 64 != 0) + { + val = 64 - (sizeOutBits % 64); + } + + Array.Copy(input, 0, output, 0, n1n2ByteSize); + + for (int i = 0; i < val; ++i) + { + output[n1n2Byte64Size - 1] &= mask >> i; + } + } + else + { + Array.Copy(input, 0, output, 0, (sizeInBits + 7) / 8); + } + } + + internal static void FromULongArrayToByteArray(byte[] output, ulong[] input) + { + int max = output.Length / 8; + for (int i = 0; i != max; i++) + { + Pack.UInt64_To_LE(input[i], output, i * 8); + } + + if (output.Length % 8 != 0) + { + int off = max * 8; + int count = 0; + while (off < output.Length) + { + output[off++] = (byte)(input[max] >> (count++ * 8)); + } + } + } + + internal static ulong BitMask(ulong a, ulong b) + { + uint tmp = (uint)(a % b); + return ((1UL << (int)tmp) - 1); + } + + internal static void FromByteArrayToULongArray(ulong[] output, byte[] input) + { + byte[] tmp = input; + if (input.Length % 8 != 0) + { + tmp = new byte[((input.Length + 7) / 8) * 8]; + Array.Copy(input, 0, tmp, 0, input.Length); + } + + int off = 0; + for (int i = 0; i < output.Length; i++) + { + output[i] = Pack.LE_To_UInt64(tmp, off); + off += 8; + } + } + + internal static void FromByteArrayToByte16Array(int[] output, byte[] input) + { + byte[] tmp = input; + if (input.Length % 2 != 0) + { + tmp = new byte[((input.Length + 1) / 2) * 2]; + Array.Copy(input, 0, tmp, 0, input.Length); + } + + int off = 0; + for (int i = 0; i < output.Length; i++) + { + output[i] = (int)Pack.LE_To_UInt16(tmp, off); + off += 2; + } + } + + internal static void FromByte32ArrayToULongArray(ulong[] output, int[] input) + { + for (int i = 0; i != input.Length; i += 2) + { + output[i / 2] = (uint)input[i]; + output[i / 2] |= (ulong)input[i + 1] << 32; + } + } + + internal static void FromByte16ArrayToULongArray(ulong[] output, ushort[] input) + { + for (int i = 0; i != input.Length; i += 4) + { + output[i / 4] = input[i]; + output[i / 4] |= (ulong)input[i + 1] << 16; + output[i / 4] |= (ulong)input[i + 2] << 32; + output[i / 4] |= (ulong)input[i + 3] << 48; + } + } + + internal static void FromULongArrayToByte32Array(int[] output, ulong[] input) + { + for (int i = 0; i != input.Length; i++) + { + output[2 * i] = (int)input[i]; + output[2 * i + 1] = (int)(input[i] >> 32); + } + } + + internal static void CopyBytes(int[] src, int offsetSrc, int[] dst, int offsetDst, int lengthBytes) + { + Array.Copy(src, offsetSrc, dst, offsetDst, lengthBytes / 2); + } + + internal static int GetByteSizeFromBitSize(int size) + { + return (size + 7) / 8; + } + + internal static int GetByte64SizeFromBitSize(int size) + { + return (size + 63) / 64; + } + + internal static int ToUnsigned8bits(int a) + { + return a & 0xff; + } + + internal static int ToUnsigned16Bits(int a) + { + return a & 0xffff; + } + + internal static void XorULongToByte16Array(ushort[] output, int outOff, ulong input) + { + output[outOff + 0] ^= (ushort)input; + output[outOff + 1] ^= (ushort)(input >> 16); + output[outOff + 2] ^= (ushort)(input >> 32); + output[outOff + 3] ^= (ushort)(input >> 48); + } + } +} diff --git a/crypto/src/pqc/crypto/lms/HSS.cs b/crypto/src/pqc/crypto/lms/HSS.cs index 77c5fdab0..9c21198e4 100644 --- a/crypto/src/pqc/crypto/lms/HSS.cs +++ b/crypto/src/pqc/crypto/lms/HSS.cs @@ -3,15 +3,15 @@ using System.Collections.Generic; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class HSS + public static class Hss { - public static HSSPrivateKeyParameters GenerateHssKeyPair(HSSKeyGenerationParameters parameters) + public static HssPrivateKeyParameters GenerateHssKeyPair(HssKeyGenerationParameters parameters) { // // LmsPrivateKey can derive and hold the public key so we just use an array of those. // - LMSPrivateKeyParameters[] keys = new LMSPrivateKeyParameters[parameters.Depth]; - LMSSignature[] sig = new LMSSignature[parameters.Depth - 1]; + LmsPrivateKeyParameters[] keys = new LmsPrivateKeyParameters[parameters.Depth]; + LmsSignature[] sig = new LmsSignature[parameters.Depth - 1]; byte[] rootSeed = new byte[32]; parameters.Random.NextBytes(rootSeed); @@ -33,7 +33,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms var lms = parameters.GetLmsParameters(t); if (t == 0) { - keys[t] = new LMSPrivateKeyParameters( + keys[t] = new LmsPrivateKeyParameters( lms.LMSigParameters, lms.LMOtsParameters, 0, @@ -61,10 +61,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms hssKeyMaxIndex = long.MaxValue; } - return new HSSPrivateKeyParameters( + return new HssPrivateKeyParameters( parameters.Depth, - new List<LMSPrivateKeyParameters>(keys), - new List<LMSSignature>(sig), + new List<LmsPrivateKeyParameters>(keys), + new List<LmsSignature>(sig), 0, hssKeyMaxIndex); } @@ -77,7 +77,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms * * @param keyPair */ - public static void IncrementIndex(HSSPrivateKeyParameters keyPair) + public static void IncrementIndex(HssPrivateKeyParameters keyPair) { lock (keyPair) { @@ -87,7 +87,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms } } - public static void RangeTestKeys(HSSPrivateKeyParameters keyPair) + public static void RangeTestKeys(HssPrivateKeyParameters keyPair) { lock (keyPair) { @@ -117,10 +117,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms } - public static HSSSignature GenerateSignature(HSSPrivateKeyParameters keyPair, byte[] message) + public static HssSignature GenerateSignature(HssPrivateKeyParameters keyPair, byte[] message) { - LMSSignedPubKey[] signed_pub_key; - LMSPrivateKeyParameters nextKey; + LmsSignedPubKey[] signed_pub_key; + LmsPrivateKeyParameters nextKey; int L = keyPair.L; lock (keyPair) @@ -134,10 +134,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms // Step 2. Stand in for sig[L-1] int i = 0; - signed_pub_key = new LMSSignedPubKey[L - 1]; + signed_pub_key = new LmsSignedPubKey[L - 1]; while (i < L - 1) { - signed_pub_key[i] = new LMSSignedPubKey(sig[i], keys[i + 1].GetPublicKey()); + signed_pub_key[i] = new LmsSignedPubKey(sig[i], keys[i + 1].GetPublicKey()); ++i; } @@ -147,26 +147,26 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms keyPair.IncIndex(); } - LMSContext context = nextKey.GenerateLmsContext().WithSignedPublicKeys(signed_pub_key); + LmsContext context = nextKey.GenerateLmsContext().WithSignedPublicKeys(signed_pub_key); context.BlockUpdate(message, 0, message.Length); return GenerateSignature(L, context); } - public static HSSSignature GenerateSignature(int L, LMSContext context) + public static HssSignature GenerateSignature(int L, LmsContext context) { - return new HSSSignature(L - 1, context.SignedPubKeys, LMS.GenerateSign(context)); + return new HssSignature(L - 1, context.SignedPubKeys, Lms.GenerateSign(context)); } - public static bool VerifySignature(HSSPublicKeyParameters publicKey, HSSSignature signature, byte[] message) + public static bool VerifySignature(HssPublicKeyParameters publicKey, HssSignature signature, byte[] message) { int Nspk = signature.GetlMinus1(); if (Nspk + 1 != publicKey.L) return false; - LMSSignature[] sigList = new LMSSignature[Nspk + 1]; - LMSPublicKeyParameters[] pubList = new LMSPublicKeyParameters[Nspk]; + LmsSignature[] sigList = new LmsSignature[Nspk + 1]; + LmsPublicKeyParameters[] pubList = new LmsPublicKeyParameters[Nspk]; for (int i = 0; i < Nspk; i++) { @@ -175,13 +175,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms } sigList[Nspk] = signature.Signature; - LMSPublicKeyParameters key = publicKey.LmsPublicKey; + LmsPublicKeyParameters key = publicKey.LmsPublicKey; for (int i = 0; i < Nspk; i++) { - LMSSignature sig = sigList[i]; + LmsSignature sig = sigList[i]; byte[] msg = pubList[i].ToByteArray(); - if (!LMS.VerifySignature(key, sig, msg)) + if (!Lms.VerifySignature(key, sig, msg)) { return false; } @@ -194,11 +194,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms throw new Exception(ex.Message, ex); } } - return LMS.VerifySignature(key, sigList[Nspk], message); + return Lms.VerifySignature(key, sigList[Nspk], message); } private class PlaceholderLMSPrivateKey - : LMSPrivateKeyParameters + : LmsPrivateKeyParameters { internal PlaceholderLMSPrivateKey(LMSigParameters lmsParameter, LMOtsParameters otsParameters, int q, byte[] I, int maxQ, byte[] masterSecret) @@ -211,7 +211,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms throw new Exception("placeholder only"); } - public override LMSPublicKeyParameters GetPublicKey() + public override LmsPublicKeyParameters GetPublicKey() { throw new Exception("placeholder only"); } diff --git a/crypto/src/pqc/crypto/lms/HSSKeyGenerationParameters.cs b/crypto/src/pqc/crypto/lms/HSSKeyGenerationParameters.cs index 5baaa7aa2..61ea51368 100644 --- a/crypto/src/pqc/crypto/lms/HSSKeyGenerationParameters.cs +++ b/crypto/src/pqc/crypto/lms/HSSKeyGenerationParameters.cs @@ -5,10 +5,10 @@ using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public sealed class HSSKeyGenerationParameters + public sealed class HssKeyGenerationParameters : KeyGenerationParameters { - private static LMSParameters[] ValidateLmsParameters(LMSParameters[] lmsParameters) + private static LmsParameters[] ValidateLmsParameters(LmsParameters[] lmsParameters) { if (lmsParameters == null) throw new ArgumentNullException(nameof(lmsParameters)); @@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return lmsParameters; } - private readonly LMSParameters[] m_lmsParameters; + private readonly LmsParameters[] m_lmsParameters; /** * Base constructor - parameters and a source of randomness. @@ -25,15 +25,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms * @param lmsParameters array of LMS parameters, one per level in the hierarchy (up to 8 levels). * @param random the random byte source. */ - public HSSKeyGenerationParameters(LMSParameters[] lmsParameters, SecureRandom random) - :base(random, LmsUtils.CalculateStrength(ValidateLmsParameters(lmsParameters)[0])) + public HssKeyGenerationParameters(LmsParameters[] lmsParameters, SecureRandom random) + :base(random, LmsUtilities.CalculateStrength(ValidateLmsParameters(lmsParameters)[0])) { m_lmsParameters = lmsParameters; } public int Depth => m_lmsParameters.Length; - public LMSParameters GetLmsParameters(int index) + public LmsParameters GetLmsParameters(int index) { if (index < 0 || index >= m_lmsParameters.Length) throw new ArgumentOutOfRangeException(nameof(index)); diff --git a/crypto/src/pqc/crypto/lms/HSSKeyPairGenerator.cs b/crypto/src/pqc/crypto/lms/HSSKeyPairGenerator.cs index 137275a9a..273e18904 100644 --- a/crypto/src/pqc/crypto/lms/HSSKeyPairGenerator.cs +++ b/crypto/src/pqc/crypto/lms/HSSKeyPairGenerator.cs @@ -2,19 +2,19 @@ using Org.BouncyCastle.Crypto; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public sealed class HSSKeyPairGenerator + public sealed class HssKeyPairGenerator : IAsymmetricCipherKeyPairGenerator { - private HSSKeyGenerationParameters m_parameters; + private HssKeyGenerationParameters m_parameters; public void Init(KeyGenerationParameters parameters) { - m_parameters = (HSSKeyGenerationParameters)parameters; + m_parameters = (HssKeyGenerationParameters)parameters; } public AsymmetricCipherKeyPair GenerateKeyPair() { - HSSPrivateKeyParameters privKey = HSS.GenerateHssKeyPair(m_parameters); + HssPrivateKeyParameters privKey = Hss.GenerateHssKeyPair(m_parameters); return new AsymmetricCipherKeyPair(privKey.GetPublicKey(), privKey); } diff --git a/crypto/src/pqc/crypto/lms/HSSPrivateKeyParameters.cs b/crypto/src/pqc/crypto/lms/HSSPrivateKeyParameters.cs index bcbccef1a..447dbad27 100644 --- a/crypto/src/pqc/crypto/lms/HSSPrivateKeyParameters.cs +++ b/crypto/src/pqc/crypto/lms/HSSPrivateKeyParameters.cs @@ -8,25 +8,25 @@ using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class HSSPrivateKeyParameters - : LMSKeyParameters, ILMSContextBasedSigner + public class HssPrivateKeyParameters + : LmsKeyParameters, ILmsContextBasedSigner { private int l; private bool isShard; - private IList<LMSPrivateKeyParameters> keys; - private IList<LMSSignature> sig; + private IList<LmsPrivateKeyParameters> keys; + private IList<LmsSignature> sig; private long indexLimit; private long index = 0; - private HSSPublicKeyParameters publicKey; + private HssPublicKeyParameters publicKey; - public HSSPrivateKeyParameters(int l, IList<LMSPrivateKeyParameters> keys, IList<LMSSignature> sig, long index, + public HssPrivateKeyParameters(int l, IList<LmsPrivateKeyParameters> keys, IList<LmsSignature> sig, long index, long indexLimit) :base(true) { this.l = l; - this.keys = new List<LMSPrivateKeyParameters>(keys); - this.sig = new List<LMSSignature>(sig); + this.keys = new List<LmsPrivateKeyParameters>(keys); + this.sig = new List<LmsSignature>(sig); this.index = index; this.indexLimit = indexLimit; this.isShard = false; @@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms ResetKeyToIndex(); } - private HSSPrivateKeyParameters(int l, IList<LMSPrivateKeyParameters> keys, IList<LMSSignature> sig, long index, + private HssPrivateKeyParameters(int l, IList<LmsPrivateKeyParameters> keys, IList<LmsSignature> sig, long index, long indexLimit, bool isShard) :base(true) { @@ -45,67 +45,56 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms this.l = l; // this.keys = new UnmodifiableListProxy(keys); // this.sig = new UnmodifiableListProxy(sig); - this.keys = new List<LMSPrivateKeyParameters>(keys); - this.sig = new List<LMSSignature>(sig); + this.keys = new List<LmsPrivateKeyParameters>(keys); + this.sig = new List<LmsSignature>(sig); this.index = index; this.indexLimit = indexLimit; this.isShard = isShard; } - public static HSSPrivateKeyParameters GetInstance(byte[] privEnc, byte[] pubEnc) + public static HssPrivateKeyParameters GetInstance(byte[] privEnc, byte[] pubEnc) { - HSSPrivateKeyParameters pKey = GetInstance(privEnc); + HssPrivateKeyParameters pKey = GetInstance(privEnc); - pKey.publicKey = HSSPublicKeyParameters.GetInstance(pubEnc); + pKey.publicKey = HssPublicKeyParameters.GetInstance(pubEnc); return pKey; } - public static HSSPrivateKeyParameters GetInstance(Object src) + public static HssPrivateKeyParameters GetInstance(object src) { - if (src is HSSPrivateKeyParameters hssPrivateKeyParameters) + if (src is HssPrivateKeyParameters hssPrivateKeyParameters) { return hssPrivateKeyParameters; } else if (src is BinaryReader binaryReader) { - byte[] data = binaryReader.ReadBytes(4); - Array.Reverse(data); - int version = BitConverter.ToInt32(data, 0); + int version = BinaryReaders.ReadInt32BigEndian(binaryReader); if (version != 0) - { - throw new Exception("unknown version for hss private key"); - } - data = binaryReader.ReadBytes(4); - Array.Reverse(data); - int d = BitConverter.ToInt32(data, 0); - - data = binaryReader.ReadBytes(8); - Array.Reverse(data); - long index = BitConverter.ToInt64(data, 0); - - data = binaryReader.ReadBytes(8); - Array.Reverse(data); - long maxIndex = BitConverter.ToInt64(data, 0);; - - data = binaryReader.ReadBytes(1); - Array.Reverse(data); - bool limited = BitConverter.ToBoolean(data, 0); - - var keys = new List<LMSPrivateKeyParameters>(); - var signatures = new List<LMSSignature>(); + throw new Exception("unknown version for HSS private key"); + + int d = BinaryReaders.ReadInt32BigEndian(binaryReader); + + long index = BinaryReaders.ReadInt64BigEndian(binaryReader); + + long maxIndex = BinaryReaders.ReadInt64BigEndian(binaryReader); + + bool limited = binaryReader.ReadBoolean(); + + var keys = new List<LmsPrivateKeyParameters>(); + var signatures = new List<LmsSignature>(); for (int t = 0; t < d; t++) { - keys.Add(LMSPrivateKeyParameters.GetInstance(src)); + keys.Add(LmsPrivateKeyParameters.GetInstance(src)); } for (int t = 0; t < d - 1; t++) { - signatures.Add(LMSSignature.GetInstance(src)); + signatures.Add(LmsSignature.GetInstance(src)); } - return new HSSPrivateKeyParameters(d, keys, signatures, index, maxIndex, limited); + return new HssPrivateKeyParameters(d, keys, signatures, index, maxIndex, limited); } else if (src is byte[] bytes) { @@ -133,25 +122,25 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms public int L => l; - public long GetIndex() + public long GetIndex() { lock (this) return index; } - public LMSParameters[] GetLmsParameters() + public LmsParameters[] GetLmsParameters() { lock (this) { int len = keys.Count; - LMSParameters[] parms = new LMSParameters[len]; + LmsParameters[] parms = new LmsParameters[len]; for (int i = 0; i < len; i++) { - LMSPrivateKeyParameters lmsPrivateKey = keys[i]; + LmsPrivateKeyParameters lmsPrivateKey = keys[i]; - parms[i] = new LMSParameters(lmsPrivateKey.GetSigParameters(), lmsPrivateKey.GetOtsParameters()); + parms[i] = new LmsParameters(lmsPrivateKey.GetSigParameters(), lmsPrivateKey.GetOtsParameters()); } return parms; @@ -166,17 +155,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms } } - private static HSSPrivateKeyParameters MakeCopy(HSSPrivateKeyParameters privateKeyParameters) + private static HssPrivateKeyParameters MakeCopy(HssPrivateKeyParameters privateKeyParameters) { return GetInstance(privateKeyParameters.GetEncoded()); } - protected void UpdateHierarchy(IList<LMSPrivateKeyParameters> newKeys, IList<LMSSignature> newSig) + protected void UpdateHierarchy(IList<LmsPrivateKeyParameters> newKeys, IList<LmsSignature> newSig) { lock (this) { - keys = new List<LMSPrivateKeyParameters>(newKeys); - sig = new List<LMSSignature>(newSig); + keys = new List<LmsPrivateKeyParameters>(newKeys); + sig = new List<LmsSignature>(newSig); } } @@ -192,7 +181,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return indexLimit - index; } - LMSPrivateKeyParameters GetRootKey() + LmsPrivateKeyParameters GetRootKey() { return keys[0]; } @@ -206,7 +195,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms * @param usageCount the number of usages the key should have. * @return a key based on the current key that can be used usageCount times. */ - public HSSPrivateKeyParameters ExtractKeyShard(int usageCount) + public HssPrivateKeyParameters ExtractKeyShard(int usageCount) { lock (this) { @@ -221,11 +210,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms // index += usageCount; - var keys = new List<LMSPrivateKeyParameters>(this.GetKeys()); - var sig = new List<LMSSignature>(this.GetSig()); + var keys = new List<LmsPrivateKeyParameters>(this.GetKeys()); + var sig = new List<LmsSignature>(this.GetSig()); - HSSPrivateKeyParameters shard = MakeCopy( - new HSSPrivateKeyParameters(l, keys, sig, shardStartIndex, maxIndexForShard, true)); + HssPrivateKeyParameters shard = MakeCopy( + new HssPrivateKeyParameters(l, keys, sig, shardStartIndex, maxIndexForShard, true)); ResetKeyToIndex(); @@ -233,12 +222,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms } } - public IList<LMSPrivateKeyParameters> GetKeys() + public IList<LmsPrivateKeyParameters> GetKeys() { lock (this) return keys; } - internal IList<LMSSignature> GetSig() + internal IList<LmsSignature> GetSig() { lock (this) return sig; } @@ -271,14 +260,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms // LMSSignature[] sig = this.sig.toArray(new LMSSignature[this.sig.Count]);// new LMSSignature[originalKeys.Size() - 1]; // - LMSPrivateKeyParameters originalRootKey = this.GetRootKey(); + LmsPrivateKeyParameters originalRootKey = this.GetRootKey(); // // We need to replace the root key to a new q value. // if (keys[0].GetIndex() - 1 != qTreePath[0]) { - keys[0] = LMS.GenerateKeys( + keys[0] = Lms.GenerateKeys( originalRootKey.GetSigParameters(), originalRootKey.GetOtsParameters(), (int)qTreePath[0], originalRootKey.GetI(), originalRootKey.GetMasterSecret()); @@ -287,7 +276,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms for (int i = 1; i < qTreePath.Length; i++) { - LMSPrivateKeyParameters intermediateKey = keys[i - 1]; + LmsPrivateKeyParameters intermediateKey = keys[i - 1]; byte[] childI = new byte[16]; byte[] childSeed = new byte[32]; @@ -326,7 +315,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms // // This means the parent has changed. // - keys[i] = LMS.GenerateKeys( + keys[i] = Lms.GenerateKeys( originalKeys[i].GetSigParameters(), originalKeys[i].GetOtsParameters(), (int)qTreePath[i], childI, childSeed); @@ -334,7 +323,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms // // Ensure post increment occurs on parent and the new public key is signed. // - sig[i - 1] = LMS.GenerateSign((LMSPrivateKeyParameters)keys[i - 1], ((LMSPrivateKeyParameters)keys[i]).GetPublicKey().ToByteArray()); + sig[i - 1] = Lms.GenerateSign((LmsPrivateKeyParameters)keys[i - 1], ((LmsPrivateKeyParameters)keys[i]).GetPublicKey().ToByteArray()); changed = true; } else if (!lmsQMatch) @@ -343,7 +332,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms // Q is different so we can generate a new private key but it will have the same public // key so we do not need to sign it again. // - keys[i] = LMS.GenerateKeys( + keys[i] = Lms.GenerateKeys( originalKeys[i].GetSigParameters(), originalKeys[i].GetOtsParameters(), (int)qTreePath[i], childI, childSeed); @@ -358,10 +347,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms } } - public HSSPublicKeyParameters GetPublicKey() + public HssPublicKeyParameters GetPublicKey() { lock (this) - return new HSSPublicKeyParameters(l, GetRootKey().GetPublicKey()); + return new HssPublicKeyParameters(l, GetRootKey().GetPublicKey()); } internal void ReplaceConsumedKey(int d) @@ -375,21 +364,21 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms byte[] childI = new byte[16]; Array.Copy(postImage, 0, childI, 0, childI.Length); - var newKeys = new List<LMSPrivateKeyParameters>(keys); + var newKeys = new List<LmsPrivateKeyParameters>(keys); // // We need the parameters from the LMS key we are replacing. // - LMSPrivateKeyParameters oldPk = keys[d]; + LmsPrivateKeyParameters oldPk = keys[d]; - newKeys[d] = LMS.GenerateKeys(oldPk.GetSigParameters(), oldPk.GetOtsParameters(), 0, childI, childRootSeed); + newKeys[d] = Lms.GenerateKeys(oldPk.GetSigParameters(), oldPk.GetOtsParameters(), 0, childI, childRootSeed); - var newSig = new List<LMSSignature>(sig); + var newSig = new List<LmsSignature>(sig); - newSig[d - 1] = LMS.GenerateSign(newKeys[d - 1], newKeys[d].GetPublicKey().ToByteArray()); + newSig[d - 1] = Lms.GenerateSign(newKeys[d - 1], newKeys[d].GetPublicKey().ToByteArray()); - this.keys = new List<LMSPrivateKeyParameters>(newKeys); - this.sig = new List<LMSSignature>(newSig); + this.keys = new List<LmsPrivateKeyParameters>(newKeys); + this.sig = new List<LmsSignature>(newSig); } public override bool Equals(Object o) @@ -403,7 +392,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return false; } - HSSPrivateKeyParameters that = (HSSPrivateKeyParameters)o; + HssPrivateKeyParameters that = (HssPrivateKeyParameters)o; if (l != that.l) { @@ -456,12 +445,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms .U64Str(indexLimit) .Boolean(isShard); // Depth - foreach (LMSPrivateKeyParameters key in keys) + foreach (LmsPrivateKeyParameters key in keys) { composer.Bytes(key); } - foreach (LMSSignature s in sig) + foreach (LmsSignature s in sig) { composer.Bytes(s); } @@ -486,15 +475,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return MakeCopy(this); } - public LMSContext GenerateLmsContext() + public LmsContext GenerateLmsContext() { - LMSSignedPubKey[] signed_pub_key; - LMSPrivateKeyParameters nextKey; + LmsSignedPubKey[] signed_pub_key; + LmsPrivateKeyParameters nextKey; int L = this.L; lock (this) { - HSS.RangeTestKeys(this); + Hss.RangeTestKeys(this); var keys = this.GetKeys(); var sig = this.GetSig(); @@ -503,10 +492,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms // Step 2. Stand in for sig[L-1] int i = 0; - signed_pub_key = new LMSSignedPubKey[L - 1]; + signed_pub_key = new LmsSignedPubKey[L - 1]; while (i < L - 1) { - signed_pub_key[i] = new LMSSignedPubKey(sig[i], keys[i + 1].GetPublicKey()); + signed_pub_key[i] = new LmsSignedPubKey(sig[i], keys[i + 1].GetPublicKey()); ++i; } @@ -519,11 +508,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return nextKey.GenerateLmsContext().WithSignedPublicKeys(signed_pub_key); } - public byte[] GenerateSignature(LMSContext context) + public byte[] GenerateSignature(LmsContext context) { try { - return HSS.GenerateSignature(L, context).GetEncoded(); + return Hss.GenerateSignature(L, context).GetEncoded(); } catch (IOException e) { diff --git a/crypto/src/pqc/crypto/lms/HSSPublicKeyParameters.cs b/crypto/src/pqc/crypto/lms/HSSPublicKeyParameters.cs index f6641d9c1..85b781228 100644 --- a/crypto/src/pqc/crypto/lms/HSSPublicKeyParameters.cs +++ b/crypto/src/pqc/crypto/lms/HSSPublicKeyParameters.cs @@ -5,32 +5,31 @@ using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public sealed class HSSPublicKeyParameters - : LMSKeyParameters, ILMSContextBasedVerifier + public sealed class HssPublicKeyParameters + : LmsKeyParameters, ILmsContextBasedVerifier { private readonly int m_l; - private readonly LMSPublicKeyParameters m_lmsPublicKey; + private readonly LmsPublicKeyParameters m_lmsPublicKey; - public HSSPublicKeyParameters(int l, LMSPublicKeyParameters lmsPublicKey) + public HssPublicKeyParameters(int l, LmsPublicKeyParameters lmsPublicKey) :base(false) { m_l = l; m_lmsPublicKey = lmsPublicKey; } - public static HSSPublicKeyParameters GetInstance(object src) + public static HssPublicKeyParameters GetInstance(object src) { - if (src is HSSPublicKeyParameters hssPublicKeyParameters) + if (src is HssPublicKeyParameters hssPublicKeyParameters) { return hssPublicKeyParameters; } else if (src is BinaryReader binaryReader) { - byte[] data = binaryReader.ReadBytes(4); - Array.Reverse(data); - int L = BitConverter.ToInt32(data, 0); - LMSPublicKeyParameters lmsPublicKey = LMSPublicKeyParameters.GetInstance(src);// todo check endianness - return new HSSPublicKeyParameters(L, lmsPublicKey); + int L = BinaryReaders.ReadInt32BigEndian(binaryReader); + + LmsPublicKeyParameters lmsPublicKey = LmsPublicKeyParameters.GetInstance(src); + return new HssPublicKeyParameters(L, lmsPublicKey); } else if (src is byte[] bytes) { @@ -55,7 +54,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms public int L => m_l; - public LMSPublicKeyParameters LmsPublicKey => m_lmsPublicKey; + public LmsPublicKeyParameters LmsPublicKey => m_lmsPublicKey; public override bool Equals(Object o) { @@ -64,7 +63,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms if (o == null || GetType() != o.GetType()) return false; - HSSPublicKeyParameters publicKey = (HSSPublicKeyParameters)o; + HssPublicKeyParameters publicKey = (HssPublicKeyParameters)o; return m_l == publicKey.m_l && m_lmsPublicKey.Equals(publicKey.m_lmsPublicKey); @@ -84,39 +83,39 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms .Build(); } - public LMSContext GenerateLmsContext(byte[] sigEnc) + public LmsContext GenerateLmsContext(byte[] sigEnc) { - HSSSignature signature; + HssSignature signature; try { - signature = HSSSignature.GetInstance(sigEnc, L); + signature = HssSignature.GetInstance(sigEnc, L); } catch (IOException e) { throw new Exception($"cannot parse signature: {e.Message}"); } - LMSSignedPubKey[] signedPubKeys = signature.GetSignedPubKeys(); - LMSPublicKeyParameters key = signedPubKeys[signedPubKeys.Length - 1].GetPublicKey(); + LmsSignedPubKey[] signedPubKeys = signature.GetSignedPubKeys(); + LmsPublicKeyParameters key = signedPubKeys[signedPubKeys.Length - 1].GetPublicKey(); return key.GenerateOtsContext(signature.Signature).WithSignedPublicKeys(signedPubKeys); } - public bool Verify(LMSContext context) + public bool Verify(LmsContext context) { - LMSSignedPubKey[] sigKeys = context.SignedPubKeys; + LmsSignedPubKey[] sigKeys = context.SignedPubKeys; if (sigKeys.Length != L - 1) return false; - LMSPublicKeyParameters key = LmsPublicKey; + LmsPublicKeyParameters key = LmsPublicKey; bool failed = false; for (int i = 0; i < sigKeys.Length; i++) { - LMSSignature sig = sigKeys[i].GetSignature(); + LmsSignature sig = sigKeys[i].GetSignature(); byte[] msg = sigKeys[i].GetPublicKey().ToByteArray(); - if (!LMS.VerifySignature(key, sig, msg)) + if (!Lms.VerifySignature(key, sig, msg)) { failed = true; } diff --git a/crypto/src/pqc/crypto/lms/HSSSignature.cs b/crypto/src/pqc/crypto/lms/HSSSignature.cs index 793beda66..7c4599835 100644 --- a/crypto/src/pqc/crypto/lms/HSSSignature.cs +++ b/crypto/src/pqc/crypto/lms/HSSSignature.cs @@ -6,54 +6,51 @@ using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class HSSSignature + public sealed class HssSignature : IEncodable { private int lMinus1; - private LMSSignedPubKey[] signedPubKey; - private LMSSignature signature; + private LmsSignedPubKey[] signedPubKey; + private LmsSignature signature; - public HSSSignature(int lMinus1, LMSSignedPubKey[] signedPubKey, LMSSignature signature) + public HssSignature(int lMinus1, LmsSignedPubKey[] signedPubKey, LmsSignature signature) { this.lMinus1 = lMinus1; this.signedPubKey = signedPubKey; this.signature = signature; } - /** - * @param src byte[], InputStream or HSSSignature - * @param L The HSS depth, available from public key. - * @return An HSSSignature instance. - * @throws IOException - */ - public static HSSSignature GetInstance(Object src, int L) + * @param src byte[], InputStream or HSSSignature + * @param L The HSS depth, available from public key. + * @return An HSSSignature instance. + * @throws IOException + */ + public static HssSignature GetInstance(object src, int L) { - if (src is HSSSignature hssSignature) + if (src is HssSignature hssSignature) { return hssSignature; } else if (src is BinaryReader binaryReader) { - byte[] data = binaryReader.ReadBytes(4); - Array.Reverse(data); - int lminus = BitConverter.ToInt32(data, 0); + int lminus = BinaryReaders.ReadInt32BigEndian(binaryReader); if (lminus != L - 1) throw new Exception("nspk exceeded maxNspk"); - LMSSignedPubKey[] signedPubKeys = new LMSSignedPubKey[lminus]; + LmsSignedPubKey[] signedPubKeys = new LmsSignedPubKey[lminus]; if (lminus != 0) { for (int t = 0; t < signedPubKeys.Length; t++) { - signedPubKeys[t] = new LMSSignedPubKey(LMSSignature.GetInstance(src), - LMSPublicKeyParameters.GetInstance(src)); + signedPubKeys[t] = new LmsSignedPubKey(LmsSignature.GetInstance(src), + LmsPublicKeyParameters.GetInstance(src)); } } - LMSSignature sig = LMSSignature.GetInstance(src); + LmsSignature sig = LmsSignature.GetInstance(src); - return new HSSSignature(lminus, signedPubKeys, sig); + return new HssSignature(lminus, signedPubKeys, sig); } else if (src is byte[] bytes) { @@ -82,12 +79,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return lMinus1; } - public LMSSignedPubKey[] GetSignedPubKeys() + public LmsSignedPubKey[] GetSignedPubKeys() { return signedPubKey; } - public LMSSignature Signature => signature; + public LmsSignature Signature => signature; public override bool Equals(Object o) { @@ -101,7 +98,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return false; } - HSSSignature signature1 = (HSSSignature) o; + HssSignature signature1 = (HssSignature) o; if (lMinus1 != signature1.lMinus1) { @@ -141,7 +138,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms composer.U32Str(lMinus1); if (signedPubKey != null) { - foreach (LMSSignedPubKey sigPub in signedPubKey) + foreach (LmsSignedPubKey sigPub in signedPubKey) { composer.Bytes(sigPub); } diff --git a/crypto/src/pqc/crypto/lms/HSSSigner.cs b/crypto/src/pqc/crypto/lms/HSSSigner.cs index 4bbdff848..9ef7b57ae 100644 --- a/crypto/src/pqc/crypto/lms/HSSSigner.cs +++ b/crypto/src/pqc/crypto/lms/HSSSigner.cs @@ -5,21 +5,21 @@ using Org.BouncyCastle.Crypto; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class HSSSigner + public sealed class HssSigner : IMessageSigner { - private HSSPrivateKeyParameters privKey; - private HSSPublicKeyParameters pubKey; + private HssPrivateKeyParameters privKey; + private HssPublicKeyParameters pubKey; public void Init(bool forSigning, ICipherParameters param) { if (forSigning) { - this.privKey = (HSSPrivateKeyParameters) param; + this.privKey = (HssPrivateKeyParameters) param; } else { - this.pubKey = (HSSPublicKeyParameters) param; + this.pubKey = (HssPublicKeyParameters) param; } } @@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms { try { - return HSS.GenerateSignature(privKey, message).GetEncoded(); + return Hss.GenerateSignature(privKey, message).GetEncoded(); } catch (IOException e) { @@ -39,7 +39,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms { try { - return HSS.VerifySignature(pubKey, HSSSignature.GetInstance(signature, pubKey.L), message); + return Hss.VerifySignature(pubKey, HssSignature.GetInstance(signature, pubKey.L), message); } catch (IOException e) { diff --git a/crypto/src/pqc/crypto/lms/ILMSContextBasedSigner.cs b/crypto/src/pqc/crypto/lms/ILMSContextBasedSigner.cs index 86144b8e8..94864b471 100644 --- a/crypto/src/pqc/crypto/lms/ILMSContextBasedSigner.cs +++ b/crypto/src/pqc/crypto/lms/ILMSContextBasedSigner.cs @@ -1,10 +1,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public interface ILMSContextBasedSigner + public interface ILmsContextBasedSigner { - LMSContext GenerateLmsContext(); + LmsContext GenerateLmsContext(); - byte[] GenerateSignature(LMSContext context); + byte[] GenerateSignature(LmsContext context); long GetUsagesRemaining(); } diff --git a/crypto/src/pqc/crypto/lms/ILMSContextBasedVerifier.cs b/crypto/src/pqc/crypto/lms/ILMSContextBasedVerifier.cs index 76538d052..ffba83ad2 100644 --- a/crypto/src/pqc/crypto/lms/ILMSContextBasedVerifier.cs +++ b/crypto/src/pqc/crypto/lms/ILMSContextBasedVerifier.cs @@ -1,9 +1,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public interface ILMSContextBasedVerifier + public interface ILmsContextBasedVerifier { - LMSContext GenerateLmsContext(byte[] signature); + LmsContext GenerateLmsContext(byte[] signature); - bool Verify(LMSContext context); + bool Verify(LmsContext context); } } \ No newline at end of file diff --git a/crypto/src/pqc/crypto/lms/LMOtsPrivateKey.cs b/crypto/src/pqc/crypto/lms/LMOtsPrivateKey.cs index 8482c1a53..e9df6fbfd 100644 --- a/crypto/src/pqc/crypto/lms/LMOtsPrivateKey.cs +++ b/crypto/src/pqc/crypto/lms/LMOtsPrivateKey.cs @@ -18,22 +18,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms m_masterSecret = masterSecret; } - public LMSContext GetSignatureContext(LMSigParameters sigParams, byte[][] path) + public LmsContext GetSignatureContext(LMSigParameters sigParams, byte[][] path) { - byte[] C = new byte[LM_OTS.SEED_LEN]; + byte[] C = new byte[LMOts.SEED_LEN]; SeedDerive derive = GetDerivationFunction(); - derive.J = LM_OTS.SEED_RANDOMISER_INDEX; // This value from reference impl. + derive.J = LMOts.SEED_RANDOMISER_INDEX; // This value from reference impl. derive.DeriveSeed(false, C, 0); IDigest ctx = DigestUtilities.GetDigest(m_parameters.DigestOid); - LmsUtils.ByteArray(m_I, ctx); - LmsUtils.U32Str(m_q, ctx); - LmsUtils.U16Str(LM_OTS.D_MESG, ctx); - LmsUtils.ByteArray(C, ctx); + LmsUtilities.ByteArray(m_I, ctx); + LmsUtilities.U32Str(m_q, ctx); + LmsUtilities.U16Str(LMOts.D_MESG, ctx); + LmsUtilities.ByteArray(C, ctx); - return new LMSContext(this, sigParams, ctx, C, path); + return new LmsContext(this, sigParams, ctx, C, path); } internal SeedDerive GetDerivationFunction() diff --git a/crypto/src/pqc/crypto/lms/LMOtsPublicKey.cs b/crypto/src/pqc/crypto/lms/LMOtsPublicKey.cs index 49c0871f5..09e8b2951 100644 --- a/crypto/src/pqc/crypto/lms/LMOtsPublicKey.cs +++ b/crypto/src/pqc/crypto/lms/LMOtsPublicKey.cs @@ -32,22 +32,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms } else if (src is BinaryReader binaryReader) { - byte[] data = binaryReader.ReadBytes(4); - Array.Reverse(data); - int index = BitConverter.ToInt32(data, 0); - + int index = BinaryReaders.ReadInt32BigEndian(binaryReader); LMOtsParameters parameter = LMOtsParameters.GetParametersByID(index); - byte[] I = new byte[16]; - binaryReader.Read(I, 0, I.Length); - - Array.Reverse(data); - int q = BitConverter.ToInt32(data, 0); - byte[] K = new byte[parameter.N]; - binaryReader.Read(K, 0, K.Length); + byte[] I = BinaryReaders.ReadBytesFully(binaryReader, 16); - return new LMOtsPublicKey(parameter, I, q, K); + int q = BinaryReaders.ReadInt32BigEndian(binaryReader); + + byte[] K = BinaryReaders.ReadBytesFully(binaryReader, parameter.N); + return new LMOtsPublicKey(parameter, I, q, K); } else if (src is byte[] bytes) { @@ -109,28 +103,28 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms .Build(); } - internal LMSContext CreateOtsContext(LMOtsSignature signature) + internal LmsContext CreateOtsContext(LMOtsSignature signature) { IDigest ctx = DigestUtilities.GetDigest(m_parameters.DigestOid); - LmsUtils.ByteArray(m_I, ctx); - LmsUtils.U32Str(m_q, ctx); - LmsUtils.U16Str(LM_OTS.D_MESG, ctx); - LmsUtils.ByteArray(signature.C, ctx); + LmsUtilities.ByteArray(m_I, ctx); + LmsUtilities.U32Str(m_q, ctx); + LmsUtilities.U16Str(LMOts.D_MESG, ctx); + LmsUtilities.ByteArray(signature.C, ctx); - return new LMSContext(this, signature, ctx); + return new LmsContext(this, signature, ctx); } - internal LMSContext CreateOtsContext(LMSSignature signature) + internal LmsContext CreateOtsContext(LmsSignature signature) { IDigest ctx = DigestUtilities.GetDigest(m_parameters.DigestOid); - LmsUtils.ByteArray(m_I, ctx); - LmsUtils.U32Str(m_q, ctx); - LmsUtils.U16Str(LM_OTS.D_MESG, ctx); - LmsUtils.ByteArray(signature.OtsSignature.C, ctx); + LmsUtilities.ByteArray(m_I, ctx); + LmsUtilities.U32Str(m_q, ctx); + LmsUtilities.U16Str(LMOts.D_MESG, ctx); + LmsUtilities.ByteArray(signature.OtsSignature.C, ctx); - return new LMSContext(this, signature, ctx); + return new LmsContext(this, signature, ctx); } } } diff --git a/crypto/src/pqc/crypto/lms/LMOtsSignature.cs b/crypto/src/pqc/crypto/lms/LMOtsSignature.cs index db4b25641..c55866661 100644 --- a/crypto/src/pqc/crypto/lms/LMOtsSignature.cs +++ b/crypto/src/pqc/crypto/lms/LMOtsSignature.cs @@ -13,9 +13,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms private readonly byte[] m_C; private readonly byte[] m_y; - public LMOtsSignature(LMOtsParameters ParamType, byte[] c, byte[] y) + public LMOtsSignature(LMOtsParameters paramType, byte[] c, byte[] y) { - m_paramType = ParamType; + m_paramType = paramType; m_C = c; m_y = y; } @@ -26,22 +26,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms { return lmOtsSignature; } - //TODO replace inputstreams with something - else if (src is BinaryReader binaryReader) { - byte[] data = binaryReader.ReadBytes(4); - Array.Reverse(data); - int index = BitConverter.ToInt32(data, 0); - LMOtsParameters type = LMOtsParameters.GetParametersByID(index); - byte[] C = new byte[type.N]; + int index = BinaryReaders.ReadInt32BigEndian(binaryReader); + LMOtsParameters parameter = LMOtsParameters.GetParametersByID(index); - binaryReader.Read(C, 0, C.Length); - - byte[] sig = new byte[type.P * type.N]; - binaryReader.Read(sig, 0, sig.Length); + byte[] C = BinaryReaders.ReadBytesFully(binaryReader, parameter.N); - return new LMOtsSignature(type, C, sig); + byte[] sig = BinaryReaders.ReadBytesFully(binaryReader, parameter.P * parameter.N); + + return new LMOtsSignature(parameter, C, sig); } else if (src is byte[] bytes) { diff --git a/crypto/src/pqc/crypto/lms/LMS.cs b/crypto/src/pqc/crypto/lms/LMS.cs index c2401bd35..3c17b0a1e 100644 --- a/crypto/src/pqc/crypto/lms/LMS.cs +++ b/crypto/src/pqc/crypto/lms/LMS.cs @@ -5,12 +5,12 @@ using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public static class LMS + public static class Lms { internal static ushort D_LEAF = 0x8282; internal static ushort D_INTR = 0x8383; - public static LMSPrivateKeyParameters GenerateKeys(LMSigParameters parameterSet, + public static LmsPrivateKeyParameters GenerateKeys(LMSigParameters parameterSet, LMOtsParameters lmOtsParameters, int q, byte[] I, byte[] rootSeed) { // @@ -30,10 +30,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms int twoToH = 1 << parameterSet.H; - return new LMSPrivateKeyParameters(parameterSet, lmOtsParameters, q, I, twoToH, rootSeed); + return new LmsPrivateKeyParameters(parameterSet, lmOtsParameters, q, I, twoToH, rootSeed); } - public static LMSSignature GenerateSign(LMSPrivateKeyParameters privateKey, byte[] message) + public static LmsSignature GenerateSign(LmsPrivateKeyParameters privateKey, byte[] message) { // // Get T from the public key. @@ -42,14 +42,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms // byte[][] T = new byte[privateKey.getMaxQ()][]; // Step 2 - LMSContext context = privateKey.GenerateLmsContext(); + LmsContext context = privateKey.GenerateLmsContext(); context.BlockUpdate(message, 0, message.Length); return GenerateSign(context); } - public static LMSSignature GenerateSign(LMSContext context) + public static LmsSignature GenerateSign(LmsContext context) { // // Get T from the public key. @@ -59,36 +59,36 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms // Step 1. LMOtsSignature ots_signature = - LM_OTS.LMOtsGenerateSignature(context.PrivateKey, context.GetQ(), context.C); + LMOts.LMOtsGenerateSignature(context.PrivateKey, context.GetQ(), context.C); - return new LMSSignature(context.PrivateKey.Q, ots_signature, context.SigParams, context.Path); + return new LmsSignature(context.PrivateKey.Q, ots_signature, context.SigParams, context.Path); } - public static bool VerifySignature(LMSPublicKeyParameters publicKey, LMSSignature S, byte[] message) + public static bool VerifySignature(LmsPublicKeyParameters publicKey, LmsSignature S, byte[] message) { - LMSContext context = publicKey.GenerateOtsContext(S); + LmsContext context = publicKey.GenerateOtsContext(S); - LmsUtils.ByteArray(message, context); + LmsUtilities.ByteArray(message, context); return VerifySignature(publicKey, context); } - public static bool VerifySignature(LMSPublicKeyParameters publicKey, byte[] S, byte[] message) + public static bool VerifySignature(LmsPublicKeyParameters publicKey, byte[] S, byte[] message) { - LMSContext context = publicKey.GenerateLmsContext(S); + LmsContext context = publicKey.GenerateLmsContext(S); - LmsUtils.ByteArray(message, context); + LmsUtilities.ByteArray(message, context); return VerifySignature(publicKey, context); } - public static bool VerifySignature(LMSPublicKeyParameters publicKey, LMSContext context) + public static bool VerifySignature(LmsPublicKeyParameters publicKey, LmsContext context) { - LMSSignature S = (LMSSignature)context.Signature; + LmsSignature S = (LmsSignature)context.Signature; LMSigParameters lmsParameter = S.SigParameters; int h = lmsParameter.H; byte[][] path = S.Y; - byte[] Kc = LM_OTS.LMOtsValidateSignatureCalculate(context); + byte[] Kc = LMOts.LMOtsValidateSignatureCalculate(context); // Step 4 // node_num = 2^h + q int node_num = (1 << h) + S.Q; @@ -99,8 +99,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms byte[] tmp = new byte[H.GetDigestSize()]; H.BlockUpdate(I, 0, I.Length); - LmsUtils.U32Str(node_num, H); - LmsUtils.U16Str(D_LEAF, H); + LmsUtilities.U32Str(node_num, H); + LmsUtilities.U16Str(D_LEAF, H); H.BlockUpdate(Kc, 0, Kc.Length); H.DoFinal(tmp, 0); @@ -112,8 +112,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms { // is odd H.BlockUpdate(I, 0, I.Length); - LmsUtils.U32Str(node_num / 2, H); - LmsUtils.U16Str(D_INTR, H); + LmsUtilities.U32Str(node_num / 2, H); + LmsUtilities.U16Str(D_INTR, H); H.BlockUpdate(path[i], 0, path[i].Length); H.BlockUpdate(tmp, 0, tmp.Length); H.DoFinal(tmp, 0); @@ -121,8 +121,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms else { H.BlockUpdate(I, 0, I.Length); - LmsUtils.U32Str(node_num / 2, H); - LmsUtils.U16Str(D_INTR, H); + LmsUtilities.U32Str(node_num / 2, H); + LmsUtilities.U16Str(D_INTR, H); H.BlockUpdate(tmp, 0, tmp.Length); H.BlockUpdate(path[i], 0, path[i].Length); H.DoFinal(tmp, 0); diff --git a/crypto/src/pqc/crypto/lms/LMSContext.cs b/crypto/src/pqc/crypto/lms/LMSContext.cs index 12975b637..6fcbd9413 100644 --- a/crypto/src/pqc/crypto/lms/LMSContext.cs +++ b/crypto/src/pqc/crypto/lms/LMSContext.cs @@ -4,7 +4,7 @@ using Org.BouncyCastle.Crypto; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public sealed class LMSContext + public sealed class LmsContext : IDigest { private readonly byte[] m_c; @@ -14,10 +14,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms private readonly LMOtsPublicKey m_publicKey; private readonly object m_signature; - private LMSSignedPubKey[] m_signedPubKeys; + private LmsSignedPubKey[] m_signedPubKeys; private volatile IDigest m_digest; - public LMSContext(LMOtsPrivateKey privateKey, LMSigParameters sigParams, IDigest digest, byte[] C, + public LmsContext(LMOtsPrivateKey privateKey, LMSigParameters sigParams, IDigest digest, byte[] C, byte[][] path) { m_privateKey = privateKey; @@ -29,7 +29,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms m_signature = null; } - public LMSContext(LMOtsPublicKey publicKey, object signature, IDigest digest) + public LmsContext(LMOtsPublicKey publicKey, object signature, IDigest digest) { m_publicKey = publicKey; m_signature = signature; @@ -44,7 +44,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms public byte[] GetQ() { - byte[] Q = new byte[LM_OTS.MAX_HASH + 2]; + byte[] Q = new byte[LMOts.MAX_HASH + 2]; m_digest.DoFinal(Q, 0); m_digest = null; return Q; @@ -60,9 +60,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms public object Signature => m_signature; - internal LMSSignedPubKey[] SignedPubKeys => m_signedPubKeys; + internal LmsSignedPubKey[] SignedPubKeys => m_signedPubKeys; - internal LMSContext WithSignedPublicKeys(LMSSignedPubKey[] signedPubKeys) + internal LmsContext WithSignedPublicKeys(LmsSignedPubKey[] signedPubKeys) { m_signedPubKeys = signedPubKeys; return this; diff --git a/crypto/src/pqc/crypto/lms/LMSException.cs b/crypto/src/pqc/crypto/lms/LMSException.cs index c9c286b7f..694a370ed 100644 --- a/crypto/src/pqc/crypto/lms/LMSException.cs +++ b/crypto/src/pqc/crypto/lms/LMSException.cs @@ -4,25 +4,25 @@ using System.Runtime.Serialization; namespace Org.BouncyCastle.Pqc.Crypto.Lms { [Serializable] - public class LMSException + public class LmsException : Exception { - public LMSException() + public LmsException() : base() { } - public LMSException(string message) + public LmsException(string message) : base(message) { } - public LMSException(string message, Exception innerException) + public LmsException(string message, Exception innerException) : base(message, innerException) { } - protected LMSException(SerializationInfo info, StreamingContext context) + protected LmsException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/crypto/src/pqc/crypto/lms/LMSKeyGenerationParameters.cs b/crypto/src/pqc/crypto/lms/LMSKeyGenerationParameters.cs index dd932c17d..ed2cb8957 100644 --- a/crypto/src/pqc/crypto/lms/LMSKeyGenerationParameters.cs +++ b/crypto/src/pqc/crypto/lms/LMSKeyGenerationParameters.cs @@ -3,10 +3,10 @@ using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class LMSKeyGenerationParameters + public class LmsKeyGenerationParameters : KeyGenerationParameters { - private readonly LMSParameters m_lmsParameters; + private readonly LmsParameters m_lmsParameters; /** * Base constructor - parameters and a source of randomness. @@ -14,12 +14,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms * @param lmsParameters LMS parameter set to use. * @param random the random byte source. */ - public LMSKeyGenerationParameters(LMSParameters lmsParameters, SecureRandom random) - : base(random, LmsUtils.CalculateStrength(lmsParameters)) // TODO: need something for "strength" + public LmsKeyGenerationParameters(LmsParameters lmsParameters, SecureRandom random) + : base(random, LmsUtilities.CalculateStrength(lmsParameters)) // TODO: need something for "strength" { m_lmsParameters = lmsParameters; } - public LMSParameters LmsParameters => m_lmsParameters; + public LmsParameters LmsParameters => m_lmsParameters; } } diff --git a/crypto/src/pqc/crypto/lms/LMSKeyPairGenerator.cs b/crypto/src/pqc/crypto/lms/LMSKeyPairGenerator.cs index 9147c3fdf..e1afb00d9 100644 --- a/crypto/src/pqc/crypto/lms/LMSKeyPairGenerator.cs +++ b/crypto/src/pqc/crypto/lms/LMSKeyPairGenerator.cs @@ -3,14 +3,14 @@ using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public sealed class LMSKeyPairGenerator + public sealed class LmsKeyPairGenerator : IAsymmetricCipherKeyPairGenerator { - private LMSKeyGenerationParameters m_parameters; + private LmsKeyGenerationParameters m_parameters; public void Init(KeyGenerationParameters parameters) { - m_parameters = (LMSKeyGenerationParameters)parameters; + m_parameters = (LmsKeyGenerationParameters)parameters; } public AsymmetricCipherKeyPair GenerateKeyPair() @@ -23,7 +23,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms byte[] rootSecret = new byte[32]; source.NextBytes(rootSecret); - LMSPrivateKeyParameters privKey = LMS.GenerateKeys(m_parameters.LmsParameters.LMSigParameters, + LmsPrivateKeyParameters privKey = Lms.GenerateKeys(m_parameters.LmsParameters.LMSigParameters, m_parameters.LmsParameters.LMOtsParameters, 0, I, rootSecret); return new AsymmetricCipherKeyPair(privKey.GetPublicKey(), privKey); diff --git a/crypto/src/pqc/crypto/lms/LMSKeyParameters.cs b/crypto/src/pqc/crypto/lms/LMSKeyParameters.cs index e4b2df66d..b35ba36c4 100644 --- a/crypto/src/pqc/crypto/lms/LMSKeyParameters.cs +++ b/crypto/src/pqc/crypto/lms/LMSKeyParameters.cs @@ -3,10 +3,10 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public abstract class LMSKeyParameters + public abstract class LmsKeyParameters : AsymmetricKeyParameter, IEncodable { - protected LMSKeyParameters(bool isPrivateKey) + protected LmsKeyParameters(bool isPrivateKey) : base(isPrivateKey) { } diff --git a/crypto/src/pqc/crypto/lms/LMSParameters.cs b/crypto/src/pqc/crypto/lms/LMSParameters.cs index adffad2da..49ce2f71a 100644 --- a/crypto/src/pqc/crypto/lms/LMSParameters.cs +++ b/crypto/src/pqc/crypto/lms/LMSParameters.cs @@ -1,11 +1,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public sealed class LMSParameters + public sealed class LmsParameters { private readonly LMSigParameters m_lmSigParameters; private readonly LMOtsParameters m_lmOtsParameters; - public LMSParameters(LMSigParameters lmSigParameters, LMOtsParameters lmOtsParameters) + public LmsParameters(LMSigParameters lmSigParameters, LMOtsParameters lmOtsParameters) { m_lmSigParameters = lmSigParameters; m_lmOtsParameters = lmOtsParameters; diff --git a/crypto/src/pqc/crypto/lms/LMSPrivateKeyParameters.cs b/crypto/src/pqc/crypto/lms/LMSPrivateKeyParameters.cs index f83cdc5f4..25ca81938 100644 --- a/crypto/src/pqc/crypto/lms/LMSPrivateKeyParameters.cs +++ b/crypto/src/pqc/crypto/lms/LMSPrivateKeyParameters.cs @@ -9,13 +9,13 @@ using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class LMSPrivateKeyParameters - : LMSKeyParameters, ILMSContextBasedSigner + public class LmsPrivateKeyParameters + : LmsKeyParameters, ILmsContextBasedSigner { private static CacheKey T1 = new CacheKey(1); private static CacheKey[] internedKeys = new CacheKey[129]; - static LMSPrivateKeyParameters() + static LmsPrivateKeyParameters() { internedKeys[1] = T1; for (int i = 2; i < internedKeys.Length; i++) @@ -39,10 +39,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms // These are not final because they can be generated. // They also do not need to be persisted. // - private LMSPublicKeyParameters publicKey; + private LmsPublicKeyParameters publicKey; - public LMSPrivateKeyParameters(LMSigParameters lmsParameter, LMOtsParameters otsParameters, int q, byte[] I, int maxQ, byte[] masterSecret) + public LmsPrivateKeyParameters(LMSigParameters lmsParameter, LMOtsParameters otsParameters, int q, byte[] I, + int maxQ, byte[] masterSecret) : base(true) { this.parameters = lmsParameter; @@ -56,7 +57,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms this.tDigest = DigestUtilities.GetDigest(lmsParameter.DigestOid); } - private LMSPrivateKeyParameters(LMSPrivateKeyParameters parent, int q, int maxQ) + private LmsPrivateKeyParameters(LmsPrivateKeyParameters parent, int q, int maxQ) : base(true) { this.parameters = parent.parameters; @@ -71,92 +72,53 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms this.publicKey = parent.publicKey; } - public static LMSPrivateKeyParameters GetInstance(byte[] privEnc, byte[] pubEnc) + public static LmsPrivateKeyParameters GetInstance(byte[] privEnc, byte[] pubEnc) { - LMSPrivateKeyParameters pKey = GetInstance(privEnc); + LmsPrivateKeyParameters pKey = GetInstance(privEnc); - pKey.publicKey = LMSPublicKeyParameters.GetInstance(pubEnc); + pKey.publicKey = LmsPublicKeyParameters.GetInstance(pubEnc); return pKey; } - public static LMSPrivateKeyParameters GetInstance(Object src) + public static LmsPrivateKeyParameters GetInstance(object src) { - if (src is LMSPrivateKeyParameters) + if (src is LmsPrivateKeyParameters lmsPrivateKeyParameters) { - return (LMSPrivateKeyParameters)src; + return lmsPrivateKeyParameters; } - //TODO - else if (src is BinaryReader) + else if (src is BinaryReader binaryReader) { - BinaryReader dIn = (BinaryReader)src; - - /* - .u32str(0) // version - .u32str(parameters.getType()) // type - .u32str(otsParameters.getType()) // ots type - .bytes(I) // I at 16 bytes - .u32str(q) // q - .u32str(maxQ) // maximum q - .u32str(masterSecret.length) // length of master secret. - .bytes(masterSecret) // the master secret - .build(); - */ - - - if (dIn.ReadInt32() != 0) // todo check endienness - { - throw new Exception("expected version 0 lms private key"); - } - - // todo check endienness - byte[] data = ((BinaryReader) src).ReadBytes(4); - Array.Reverse(data); - int paramType = BitConverter.ToInt32(data, 0); - LMSigParameters parameter = LMSigParameters.GetParametersByID(paramType); - - data = ((BinaryReader) src).ReadBytes(4); - Array.Reverse(data); - paramType = BitConverter.ToInt32(data, 0); - - LMOtsParameters otsParameter = LMOtsParameters.GetParametersByID(paramType); - byte[] I = new byte[16]; - dIn.Read(I, 0, I.Length); - - - data = ((BinaryReader) src).ReadBytes(4); - Array.Reverse(data); - int q = BitConverter.ToInt32(data, 0); - - data = ((BinaryReader) src).ReadBytes(4); - Array.Reverse(data); - int maxQ = BitConverter.ToInt32(data, 0); - - data = ((BinaryReader) src).ReadBytes(4); - Array.Reverse(data); - int l = BitConverter.ToInt32(data, 0); - - + int version = BinaryReaders.ReadInt32BigEndian(binaryReader); + if (version != 0) + throw new Exception("unknown version for LMS private key"); + + int sigParamType = BinaryReaders.ReadInt32BigEndian(binaryReader); + LMSigParameters sigParameter = LMSigParameters.GetParametersByID(sigParamType); + + int otsParamType = BinaryReaders.ReadInt32BigEndian(binaryReader); + LMOtsParameters otsParameter = LMOtsParameters.GetParametersByID(otsParamType); + + byte[] I = BinaryReaders.ReadBytesFully(binaryReader, 16); + + int q = BinaryReaders.ReadInt32BigEndian(binaryReader); + + int maxQ = BinaryReaders.ReadInt32BigEndian(binaryReader); + + int l = BinaryReaders.ReadInt32BigEndian(binaryReader); if (l < 0) - { throw new Exception("secret length less than zero"); - } - if (l > dIn.BaseStream.Length) - { - throw new IOException("secret length exceeded " + dIn.BaseStream.Length); - } - byte[] masterSecret = new byte[l]; - dIn.Read(masterSecret, 0, masterSecret.Length); - - return new LMSPrivateKeyParameters(parameter, otsParameter, q, I, maxQ, masterSecret); - + + byte[] masterSecret = BinaryReaders.ReadBytesFully(binaryReader, l); + + return new LmsPrivateKeyParameters(sigParameter, otsParameter, q, I, maxQ, masterSecret); } - else if (src is byte[]) + else if (src is byte[] bytes) { BinaryReader input = null; try // 1.5 / 1.6 compatibility { - input = new BinaryReader(new MemoryStream((byte[])src, false)); + input = new BinaryReader(new MemoryStream(bytes, false)); return GetInstance(input); } finally @@ -167,9 +129,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms } } } - else if (src is MemoryStream) + else if (src is MemoryStream memoryStream) { - return GetInstance(Streams.ReadAll((Stream)src)); + return GetInstance(Streams.ReadAll(memoryStream)); } throw new ArgumentException($"cannot parse {src}"); @@ -181,9 +143,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms lock (this) { if (q >= maxQ) - { throw new Exception("ots private keys expired"); - } + return new LMOtsPrivateKey(otsParameters, I, q, masterSecret); } } @@ -205,7 +166,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms q++; } - public LMSContext GenerateLmsContext() + public LmsContext GenerateLmsContext() { // Step 1. LMSigParameters lmsParameter = this.GetSigParameters(); @@ -230,11 +191,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return otsPk.GetSignatureContext(this.GetSigParameters(), path); } - public byte[] GenerateSignature(LMSContext context) + public byte[] GenerateSignature(LmsContext context) { try { - return LMS.GenerateSign(context).GetEncoded(); + return Lms.GenerateSign(context).GetEncoded(); } catch (IOException e) { @@ -247,9 +208,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms lock (this) { if (q >= maxQ) - { throw new Exception("ots private key exhausted"); - } + LMOtsPrivateKey otsPrivateKey = new LMOtsPrivateKey(otsParameters, I, q, masterSecret); IncIndex(); return otsPrivateKey; @@ -265,15 +225,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms * @param usageCount the number of usages the key should have. * @return a key based on the current key that can be used usageCount times. */ - public LMSPrivateKeyParameters ExtractKeyShard(int usageCount) + public LmsPrivateKeyParameters ExtractKeyShard(int usageCount) { lock (this) { if (q + usageCount >= maxQ) - { throw new ArgumentException("usageCount exceeds usages remaining"); - } - LMSPrivateKeyParameters keyParameters = new LMSPrivateKeyParameters(this, q, q + usageCount); + + LmsPrivateKeyParameters keyParameters = new LmsPrivateKeyParameters(this, q, q + usageCount); q += usageCount; return keyParameters; @@ -305,13 +264,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return maxQ - q; } - public virtual LMSPublicKeyParameters GetPublicKey() + public virtual LmsPublicKeyParameters GetPublicKey() { lock (this) { if (publicKey == null) { - publicKey = new LMSPublicKeyParameters(parameters, otsParameters, this.FindT(T1), I); + publicKey = new LmsPublicKeyParameters(parameters, otsParameters, this.FindT(T1), I); } return publicKey; } @@ -354,17 +313,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms if (r >= twoToh) { - LmsUtils.ByteArray(this.GetI(), tDigest); - LmsUtils.U32Str(r, tDigest); - LmsUtils.U16Str(LMS.D_LEAF, tDigest); + LmsUtilities.ByteArray(this.GetI(), tDigest); + LmsUtilities.U32Str(r, tDigest); + LmsUtilities.U16Str(Lms.D_LEAF, tDigest); // // These can be pre generated at the time of key generation and held within the private key. // However it will cost memory to have them stick around. // - byte[] K = LM_OTS.LmsOtsGeneratePublicKey(this.GetOtsParameters(), this.GetI(), (r - twoToh), + byte[] K = LMOts.LmsOtsGeneratePublicKey(this.GetOtsParameters(), this.GetI(), (r - twoToh), this.GetMasterSecret()); - LmsUtils.ByteArray(K, tDigest); + LmsUtilities.ByteArray(K, tDigest); T = new byte[tDigest.GetDigestSize()]; tDigest.DoFinal(T, 0); return T; @@ -373,11 +332,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms byte[] t2r = FindT(2 * r); byte[] t2rPlus1 = FindT((2 * r + 1)); - LmsUtils.ByteArray(this.GetI(), tDigest); - LmsUtils.U32Str(r, tDigest); - LmsUtils.U16Str(LMS.D_INTR, tDigest); - LmsUtils.ByteArray(t2r, tDigest); - LmsUtils.ByteArray(t2rPlus1, tDigest); + LmsUtilities.ByteArray(this.GetI(), tDigest); + LmsUtilities.U32Str(r, tDigest); + LmsUtilities.U16Str(Lms.D_INTR, tDigest); + LmsUtilities.ByteArray(t2r, tDigest); + LmsUtilities.ByteArray(t2rPlus1, tDigest); T = new byte[tDigest.GetDigestSize()]; tDigest.DoFinal(T, 0); @@ -395,7 +354,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return false; } - LMSPrivateKeyParameters that = (LMSPrivateKeyParameters)o; + LmsPrivateKeyParameters that = (LmsPrivateKeyParameters)o; if (q != that.q) { diff --git a/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs b/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs index 1bf857f60..fa12b47c3 100644 --- a/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs +++ b/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs @@ -6,15 +6,15 @@ using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class LMSPublicKeyParameters - : LMSKeyParameters, ILMSContextBasedVerifier + public class LmsPublicKeyParameters + : LmsKeyParameters, ILmsContextBasedVerifier { private LMSigParameters parameterSet; private LMOtsParameters lmOtsType; private byte[] I; private byte[] T1; - public LMSPublicKeyParameters(LMSigParameters parameterSet, LMOtsParameters lmOtsType, byte[] T1, byte[] I) + public LmsPublicKeyParameters(LMSigParameters parameterSet, LMOtsParameters lmOtsType, byte[] T1, byte[] I) : base(false) { this.parameterSet = parameterSet; @@ -23,33 +23,27 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms this.T1 = Arrays.Clone(T1); } - public static LMSPublicKeyParameters GetInstance(Object src) + public static LmsPublicKeyParameters GetInstance(object src) { - if (src is LMSPublicKeyParameters lmsPublicKeyParameters) + if (src is LmsPublicKeyParameters lmsPublicKeyParameters) { return lmsPublicKeyParameters; } - // todo - else if (src is BinaryReader binaryReader) - { - byte[] data = binaryReader.ReadBytes(4); - Array.Reverse(data); - int pubType = BitConverter.ToInt32(data, 0); - LMSigParameters lmsParameter = LMSigParameters.GetParametersByID(pubType); - - data = binaryReader.ReadBytes(4); - Array.Reverse(data); - int index = BitConverter.ToInt32(data, 0); - LMOtsParameters ostTypeCode = LMOtsParameters.GetParametersByID(index); - - byte[] I = new byte[16]; - binaryReader.Read(I, 0, I.Length);//change to readbytes? - - byte[] T1 = new byte[lmsParameter.M]; - binaryReader.Read(T1, 0, T1.Length); - return new LMSPublicKeyParameters(lmsParameter, ostTypeCode, T1, I); - } - else if (src is byte[] bytes) + else if (src is BinaryReader binaryReader) + { + int pubType = BinaryReaders.ReadInt32BigEndian(binaryReader); + LMSigParameters lmsParameter = LMSigParameters.GetParametersByID(pubType); + + int index = BinaryReaders.ReadInt32BigEndian(binaryReader); + LMOtsParameters ostTypeCode = LMOtsParameters.GetParametersByID(index); + + byte[] I = BinaryReaders.ReadBytesFully(binaryReader, 16); + + byte[] T1 = BinaryReaders.ReadBytesFully(binaryReader, lmsParameter.M); + + return new LmsPublicKeyParameters(lmsParameter, ostTypeCode, T1, I); + } + else if (src is byte[] bytes) { BinaryReader input = null; try // 1.5 / 1.6 compatibility @@ -87,9 +81,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return lmOtsType; } - public LMSParameters GetLmsParameters() + public LmsParameters GetLmsParameters() { - return new LMSParameters(this.GetSigParameters(), this.GetOtsParameters()); + return new LmsParameters(this.GetSigParameters(), this.GetOtsParameters()); } public byte[] GetT1() @@ -123,7 +117,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return false; } - LMSPublicKeyParameters publicKey = (LMSPublicKeyParameters)o; + LmsPublicKeyParameters publicKey = (LmsPublicKeyParameters)o; if (!parameterSet.Equals(publicKey.parameterSet)) { @@ -159,11 +153,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms .Build(); } - public LMSContext GenerateLmsContext(byte[] signature) + public LmsContext GenerateLmsContext(byte[] signature) { try { - return GenerateOtsContext(LMSSignature.GetInstance(signature)); + return GenerateOtsContext(LmsSignature.GetInstance(signature)); } catch (IOException e) { @@ -171,7 +165,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms } } - internal LMSContext GenerateOtsContext(LMSSignature S) + internal LmsContext GenerateOtsContext(LmsSignature S) { int ots_typecode = GetOtsParameters().ID; if (S.OtsSignature.ParamType.ID != ots_typecode) @@ -184,9 +178,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms .CreateOtsContext(S); } - public bool Verify(LMSContext context) + public bool Verify(LmsContext context) { - return LMS.VerifySignature(this, context); + return Lms.VerifySignature(this, context); } } } diff --git a/crypto/src/pqc/crypto/lms/LMSSignature.cs b/crypto/src/pqc/crypto/lms/LMSSignature.cs index 48026e2f6..f5d355297 100644 --- a/crypto/src/pqc/crypto/lms/LMSSignature.cs +++ b/crypto/src/pqc/crypto/lms/LMSSignature.cs @@ -6,7 +6,7 @@ using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class LMSSignature + public class LmsSignature : IEncodable { private int q; @@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms private LMSigParameters parameter; private byte[][] y; - public LMSSignature(int q, LMOtsSignature otsSignature, LMSigParameters parameter, byte[][] y) + public LmsSignature(int q, LMOtsSignature otsSignature, LMSigParameters parameter, byte[][] y) { this.q = q; this.otsSignature = otsSignature; @@ -22,23 +22,19 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms this.y = y; } - public static LMSSignature GetInstance(object src) + public static LmsSignature GetInstance(object src) { - if (src is LMSSignature lmsSignature) + if (src is LmsSignature lmsSignature) { return lmsSignature; } else if (src is BinaryReader binaryReader) { - byte[] data = binaryReader.ReadBytes(4); - Array.Reverse(data); - int q = BitConverter.ToInt32(data, 0); - + int q = BinaryReaders.ReadInt32BigEndian(binaryReader); + LMOtsSignature otsSignature = LMOtsSignature.GetInstance(src); - data = binaryReader.ReadBytes(4); - Array.Reverse(data); - int index = BitConverter.ToInt32(data, 0); + int index = BinaryReaders.ReadInt32BigEndian(binaryReader); LMSigParameters type = LMSigParameters.GetParametersByID(index); byte[][] path = new byte[type.H][]; @@ -47,8 +43,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms path[h] = new byte[type.M]; binaryReader.Read(path[h], 0, path[h].Length); } - - return new LMSSignature(q, otsSignature, type, path); + + return new LmsSignature(q, otsSignature, type, path); } else if (src is byte[] bytes) { @@ -81,7 +77,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return false; } - LMSSignature that = (LMSSignature)o; + LmsSignature that = (LmsSignature)o; if (q != that.q) { diff --git a/crypto/src/pqc/crypto/lms/LMSSignedPubKey.cs b/crypto/src/pqc/crypto/lms/LMSSignedPubKey.cs index 024ee5f4c..5e07c9c93 100644 --- a/crypto/src/pqc/crypto/lms/LMSSignedPubKey.cs +++ b/crypto/src/pqc/crypto/lms/LMSSignedPubKey.cs @@ -4,25 +4,25 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class LMSSignedPubKey + public class LmsSignedPubKey : IEncodable { - private LMSSignature signature; - private LMSPublicKeyParameters publicKey; + private LmsSignature signature; + private LmsPublicKeyParameters publicKey; - public LMSSignedPubKey(LMSSignature signature, LMSPublicKeyParameters publicKey) + public LmsSignedPubKey(LmsSignature signature, LmsPublicKeyParameters publicKey) { this.signature = signature; this.publicKey = publicKey; } - public LMSSignature GetSignature() + public LmsSignature GetSignature() { return signature; } - public LMSPublicKeyParameters GetPublicKey() + public LmsPublicKeyParameters GetPublicKey() { return publicKey; } @@ -38,7 +38,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms return false; } - LMSSignedPubKey that = (LMSSignedPubKey)o; + LmsSignedPubKey that = (LmsSignedPubKey)o; if (signature != null ? !signature.Equals(that.signature) : that.signature != null) { diff --git a/crypto/src/pqc/crypto/lms/LMSSigner.cs b/crypto/src/pqc/crypto/lms/LMSSigner.cs index 05824307a..edbfd7330 100644 --- a/crypto/src/pqc/crypto/lms/LMSSigner.cs +++ b/crypto/src/pqc/crypto/lms/LMSSigner.cs @@ -5,21 +5,21 @@ using Org.BouncyCastle.Crypto; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public sealed class LMSSigner + public sealed class LmsSigner : IMessageSigner { - private LMSPrivateKeyParameters m_privateKey; - private LMSPublicKeyParameters m_publicKey; + private LmsPrivateKeyParameters m_privateKey; + private LmsPublicKeyParameters m_publicKey; public void Init(bool forSigning, ICipherParameters param) { if (forSigning) { - m_privateKey = (LMSPrivateKeyParameters)param; + m_privateKey = (LmsPrivateKeyParameters)param; } else { - m_publicKey = (LMSPublicKeyParameters)param; + m_publicKey = (LmsPublicKeyParameters)param; } } @@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms { try { - return LMS.GenerateSign(m_privateKey, message).GetEncoded(); + return Lms.GenerateSign(m_privateKey, message).GetEncoded(); } catch (IOException e) { @@ -39,7 +39,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms { try { - return LMS.VerifySignature(m_publicKey, LMSSignature.GetInstance(signature), message); + return Lms.VerifySignature(m_publicKey, LmsSignature.GetInstance(signature), message); } catch (IOException e) { diff --git a/crypto/src/pqc/crypto/lms/LM_OTS.cs b/crypto/src/pqc/crypto/lms/LM_OTS.cs index b9634c652..c3cd3da90 100644 --- a/crypto/src/pqc/crypto/lms/LM_OTS.cs +++ b/crypto/src/pqc/crypto/lms/LM_OTS.cs @@ -7,7 +7,7 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class LM_OTS + public static class LMOts { private static ushort D_PBLC = 0x8080; private static int ITER_K = 20; @@ -113,9 +113,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms if (!preHashed) { - LMSContext qCtx = privateKey.GetSignatureContext(sigParams, path); + LmsContext qCtx = privateKey.GetSignatureContext(sigParams, path); - LmsUtils.ByteArray(message, 0, message.Length, qCtx); + LmsUtilities.ByteArray(message, 0, message.Length, qCtx); C = qCtx.C; Q = qCtx.GetQ(); @@ -175,7 +175,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms bool prehashed) { if (!signature.ParamType.Equals(publicKey.Parameters)) // todo check - throw new LMSException("public key and signature ots types do not match"); + throw new LmsException("public key and signature ots types do not match"); return Arrays.AreEqual(LMOtsValidateSignatureCalculate(publicKey, signature, message), publicKey.K); } @@ -183,22 +183,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms public static byte[] LMOtsValidateSignatureCalculate(LMOtsPublicKey publicKey, LMOtsSignature signature, byte[] message) { - LMSContext ctx = publicKey.CreateOtsContext(signature); + LmsContext ctx = publicKey.CreateOtsContext(signature); - LmsUtils.ByteArray(message, ctx); + LmsUtilities.ByteArray(message, ctx); return LMOtsValidateSignatureCalculate(ctx); } - public static byte[] LMOtsValidateSignatureCalculate(LMSContext context) + public static byte[] LMOtsValidateSignatureCalculate(LmsContext context) { LMOtsPublicKey publicKey = context.PublicKey; LMOtsParameters parameter = publicKey.Parameters; object sig = context.Signature; LMOtsSignature signature; - if (sig is LMSSignature) + if (sig is LmsSignature) { - signature = ((LMSSignature)sig).OtsSignature; + signature = ((LmsSignature)sig).OtsSignature; } else { @@ -218,9 +218,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms int q = publicKey.Q; IDigest finalContext = DigestUtilities.GetDigest(parameter.DigestOid); - LmsUtils.ByteArray(I, finalContext); - LmsUtils.U32Str(q, finalContext); - LmsUtils.U16Str(D_PBLC, finalContext); + LmsUtilities.ByteArray(I, finalContext); + LmsUtilities.U32Str(q, finalContext); + LmsUtilities.U16Str(D_PBLC, finalContext); byte[] tmp = Composer.Compose() .Bytes(I) diff --git a/crypto/src/pqc/crypto/lms/LmsUtils.cs b/crypto/src/pqc/crypto/lms/LmsUtils.cs index 3b08b009d..da3f457d2 100644 --- a/crypto/src/pqc/crypto/lms/LmsUtils.cs +++ b/crypto/src/pqc/crypto/lms/LmsUtils.cs @@ -4,7 +4,7 @@ using Org.BouncyCastle.Crypto; namespace Org.BouncyCastle.Pqc.Crypto.Lms { - public class LmsUtils + public static class LmsUtilities { public static void U32Str(int n, IDigest d) { @@ -30,7 +30,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms digest.BlockUpdate(array, start, len); } - public static int CalculateStrength(LMSParameters lmsParameters) + public static int CalculateStrength(LmsParameters lmsParameters) { if (lmsParameters == null) throw new ArgumentNullException(nameof(lmsParameters)); diff --git a/crypto/src/pqc/crypto/saber/Poly.cs b/crypto/src/pqc/crypto/saber/Poly.cs index 021f1d0e3..1a7312201 100644 --- a/crypto/src/pqc/crypto/saber/Poly.cs +++ b/crypto/src/pqc/crypto/saber/Poly.cs @@ -1,65 +1,70 @@ - using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; namespace Org.BouncyCastle.Pqc.Crypto.Saber { - - class Poly + internal class Poly { - private static int KARATSUBA_N = 64; - - private static int SCHB_N = 16; - - private int N_RES; - private int N_SB; - private int N_SB_RES; - private int SABER_N; - private int SABER_L; + private const int KARATSUBA_N = 64; - private SABEREngine engine; - private Utils utils; + //private readonly int N_RES; + private readonly int N_SB; + private readonly int N_SB_RES; + private readonly int SABER_N; + private readonly int SABER_L; + private readonly SaberEngine engine; + private readonly SaberUtilities utils; - public Poly(SABEREngine engine) + public Poly(SaberEngine engine) { this.engine = engine; - this.SABER_L = engine.getSABER_L(); - this.SABER_N = engine.getSABER_N(); - this.N_RES = (SABER_N << 1); - this.N_SB = (SABER_N >> 2); - this.N_SB_RES = (2 * N_SB - 1); - this.utils = engine.GetUtils(); + this.SABER_L = engine.L; + this.SABER_N = engine.N; + //this.N_RES = SABER_N << 1; + this.N_SB = SABER_N >> 2; + this.N_SB_RES = 2 * N_SB - 1; + this.utils = engine.Utilities; } public void GenMatrix(short[][][] A, byte[] seed) { - byte[] buf = new byte[SABER_L * engine.getSABER_POLYVECBYTES()]; + byte[] buf = new byte[SABER_L * engine.PolyVecBytes]; int i; - IXof digest = new ShakeDigest(128); - digest.BlockUpdate(seed, 0, engine.getSABER_SEEDBYTES()); - digest.OutputFinal(buf, 0, buf.Length); + engine.Symmetric.Prf(buf, seed, engine.SeedBytes, buf.Length); + for (i = 0; i < SABER_L; i++) { - utils.BS2POLVECq(buf, i * engine.getSABER_POLYVECBYTES(), A[i]); + utils.BS2POLVECq(buf, i * engine.PolyVecBytes, A[i]); } } public void GenSecret(short[][] s, byte[] seed) { - byte[] buf = new byte[SABER_L * engine.getSABER_POLYCOINBYTES()]; - int i; - IXof digest = new ShakeDigest(128); - digest.BlockUpdate(seed, 0, engine.getSABER_NOISE_SEEDBYTES()); - digest.OutputFinal(buf, 0, buf.Length); + byte[] buf = new byte[SABER_L * engine.PolyCoinBytes]; - for (i = 0; i < SABER_L; i++) + engine.Symmetric.Prf(buf, seed, engine.NoiseSeedBytes, buf.Length); + + + for (int i = 0; i < SABER_L; i++) { - Cbd(s[i], buf, i * engine.getSABER_POLYCOINBYTES()); + if (!engine.UsingEffectiveMasking) + { + Cbd(s[i], buf, i * engine.PolyCoinBytes); + } + else + { + for(int j = 0; j<SABER_N/4; j++) + { + s[i][4*j] = (short) ((((buf[j + i * engine.PolyCoinBytes]) & 0x03) ^ 2) - 2); + s[i][4*j+1] = (short) ((((buf[j + i * engine.PolyCoinBytes] >> 2) & 0x03) ^ 2) - 2); + s[i][4*j+2] = (short) ((((buf[j + i * engine.PolyCoinBytes] >> 4) & 0x03) ^ 2) - 2); + s[i][4*j+3] = (short) ((((buf[j + i * engine.PolyCoinBytes] >> 6) & 0x03) ^ 2) - 2); + } + } } - } private long LoadLittleEndian(byte[] x, int offset, int bytes) @@ -78,7 +83,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber { int[] a = new int[4], b = new int[4]; int i, j; - if (engine.getSABER_MU() == 6) + if (engine.MU == 6) { int t, d; for (i = 0; i < SABER_N / 4; i++) @@ -103,7 +108,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber s[4 * i + 3] = (short) (a[3] - b[3]); } } - else if (engine.getSABER_MU() == 8) + else if (engine.MU == 8) { int t, d; for (i = 0; i < SABER_N / 4; i++) @@ -129,7 +134,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber s[4 * i + 3] = (short) (a[3] - b[3]); } } - else if (engine.getSABER_MU() == 10) + else if (engine.MU == 10) { long t, d; for (i = 0; i < SABER_N / 4; i++) @@ -435,4 +440,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/saber/SABEREngine.cs b/crypto/src/pqc/crypto/saber/SABEREngine.cs index a7c8d3ff9..e57c0a23f 100644 --- a/crypto/src/pqc/crypto/saber/SABEREngine.cs +++ b/crypto/src/pqc/crypto/saber/SABEREngine.cs @@ -1,5 +1,5 @@ - using System; + using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Security; @@ -7,103 +7,75 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Saber { - internal class SABEREngine + internal sealed class SaberEngine { // constant parameters - public static int SABER_EQ = 13; - public static int SABER_EP = 10; - public static int SABER_N = 256; - - private static int SABER_SEEDBYTES = 32; - private static int SABER_NOISE_SEEDBYTES = 32; - private static int SABER_KEYBYTES = 32; - private static int SABER_HASHBYTES = 32; + internal const int SABER_EP = 10; + internal const int SABER_N = 256; + private const int SABER_SEEDBYTES = 32; + private const int SABER_NOISE_SEEDBYTES = 32; + private const int SABER_KEYBYTES = 32; + private const int SABER_HASHBYTES = 32; // parameters for SABER{n} - private int SABER_L; - private int SABER_MU; - private int SABER_ET; - - private int SABER_POLYCOINBYTES; - private int SABER_POLYBYTES; - private int SABER_POLYVECBYTES; - private int SABER_POLYCOMPRESSEDBYTES; - private int SABER_POLYVECCOMPRESSEDBYTES; - private int SABER_SCALEBYTES_KEM; - private int SABER_INDCPA_PUBLICKEYBYTES; - private int SABER_INDCPA_SECRETKEYBYTES; - private int SABER_PUBLICKEYBYTES; - private int SABER_SECRETKEYBYTES; - private int SABER_BYTES_CCA_DEC; - private int defaultKeySize; + private readonly int SABER_L; + private readonly int SABER_MU; + private readonly int SABER_ET; + + private readonly int SABER_POLYCOINBYTES; + private readonly int SABER_EQ; + private readonly int SABER_POLYBYTES; + private readonly int SABER_POLYVECBYTES; + private readonly int SABER_POLYCOMPRESSEDBYTES; + private readonly int SABER_POLYVECCOMPRESSEDBYTES; + private readonly int SABER_SCALEBYTES_KEM; + private readonly int SABER_INDCPA_PUBLICKEYBYTES; + private readonly int SABER_INDCPA_SECRETKEYBYTES; + private readonly int SABER_PUBLICKEYBYTES; + private readonly int SABER_SECRETKEYBYTES; + private readonly int SABER_BYTES_CCA_DEC; + private readonly int defaultKeySize; // private int h1; private int h2; - private Utils utils; + private Symmetric symmetric; + private SaberUtilities utils; private Poly poly; - public int getSABER_N() - { - return SABER_N; - } + private readonly bool usingAes; + private readonly bool usingEffectiveMasking; - public int getSABER_EP() - { - return SABER_EP; - } + public bool UsingAes => usingAes; + public bool UsingEffectiveMasking => usingEffectiveMasking; + public Symmetric Symmetric => symmetric; + + public int EQ => SABER_EQ; + public int N => SABER_N; - public int getSABER_KEYBYTES() - { - return SABER_KEYBYTES; - } + public int EP => SABER_EP; - public int getSABER_L() - { - return SABER_L; - } + public int KeyBytes => SABER_KEYBYTES; - public int getSABER_ET() - { - return SABER_ET; - } + public int L => SABER_L; - public int getSABER_POLYBYTES() - { - return SABER_POLYBYTES; - } + public int ET => SABER_ET; - public int getSABER_POLYVECBYTES() - { - return SABER_POLYVECBYTES; - } + public int PolyBytes => SABER_POLYBYTES; - public int getSABER_SEEDBYTES() - { - return SABER_SEEDBYTES; - } + public int PolyVecBytes => SABER_POLYVECBYTES; - public int getSABER_POLYCOINBYTES() - { - return SABER_POLYCOINBYTES; - } + public int SeedBytes => SABER_SEEDBYTES; - public int getSABER_NOISE_SEEDBYTES() - { - return SABER_NOISE_SEEDBYTES; - } + public int PolyCoinBytes => SABER_POLYCOINBYTES; - public int getSABER_MU() - { - return SABER_MU; - } + public int NoiseSeedBytes => SABER_NOISE_SEEDBYTES; - public Utils GetUtils() - { - return utils; - } + public int MU => SABER_MU; + + public SaberUtilities Utilities => utils; public int GetSessionKeySize() { @@ -126,10 +98,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber return SABER_SECRETKEYBYTES; } - public SABEREngine(int l, int defaultKeySize) + internal SaberEngine(int l, int defaultKeySize, bool usingAes, bool usingEffectiveMasking) { this.defaultKeySize = defaultKeySize; - + this.usingAes = usingAes; + this.usingEffectiveMasking = usingEffectiveMasking; this.SABER_L = l; if (l == 2) { @@ -146,8 +119,25 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber this.SABER_MU = 6; this.SABER_ET = 6; } + if(usingAes) + { + symmetric = new Symmetric.AesSymmetric(); + } + else + { + symmetric = new Symmetric.ShakeSymmetric(); + } - this.SABER_POLYCOINBYTES = (SABER_MU * SABER_N / 8); + if(usingEffectiveMasking) + { + this.SABER_EQ = 12; + this.SABER_POLYCOINBYTES = (2 * SABER_N / 8); + } + else + { + this.SABER_EQ = 13; + this.SABER_POLYCOINBYTES = (SABER_MU * SABER_N / 8); + } this.SABER_POLYBYTES = (SABER_EQ * SABER_N / 8); this.SABER_POLYVECBYTES = (SABER_L * SABER_POLYBYTES); this.SABER_POLYCOMPRESSEDBYTES = (SABER_EP * SABER_N / 8); @@ -162,7 +152,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber this.h1 = (1 << (SABER_EQ - SABER_EP - 1)); this.h2 = ((1 << (SABER_EP - 2)) - (1 << (SABER_EP - SABER_ET - 1)) + (1 << (SABER_EQ - SABER_EP - 1))); - utils = new Utils(this); + utils = new SaberUtilities(this); poly = new Poly(this); } @@ -202,9 +192,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber random.NextBytes(seed_A); - IXof digest = new ShakeDigest(128); - digest.BlockUpdate(seed_A, 0, SABER_SEEDBYTES); - digest.OutputFinal(seed_A, 0, SABER_SEEDBYTES); + symmetric.Prf(seed_A, seed_A, SABER_SEEDBYTES, SABER_SEEDBYTES); random.NextBytes(seed_s); @@ -233,13 +221,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber int i; indcpa_kem_keypair(pk, sk, random); // sk[0:SABER_INDCPA_SECRETKEYBYTES-1] <-- sk for (i = 0; i < SABER_INDCPA_PUBLICKEYBYTES; i++) + { sk[i + SABER_INDCPA_SECRETKEYBYTES] = pk[i]; // sk[SABER_INDCPA_SECRETKEYBYTES:SABER_INDCPA_SECRETKEYBYTES+SABER_INDCPA_SECRETKEYBYTES-1] <-- pk - + } // Then hash(pk) is appended. - Sha3Digest digest = new Sha3Digest(256); - digest.BlockUpdate(pk, 0, SABER_INDCPA_PUBLICKEYBYTES); - digest.DoFinal(sk, SABER_SECRETKEYBYTES - 64); + symmetric.Hash_h(sk, pk, SABER_SECRETKEYBYTES - 64); // Remaining part of sk contains a pseudo-random number. byte[] nonce = new byte[SABER_KEYBYTES]; @@ -289,7 +276,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber } short[] mp = new short[SABER_N]; - ; short[] vp = new short[SABER_N]; byte[] seed_A = Arrays.CopyOfRange(pk, SABER_POLYVECCOMPRESSEDBYTES, pk.Length); @@ -327,35 +313,30 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber byte[] nonce = new byte[32]; random.NextBytes(nonce); - Sha3Digest digest_256 = new Sha3Digest(256); - Sha3Digest digest_512 = new Sha3Digest(512); + // BUF[0:31] <-- random message (will be used as the key for client) Note: hash doesnot release system RNG output - digest_256.BlockUpdate(nonce, 0, 32); - digest_256.DoFinal(nonce, 0); + symmetric.Hash_h(nonce, nonce, 0); + Array.Copy(nonce, 0, buf, 0, 32); // BUF[32:63] <-- Hash(public key); Multitarget countermeasure for coins + contributory KEM - digest_256.BlockUpdate(pk, 0, SABER_INDCPA_PUBLICKEYBYTES); - digest_256.DoFinal(buf, 32); + symmetric.Hash_h(buf, pk, 32); // kr[0:63] <-- Hash(buf[0:63]); - digest_512.BlockUpdate(buf, 0, 64); - digest_512.DoFinal(kr, 0); + symmetric.Hash_g(kr, buf); // K^ <-- kr[0:31] // noiseseed (r) <-- kr[32:63]; // buf[0:31] contains message; kr[32:63] contains randomness r; indcpa_kem_enc(buf, Arrays.CopyOfRange(kr, 32, kr.Length), pk, c); - digest_256.BlockUpdate(c, 0, SABER_BYTES_CCA_DEC); - digest_256.DoFinal(kr, 32); + symmetric.Hash_h(kr, c, 32); // hash concatenation of pre-k and h(c) to k //todo support 128 and 192 bit keys byte[] temp_k = new byte[32]; - digest_256.BlockUpdate(kr, 0, 64); - digest_256.DoFinal(temp_k, 0); + symmetric.Hash_h(temp_k, kr, 0); Array.Copy(temp_k, 0, k, 0, defaultKeySize / 8); @@ -407,14 +388,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber // Multitarget countermeasure for coins + contributory KEM for (i = 0; i < 32; i++) // Save hash by storing h(pk) in sk + { buf[32 + i] = sk[SABER_SECRETKEYBYTES - 64 + i]; + } - Sha3Digest digest_256 = new Sha3Digest(256); - Sha3Digest digest_512 = new Sha3Digest(512); - - digest_512.BlockUpdate(buf, 0, 64); - digest_512.DoFinal(kr, 0); + symmetric.Hash_g(kr, buf); indcpa_kem_enc(buf, Arrays.CopyOfRange(kr, 32, kr.Length), pk, cmp); @@ -422,16 +401,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber // overwrite coins in kr with h(c) - digest_256.BlockUpdate(c, 0, SABER_BYTES_CCA_DEC); - digest_256.DoFinal(kr, 32); - + symmetric.Hash_h(kr, c, 32); + cmov(kr, sk, SABER_SECRETKEYBYTES - SABER_KEYBYTES, SABER_KEYBYTES, (byte) fail); // hash concatenation of pre-k and h(c) to k //todo support 128 and 192 bit keys byte[] temp_k = new byte[32]; - digest_256.BlockUpdate(kr, 0, 64); - digest_256.DoFinal(temp_k, 0); + symmetric.Hash_h(temp_k, kr, 0); Array.Copy(temp_k, 0, k, 0, defaultKeySize / 8); return 0; @@ -461,4 +438,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/saber/SABERKEMExtractor.cs b/crypto/src/pqc/crypto/saber/SABERKEMExtractor.cs index 7199b9dab..ce0b374f3 100644 --- a/crypto/src/pqc/crypto/saber/SABERKEMExtractor.cs +++ b/crypto/src/pqc/crypto/saber/SABERKEMExtractor.cs @@ -1,24 +1,23 @@ - using Org.BouncyCastle.Crypto; namespace Org.BouncyCastle.Pqc.Crypto.Saber { - public class SaberKemExtractor + public sealed class SaberKemExtractor : IEncapsulatedSecretExtractor { - private SABEREngine engine; + private readonly SaberKeyParameters key; - private SaberKeyParameters key; + private SaberEngine engine; public SaberKemExtractor(SaberKeyParameters privParams) { this.key = privParams; - InitCipher(key.GetParameters()); + InitCipher(key.Parameters); } private void InitCipher(SaberParameters param) { - engine = param.GetEngine(); + engine = param.Engine; } public byte[] ExtractSecret(byte[] encapsulation) @@ -30,4 +29,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber public int EncapsulationLength => engine.GetCipherTextSize(); } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/saber/SABERKEMGenerator.cs b/crypto/src/pqc/crypto/saber/SABERKEMGenerator.cs index 0919b4dea..f948717b1 100644 --- a/crypto/src/pqc/crypto/saber/SABERKEMGenerator.cs +++ b/crypto/src/pqc/crypto/saber/SABERKEMGenerator.cs @@ -1,13 +1,10 @@ - -using System; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Pqc.Crypto.Utilities; using Org.BouncyCastle.Security; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Saber { - public class SaberKemGenerator + public sealed class SaberKemGenerator : IEncapsulatedSecretGenerator { // the source of randomness @@ -15,18 +12,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber public SaberKemGenerator(SecureRandom random) { - this.sr = random; + this.sr = CryptoServicesRegistrar.GetSecureRandom(random); } public ISecretWithEncapsulation GenerateEncapsulated(AsymmetricKeyParameter recipientKey) { - SaberPublicKeyParameters key = (SaberPublicKeyParameters) recipientKey; - SABEREngine engine = key.GetParameters().GetEngine(); + SaberPublicKeyParameters key = (SaberPublicKeyParameters)recipientKey; + SaberEngine engine = key.Parameters.Engine; byte[] cipher_text = new byte[engine.GetCipherTextSize()]; byte[] sessionKey = new byte[engine.GetSessionKeySize()]; - engine.crypto_kem_enc(cipher_text, sessionKey, key.PublicKey, sr); + engine.crypto_kem_enc(cipher_text, sessionKey, key.GetPublicKey(), sr); return new SecretWithEncapsulationImpl(sessionKey, cipher_text); } - } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/saber/SABERKeyGenerationParameters.cs b/crypto/src/pqc/crypto/saber/SABERKeyGenerationParameters.cs index 038c191ef..c76ec6234 100644 --- a/crypto/src/pqc/crypto/saber/SABERKeyGenerationParameters.cs +++ b/crypto/src/pqc/crypto/saber/SABERKeyGenerationParameters.cs @@ -1,17 +1,14 @@ - using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Pqc.Crypto.Saber { - public class SaberKeyGenerationParameters + public sealed class SaberKeyGenerationParameters : KeyGenerationParameters { private SaberParameters parameters; - public SaberKeyGenerationParameters( - SecureRandom random, - SaberParameters saberParameters) + public SaberKeyGenerationParameters(SecureRandom random, SaberParameters saberParameters) : base(random, 256) { this.parameters = saberParameters; @@ -19,4 +16,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber public SaberParameters Parameters => parameters; } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/saber/SABERKeyPairGenerator.cs b/crypto/src/pqc/crypto/saber/SABERKeyPairGenerator.cs index 73209b18b..1407f74a3 100644 --- a/crypto/src/pqc/crypto/saber/SABERKeyPairGenerator.cs +++ b/crypto/src/pqc/crypto/saber/SABERKeyPairGenerator.cs @@ -1,4 +1,3 @@ - using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; @@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber private void Initialize( KeyGenerationParameters param) { - this.saberParams = (SaberKeyGenerationParameters) param; + this.saberParams = (SaberKeyGenerationParameters)param; this.random = param.Random; this.l = this.saberParams.Parameters.L; @@ -24,7 +23,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber private AsymmetricCipherKeyPair GenKeyPair() { - SABEREngine engine = saberParams.Parameters.GetEngine(); + SaberEngine engine = saberParams.Parameters.Engine; byte[] sk = new byte[engine.GetPrivateKeySize()]; byte[] pk = new byte[engine.GetPublicKeySize()]; engine.crypto_kem_keypair(pk, sk, random); @@ -44,4 +43,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber return GenKeyPair(); } } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/saber/SABERKeyParameters.cs b/crypto/src/pqc/crypto/saber/SABERKeyParameters.cs index e5a9e767e..d83d2e3ea 100644 --- a/crypto/src/pqc/crypto/saber/SABERKeyParameters.cs +++ b/crypto/src/pqc/crypto/saber/SABERKeyParameters.cs @@ -1,24 +1,18 @@ - using Org.BouncyCastle.Crypto; namespace Org.BouncyCastle.Pqc.Crypto.Saber { - public class SaberKeyParameters + public abstract class SaberKeyParameters : AsymmetricKeyParameter { - private SaberParameters parameters; + private readonly SaberParameters parameters; - public SaberKeyParameters( - bool isPrivate, - SaberParameters parameters) + public SaberKeyParameters(bool isPrivate, SaberParameters parameters) : base(isPrivate) { this.parameters = parameters; } - public SaberParameters GetParameters() - { - return parameters; - } + public SaberParameters Parameters => parameters; } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/saber/SABERParameters.cs b/crypto/src/pqc/crypto/saber/SABERParameters.cs index 357430d50..e2992d4c4 100644 --- a/crypto/src/pqc/crypto/saber/SABERParameters.cs +++ b/crypto/src/pqc/crypto/saber/SABERParameters.cs @@ -1,5 +1,3 @@ - -using System; using Org.BouncyCastle.Crypto; namespace Org.BouncyCastle.Pqc.Crypto.Saber @@ -7,29 +5,42 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber public sealed class SaberParameters : ICipherParameters { - public static SaberParameters lightsaberkem128r3 = new SaberParameters("lightsaberkem128r3", 2, 128); - public static SaberParameters saberkem128r3 = new SaberParameters("saberkem128r3", 3, 128); - public static SaberParameters firesaberkem128r3 = new SaberParameters("firesaberkem128r3", 4, 128); + public static SaberParameters lightsaberkem128r3 = new SaberParameters("lightsaberkem128r3", 2, 128, false, false); + public static SaberParameters saberkem128r3 = new SaberParameters("saberkem128r3", 3, 128, false, false); + public static SaberParameters firesaberkem128r3 = new SaberParameters("firesaberkem128r3", 4, 128, false, false); + + public static SaberParameters lightsaberkem192r3 = new SaberParameters("lightsaberkem192r3", 2, 192, false, false); + public static SaberParameters saberkem192r3 = new SaberParameters("saberkem192r3", 3, 192, false, false); + public static SaberParameters firesaberkem192r3 = new SaberParameters("firesaberkem192r3", 4, 192, false, false); + + public static SaberParameters lightsaberkem256r3 = new SaberParameters("lightsaberkem256r3", 2, 256, false, false); + public static SaberParameters saberkem256r3 = new SaberParameters("saberkem256r3", 3, 256, false, false); + public static SaberParameters firesaberkem256r3 = new SaberParameters("firesaberkem256r3", 4, 256, false, false); + + public static SaberParameters lightsaberkem90sr3 = new SaberParameters("lightsaberkem90sr3", 2, 256, true, false); + public static SaberParameters saberkem90sr3 = new SaberParameters("saberkem90sr3", 3, 256, true, false); + public static SaberParameters firesaberkem90sr3 = new SaberParameters("firesaberkem90sr3", 4, 256, true, false); - public static SaberParameters lightsaberkem192r3 = new SaberParameters("lightsaberkem192r3", 2, 192); - public static SaberParameters saberkem192r3 = new SaberParameters("saberkem192r3", 3, 192); - public static SaberParameters firesaberkem192r3 = new SaberParameters("firesaberkem192r3", 4, 192); + public static SaberParameters ulightsaberkemr3 = new SaberParameters("ulightsaberkemr3", 2, 256, false, true); + public static SaberParameters usaberkemr3 = new SaberParameters("usaberkemr3", 3, 256, false, true); + public static SaberParameters ufiresaberkemr3 = new SaberParameters("ufiresaberkemr3", 4, 256, false, true); - public static SaberParameters lightsaberkem256r3 = new SaberParameters("lightsaberkem256r3", 2, 256); - public static SaberParameters saberkem256r3 = new SaberParameters("saberkem256r3", 3, 256); - public static SaberParameters firesaberkem256r3 = new SaberParameters("firesaberkem256r3", 4, 256); + public static SaberParameters ulightsaberkem90sr3 = new SaberParameters("ulightsaberkem90sr3", 2, 256, true, true); + public static SaberParameters usaberkem90sr3 = new SaberParameters("usaberkem90sr3", 3, 256, true, true); + public static SaberParameters ufiresaberkem90sr3 = new SaberParameters("ufiresaberkem90sr3", 4, 256, true, true); - private string name; - private int l; - private int defaultKeySize; - private SABEREngine engine; - public SaberParameters(string name, int l, int defaultKeySize) + private readonly string name; + private readonly int l; + private readonly int defaultKeySize; + private readonly SaberEngine engine; + + private SaberParameters(string name, int l, int defaultKeySize, bool usingAes, bool usingEffectiveMasking) { this.name = name; this.l = l; this.defaultKeySize = defaultKeySize; - this.engine = new SABEREngine(l, defaultKeySize); + this.engine = new SaberEngine(l, defaultKeySize, usingAes, usingEffectiveMasking); } public string Name => name; @@ -38,9 +49,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber public int DefaultKeySize => defaultKeySize; - internal SABEREngine GetEngine() - { - return engine; - } + internal SaberEngine Engine => engine; } } diff --git a/crypto/src/pqc/crypto/saber/SABERPrivateKeyParameters.cs b/crypto/src/pqc/crypto/saber/SABERPrivateKeyParameters.cs index ec4add8b5..6b708af73 100644 --- a/crypto/src/pqc/crypto/saber/SABERPrivateKeyParameters.cs +++ b/crypto/src/pqc/crypto/saber/SABERPrivateKeyParameters.cs @@ -2,15 +2,10 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Saber { - public class SaberPrivateKeyParameters + public sealed class SaberPrivateKeyParameters : SaberKeyParameters { - private byte[] privateKey; - - public byte[] GetPrivateKey() - { - return Arrays.Clone(privateKey); - } + private readonly byte[] privateKey; public SaberPrivateKeyParameters(SaberParameters parameters, byte[] privateKey) : base(true, parameters) @@ -22,5 +17,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber { return Arrays.Clone(privateKey); } + + public byte[] GetPrivateKey() + { + return Arrays.Clone(privateKey); + } } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/saber/SABERPublicKeyParameters.cs b/crypto/src/pqc/crypto/saber/SABERPublicKeyParameters.cs index dcac1ec3c..573ca2661 100644 --- a/crypto/src/pqc/crypto/saber/SABERPublicKeyParameters.cs +++ b/crypto/src/pqc/crypto/saber/SABERPublicKeyParameters.cs @@ -2,22 +2,25 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Saber { - public class SaberPublicKeyParameters + public sealed class SaberPublicKeyParameters : SaberKeyParameters { - public byte[] publicKey; + public readonly byte[] publicKey; - public byte[] PublicKey => Arrays.Clone(publicKey); + public SaberPublicKeyParameters(SaberParameters parameters, byte[] publicKey) + : base(false, parameters) + { + this.publicKey = Arrays.Clone(publicKey); + } public byte[] GetEncoded() { - return PublicKey; + return Arrays.Clone(publicKey); } - public SaberPublicKeyParameters(SaberParameters parameters, byte[] publicKey) - : base(false, parameters) + public byte[] GetPublicKey() { - this.publicKey = Arrays.Clone(publicKey); + return Arrays.Clone(publicKey); } } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/saber/Utils.cs b/crypto/src/pqc/crypto/saber/SaberUtilities.cs index ff74ef1cb..90c2b4ea4 100644 --- a/crypto/src/pqc/crypto/saber/Utils.cs +++ b/crypto/src/pqc/crypto/saber/SaberUtilities.cs @@ -1,23 +1,23 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber { - internal class Utils + internal class SaberUtilities { - - private int SABER_N; - private int SABER_L; - private int SABER_ET; - private int SABER_POLYBYTES; - private int SABER_EP; - private int SABER_KEYBYTES; - - internal Utils(SABEREngine engine) + private readonly int SABER_N; + private readonly int SABER_L; + private readonly int SABER_ET; + private readonly int SABER_POLYBYTES; + private readonly int SABER_EP; + private readonly int SABER_KEYBYTES; + private readonly bool usingEffectiveMasking; + internal SaberUtilities(SaberEngine engine) { - this.SABER_N = engine.getSABER_N(); - this.SABER_L = engine.getSABER_L(); - this.SABER_ET = engine.getSABER_ET(); - this.SABER_POLYBYTES = engine.getSABER_POLYBYTES(); - this.SABER_EP = engine.getSABER_EP(); - this.SABER_KEYBYTES = engine.getSABER_KEYBYTES(); + this.SABER_N = engine.N; + this.SABER_L = engine.L; + this.SABER_ET = engine.ET; + this.SABER_POLYBYTES = engine.PolyBytes; + this.SABER_EP = engine.EP; + this.SABER_KEYBYTES = engine.KeyBytes; + this.usingEffectiveMasking = engine.UsingEffectiveMasking; } public void POLT2BS(byte[] bytes, int byteIndex, short[] data) @@ -118,60 +118,87 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber private void POLq2BS(byte[] bytes, int byteIndex, short[] data) { short j, offset_byte, offset_data; - for (j = 0; j < SABER_N / 8; j++) + if (!usingEffectiveMasking) { - offset_byte = (short) (13 * j); - offset_data = (short) (8 * j); - bytes[byteIndex + offset_byte + 0] = (byte) (data[offset_data + 0] & (0xff)); - bytes[byteIndex + offset_byte + 1] = - (byte) (((data[offset_data + 0] >> 8) & 0x1f) | ((data[offset_data + 1] & 0x07) << 5)); - bytes[byteIndex + offset_byte + 2] = (byte) ((data[offset_data + 1] >> 3) & 0xff); - bytes[byteIndex + offset_byte + 3] = - (byte) (((data[offset_data + 1] >> 11) & 0x03) | ((data[offset_data + 2] & 0x3f) << 2)); - bytes[byteIndex + offset_byte + 4] = - (byte) (((data[offset_data + 2] >> 6) & 0x7f) | ((data[offset_data + 3] & 0x01) << 7)); - bytes[byteIndex + offset_byte + 5] = (byte) ((data[offset_data + 3] >> 1) & 0xff); - bytes[byteIndex + offset_byte + 6] = - (byte) (((data[offset_data + 3] >> 9) & 0x0f) | ((data[offset_data + 4] & 0x0f) << 4)); - bytes[byteIndex + offset_byte + 7] = (byte) ((data[offset_data + 4] >> 4) & 0xff); - bytes[byteIndex + offset_byte + 8] = - (byte) (((data[offset_data + 4] >> 12) & 0x01) | ((data[offset_data + 5] & 0x7f) << 1)); - bytes[byteIndex + offset_byte + 9] = - (byte) (((data[offset_data + 5] >> 7) & 0x3f) | ((data[offset_data + 6] & 0x03) << 6)); - bytes[byteIndex + offset_byte + 10] = (byte) ((data[offset_data + 6] >> 2) & 0xff); - bytes[byteIndex + offset_byte + 11] = - (byte) (((data[offset_data + 6] >> 10) & 0x07) | ((data[offset_data + 7] & 0x1f) << 3)); - bytes[byteIndex + offset_byte + 12] = (byte) ((data[offset_data + 7] >> 5) & 0xff); + for (j = 0; j < SABER_N / 8; j++) + { + offset_byte = (short)(13 * j); + offset_data = (short)(8 * j); + bytes[byteIndex + offset_byte + 0] = (byte)(data[offset_data + 0] & (0xff)); + bytes[byteIndex + offset_byte + 1] = + (byte)(((data[offset_data + 0] >> 8) & 0x1f) | ((data[offset_data + 1] & 0x07) << 5)); + bytes[byteIndex + offset_byte + 2] = (byte)((data[offset_data + 1] >> 3) & 0xff); + bytes[byteIndex + offset_byte + 3] = + (byte)(((data[offset_data + 1] >> 11) & 0x03) | ((data[offset_data + 2] & 0x3f) << 2)); + bytes[byteIndex + offset_byte + 4] = + (byte)(((data[offset_data + 2] >> 6) & 0x7f) | ((data[offset_data + 3] & 0x01) << 7)); + bytes[byteIndex + offset_byte + 5] = (byte)((data[offset_data + 3] >> 1) & 0xff); + bytes[byteIndex + offset_byte + 6] = + (byte)(((data[offset_data + 3] >> 9) & 0x0f) | ((data[offset_data + 4] & 0x0f) << 4)); + bytes[byteIndex + offset_byte + 7] = (byte)((data[offset_data + 4] >> 4) & 0xff); + bytes[byteIndex + offset_byte + 8] = + (byte)(((data[offset_data + 4] >> 12) & 0x01) | ((data[offset_data + 5] & 0x7f) << 1)); + bytes[byteIndex + offset_byte + 9] = + (byte)(((data[offset_data + 5] >> 7) & 0x3f) | ((data[offset_data + 6] & 0x03) << 6)); + bytes[byteIndex + offset_byte + 10] = (byte)((data[offset_data + 6] >> 2) & 0xff); + bytes[byteIndex + offset_byte + 11] = + (byte)(((data[offset_data + 6] >> 10) & 0x07) | ((data[offset_data + 7] & 0x1f) << 3)); + bytes[byteIndex + offset_byte + 12] = (byte)((data[offset_data + 7] >> 5) & 0xff); + } + } + else + { + for (j = 0; j < SABER_N / 2; j++) + { + offset_byte = (short) (3 * j); + offset_data = (short) (2 * j); + bytes[byteIndex + offset_byte + 0] = (byte) (data[offset_data + 0] & (0xff)); + bytes[byteIndex + offset_byte + 1] = (byte) (((data[offset_data + 0] >> 8) & 0xf) | ((data[offset_data + 1] & 0xf) << 4)); + bytes[byteIndex + offset_byte + 2] = (byte) ((data[offset_data + 1] >> 4) & 0xff); + } } } private void BS2POLq(byte[] bytes, int byteIndex, short[] data) { short j, offset_byte, offset_data; - for (j = 0; j < SABER_N / 8; j++) + if (!usingEffectiveMasking) { - offset_byte = (short) (13 * j); - offset_data = (short) (8 * j); - data[offset_data + 0] = (short) ((bytes[byteIndex + offset_byte + 0] & (0xff)) | - ((bytes[byteIndex + offset_byte + 1] & 0x1f) << 8)); - data[offset_data + 1] = (short) ((bytes[byteIndex + offset_byte + 1] >> 5 & (0x07)) | - ((bytes[byteIndex + offset_byte + 2] & 0xff) << 3) | - ((bytes[byteIndex + offset_byte + 3] & 0x03) << 11)); - data[offset_data + 2] = (short) ((bytes[byteIndex + offset_byte + 3] >> 2 & (0x3f)) | - ((bytes[byteIndex + offset_byte + 4] & 0x7f) << 6)); - data[offset_data + 3] = (short) ((bytes[byteIndex + offset_byte + 4] >> 7 & (0x01)) | - ((bytes[byteIndex + offset_byte + 5] & 0xff) << 1) | - ((bytes[byteIndex + offset_byte + 6] & 0x0f) << 9)); - data[offset_data + 4] = (short) ((bytes[byteIndex + offset_byte + 6] >> 4 & (0x0f)) | - ((bytes[byteIndex + offset_byte + 7] & 0xff) << 4) | - ((bytes[byteIndex + offset_byte + 8] & 0x01) << 12)); - data[offset_data + 5] = (short) ((bytes[byteIndex + offset_byte + 8] >> 1 & (0x7f)) | - ((bytes[byteIndex + offset_byte + 9] & 0x3f) << 7)); - data[offset_data + 6] = (short) ((bytes[byteIndex + offset_byte + 9] >> 6 & (0x03)) | - ((bytes[byteIndex + offset_byte + 10] & 0xff) << 2) | - ((bytes[byteIndex + offset_byte + 11] & 0x07) << 10)); - data[offset_data + 7] = (short) ((bytes[byteIndex + offset_byte + 11] >> 3 & (0x1f)) | - ((bytes[byteIndex + offset_byte + 12] & 0xff) << 5)); + for (j = 0; j < SABER_N / 8; j++) + { + offset_byte = (short)(13 * j); + offset_data = (short)(8 * j); + data[offset_data + 0] = (short)((bytes[byteIndex + offset_byte + 0] & (0xff)) | + ((bytes[byteIndex + offset_byte + 1] & 0x1f) << 8)); + data[offset_data + 1] = (short)((bytes[byteIndex + offset_byte + 1] >> 5 & (0x07)) | + ((bytes[byteIndex + offset_byte + 2] & 0xff) << 3) | + ((bytes[byteIndex + offset_byte + 3] & 0x03) << 11)); + data[offset_data + 2] = (short)((bytes[byteIndex + offset_byte + 3] >> 2 & (0x3f)) | + ((bytes[byteIndex + offset_byte + 4] & 0x7f) << 6)); + data[offset_data + 3] = (short)((bytes[byteIndex + offset_byte + 4] >> 7 & (0x01)) | + ((bytes[byteIndex + offset_byte + 5] & 0xff) << 1) | + ((bytes[byteIndex + offset_byte + 6] & 0x0f) << 9)); + data[offset_data + 4] = (short)((bytes[byteIndex + offset_byte + 6] >> 4 & (0x0f)) | + ((bytes[byteIndex + offset_byte + 7] & 0xff) << 4) | + ((bytes[byteIndex + offset_byte + 8] & 0x01) << 12)); + data[offset_data + 5] = (short)((bytes[byteIndex + offset_byte + 8] >> 1 & (0x7f)) | + ((bytes[byteIndex + offset_byte + 9] & 0x3f) << 7)); + data[offset_data + 6] = (short)((bytes[byteIndex + offset_byte + 9] >> 6 & (0x03)) | + ((bytes[byteIndex + offset_byte + 10] & 0xff) << 2) | + ((bytes[byteIndex + offset_byte + 11] & 0x07) << 10)); + data[offset_data + 7] = (short)((bytes[byteIndex + offset_byte + 11] >> 3 & (0x1f)) | + ((bytes[byteIndex + offset_byte + 12] & 0xff) << 5)); + } + } + else + { + for (j = 0; j < SABER_N / 2; j++) + { + offset_byte = (short) (3 * j); + offset_data = (short) (2 * j); + data[offset_data + 0] = (short) ((bytes[byteIndex + offset_byte + 0] & (0xff)) | ((bytes[byteIndex + offset_byte + 1] & 0xf) << 8)); + data[offset_data + 1] = (short) ((bytes[byteIndex + offset_byte + 1] >> 4 & (0xf)) | ((bytes[byteIndex + offset_byte + 2] & 0xff) << 4)); + } } } @@ -271,4 +298,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Saber } } } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/saber/Symmetric.cs b/crypto/src/pqc/crypto/saber/Symmetric.cs new file mode 100644 index 000000000..bcbe8a9a3 --- /dev/null +++ b/crypto/src/pqc/crypto/saber/Symmetric.cs @@ -0,0 +1,99 @@ +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Pqc.Crypto.Saber +{ + + public abstract class Symmetric + { + + internal abstract void Hash_h(byte[] output, byte[] input, int outputOffset); + + internal abstract void Hash_g(byte[] output, byte[] input); + + internal abstract void Prf(byte[] output, byte[] input, int inLen, int outputLen); + + protected internal class ShakeSymmetric + : Symmetric + { + + private readonly Sha3Digest sha3Digest256; + private readonly Sha3Digest sha3Digest512; + private readonly IXof shakeDigest; + + internal ShakeSymmetric() + { + shakeDigest = new ShakeDigest(128); + sha3Digest256 = new Sha3Digest(256); + sha3Digest512 = new Sha3Digest(512); + } + + internal override void Hash_h(byte[] output, byte[] input, int outputOffset) + { + sha3Digest256.BlockUpdate(input, 0, input.Length); + sha3Digest256.DoFinal(output, outputOffset); + } + + internal override void Hash_g(byte[] output, byte[] input) + { + sha3Digest512.BlockUpdate(input, 0, input.Length); + sha3Digest512.DoFinal(output, 0); + } + + internal override void Prf(byte[] output, byte[] input, int inLen, int outputLen) + { + shakeDigest.Reset(); + shakeDigest.BlockUpdate(input, 0, inLen); + shakeDigest.OutputFinal(output, 0, outputLen); + } + + + } + + internal class AesSymmetric + : Symmetric + { + + private readonly Sha256Digest sha256Digest; + private readonly Sha512Digest sha512Digest; + + private readonly SicBlockCipher cipher; + + + protected internal AesSymmetric() + { + sha256Digest = new Sha256Digest(); + sha512Digest = new Sha512Digest(); + cipher = new SicBlockCipher(AesUtilities.CreateEngine()); + } + + internal override void Hash_h(byte[] output, byte[] input, int outputOffset) + { + sha256Digest.BlockUpdate(input, 0, input.Length); + sha256Digest.DoFinal(output, outputOffset); + } + + internal override void Hash_g(byte[] output, byte[] input) + { + sha512Digest.BlockUpdate(input, 0, input.Length); + sha512Digest.DoFinal(output, 0); + } + + internal override void Prf(byte[] output, byte[] input, int inLen, int outputLen) + { + ParametersWithIV kp = new ParametersWithIV(new KeyParameter(input, 0, inLen), new byte[16]); + cipher.Init(true, kp); + byte[] buf = new byte[outputLen]; // TODO: there might be a more efficient way of doing this... + for (int i = 0; i < outputLen; i += 16) + { + cipher.ProcessBlock(buf, i, output, i); + } + } + + + } + + } +} \ No newline at end of file diff --git a/crypto/src/pqc/crypto/sike/Fpx.cs b/crypto/src/pqc/crypto/sike/Fpx.cs index 2ba6ab2f5..9ba332753 100644 --- a/crypto/src/pqc/crypto/sike/Fpx.cs +++ b/crypto/src/pqc/crypto/sike/Fpx.cs @@ -1,4 +1,3 @@ -using System; using System.Diagnostics; #if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER using System.Runtime.CompilerServices; @@ -8,11 +7,11 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Sike { - internal class Fpx + internal sealed class Fpx { - private SIKEEngine engine; + private readonly SikeEngine engine; - internal Fpx(SIKEEngine engine) + internal Fpx(SikeEngine engine) { this.engine = engine; } @@ -47,7 +46,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Also, vec and out CANNOT be the same variable! protected internal void mont_n_way_inv(ulong[][][] vec, uint n, ulong[][][] output) { - ulong[][] t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); int i; fp2copy(vec[0], output[0]); // output[0] = vec[0] @@ -368,7 +367,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // This uses the binary GCD for inversion in fp and is NOT constant time!!! protected internal void fp2inv_mont_bingcd(ulong[][] a) { - ulong[][] t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); fpsqr_mont(a[0], t1[0]); // t10 = a0^2 fpsqr_mont(a[1], t1[1]); // t11 = a1^2 @@ -892,7 +891,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Conversion of GF(p^2) element from Montgomery to standard representation, and encoding by removing leading 0 bytes protected internal void fp2_encode(ulong[][] x, byte[] enc, uint encOffset) { - ulong[][] t = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); from_fp2mont(x, t); encode_to_bytes(t[0], enc, encOffset,engine.param.FP2_ENCODED_BYTES / 2); @@ -1280,8 +1279,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike protected internal byte cmp_f2elm(ulong[][] x, ulong[][] y) { // Comparison of two GF(p^2) elements in constant time. // Is x != y? return -1 if condition is true, 0 otherwise. - ulong[][] a = Utils.InitArray(2, engine.param.NWORDS_FIELD), - b = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] a = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + b = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); byte r = 0; fp2copy(x, a); @@ -1661,7 +1660,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // GF(p^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2). protected internal void fp2inv_mont(ulong[][] a) { - ulong[][] t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); fpsqr_mont(a[0], t1[0]); // t10 = a0^2 fpsqr_mont(a[1], t1[1]); // t11 = a1^2 @@ -1808,7 +1807,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike if (engine.param.NBITS_FIELD == 434) { ulong[] tt = new ulong[engine.param.NWORDS_FIELD]; - ulong[][] t = Utils.InitArray(31, engine.param.NWORDS_FIELD); + ulong[][] t = SikeUtilities.InitArray(31, engine.param.NWORDS_FIELD); // Precomputed table fpsqr_mont(a, tt); @@ -1888,7 +1887,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike if (engine.param.NBITS_FIELD == 503) { - ulong[][] t = Utils.InitArray(15, engine.param.NWORDS_FIELD); + ulong[][] t = SikeUtilities.InitArray(15, engine.param.NWORDS_FIELD); ulong[] tt = new ulong[engine.param.NWORDS_FIELD]; // Precomputed table @@ -1991,7 +1990,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike if (engine.param.NBITS_FIELD == 610) { - ulong[][] t = Utils.InitArray(31, engine.param.NWORDS_FIELD); + ulong[][] t = SikeUtilities.InitArray(31, engine.param.NWORDS_FIELD); ulong[] tt = new ulong[engine.param.NWORDS_FIELD]; // Precomputed table @@ -2096,7 +2095,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike if (engine.param.NBITS_FIELD == 751) { - ulong[][] t = Utils.InitArray(27, engine.param.NWORDS_FIELD); + ulong[][] t = SikeUtilities.InitArray(27, engine.param.NWORDS_FIELD); ulong[] tt = new ulong[engine.param.NWORDS_FIELD]; // Precomputed table diff --git a/crypto/src/pqc/crypto/sike/Internal.cs b/crypto/src/pqc/crypto/sike/Internal.cs index 06df0a202..35b1a46e8 100644 --- a/crypto/src/pqc/crypto/sike/Internal.cs +++ b/crypto/src/pqc/crypto/sike/Internal.cs @@ -1,217 +1,214 @@ using System; using System.Collections.Generic; + using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Pqc.Crypto.Sike { - internal abstract class Internal - { - protected static Dictionary<string, string> _props; + { + protected static Dictionary<string, string> _props; - protected internal static uint RADIX = 64; - protected internal static uint LOG2RADIX = 6; - - protected internal uint CRYPTO_PUBLICKEYBYTES; - protected internal int CRYPTO_CIPHERTEXTBYTES; - protected internal uint CRYPTO_BYTES; - protected internal uint CRYPTO_SECRETKEYBYTES; - - - - protected internal uint NWORDS_FIELD; // Number of words of a n-bit field element - protected internal uint PRIME_ZERO_WORDS; // Number of "0" digits in the least significant part of PRIME + 1 - protected internal uint NBITS_FIELD; - protected internal uint MAXBITS_FIELD; - protected uint MAXWORDS_FIELD; // Max. number of words to represent field elements - protected uint NWORDS64_FIELD; // Number of 64-bit words of a 434-bit field element - protected internal uint NBITS_ORDER; - protected internal uint NWORDS_ORDER; // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp. - protected uint NWORDS64_ORDER; // Number of 64-bit words of a x-bit element - protected internal uint MAXBITS_ORDER; - protected internal uint ALICE; - protected internal uint BOB; - protected internal uint OALICE_BITS; - protected internal uint OBOB_BITS; - protected internal uint OBOB_EXPON; - protected internal uint MASK_ALICE; - protected internal uint MASK_BOB; - protected uint PARAM_A; - protected uint PARAM_C; - - // Fixed parameters for isogeny tree computation - protected internal uint MAX_INT_POINTS_ALICE; - protected internal uint MAX_INT_POINTS_BOB; - protected internal uint MAX_Alice; - protected internal uint MAX_Bob; - protected internal uint MSG_BYTES; - protected internal uint SECRETKEY_A_BYTES; - protected internal uint SECRETKEY_B_BYTES; - protected internal uint FP2_ENCODED_BYTES; - - protected bool COMPRESS; - - // Compressed Parameters - protected internal uint MASK2_BOB; - protected internal uint MASK3_BOB; - protected internal uint ORDER_A_ENCODED_BYTES; - protected internal uint ORDER_B_ENCODED_BYTES; - protected internal uint PARTIALLY_COMPRESSED_CHUNK_CT; - protected uint COMPRESSED_CHUNK_CT; - protected uint UNCOMPRESSEDPK_BYTES; - // Table sizes used by the Entangled basis generation - protected uint TABLE_R_LEN; - protected internal uint TABLE_V_LEN; - protected uint TABLE_V3_LEN; - // Parameters for discrete log computations - // Binary Pohlig-Hellman reduced to smaller logs of order ell^W - protected internal uint W_2; - protected internal uint W_3; - // ell^w - protected internal uint ELL2_W; - protected internal uint ELL3_W; - // ell^(e mod w) - protected internal uint ELL2_EMODW; - protected internal uint ELL3_EMODW; - // # of digits in the discrete log - protected internal uint DLEN_2; // ceil(eA/W_2) - protected internal uint DLEN_3; // ceil(eB/W_3) - // Use compressed tables: FULL_SIGNED - - - // Encoding of field elements - protected internal uint PLEN_2; - protected internal uint PLEN_3; - - protected internal ulong[] PRIME; - protected internal ulong[] PRIMEx2; - protected internal ulong[] PRIMEx4; - protected internal ulong[] PRIMEp1; - protected ulong[] PRIMEx16p; - protected ulong[] PRIMEp1x64; - protected internal ulong[] Alice_order; // Order of Alice's subgroup - protected internal ulong[] Bob_order; // Order of Bob's subgroup - protected internal ulong[] A_gen; // Alice's generator values {XPA0 + XPA1*iL, XQA0 + xQA1*iL, XRA0 + XRA1*i} in GF(p^2)L, expressed in Montgomery representation - protected internal ulong[] B_gen; // Bob's generator values {XPB0L, XQB0L, XRB0 + XRB1*i} in GF(p^2)L, expressed in Montgomery representation - protected internal ulong[] Montgomery_R2; // Montgomery constant Montgomery_R2 = (2^448)^2 mod p434 - protected internal ulong[] Montgomery_one; // Value one in Montgomery representation - - // Fixed parameters for isogeny tree computation - protected internal uint[] strat_Alice; - protected internal uint[] strat_Bob; - - //Compressed Encodings - //todo: abstract this more? - protected internal ulong[] XQB3; - protected internal ulong[] A_basis_zero; - protected ulong[] B_basis_zero; - protected internal ulong[] B_gen_3_tors; - protected internal ulong[] g_R_S_im; - protected ulong[] g_phiR_phiS_re; - protected ulong[] g_phiR_phiS_im; - protected ulong[] Montgomery_R; - protected internal ulong[] Montgomery_RB1; - protected internal ulong[] Montgomery_RB2; - protected ulong[] threeinv; - protected internal uint[] ph2_path; - protected internal uint[] ph3_path; - protected ulong[] u_entang; - protected ulong[] u0_entang; - protected internal ulong[][] table_r_qr; - protected internal ulong[][] table_r_qnr; - protected internal ulong[][] table_v_qr; - protected internal ulong[][] table_v_qnr; - protected internal ulong[][][] v_3_torsion; - - protected internal ulong[] T_tate3; - protected internal ulong[] T_tate2_firststep_P; - protected internal ulong[] T_tate2_P; - protected internal ulong[] T_tate2_firststep_Q; - protected internal ulong[] T_tate2_Q; - - ///Compressed Dlogs - protected internal ulong[] ph2_T; - protected internal ulong[] ph2_T1; - protected internal ulong[] ph2_T2; - protected internal ulong[] ph3_T; - protected internal ulong[] ph3_T1; - protected internal ulong[] ph3_T2; - - - static protected uint[] ReadIntsFromProperty(string key, uint intSize) - { - uint[] ints = new uint[intSize]; - string s = _props[key]; - uint i = 0; - foreach (string number in s.Split(',')) - { - ints[i] = UInt32.Parse(number); - i++; - } - return ints; - } + protected internal static uint RADIX = 64; + protected internal static uint LOG2RADIX = 6; + + protected internal uint CRYPTO_PUBLICKEYBYTES; + protected internal int CRYPTO_CIPHERTEXTBYTES; + protected internal uint CRYPTO_BYTES; + protected internal uint CRYPTO_SECRETKEYBYTES; + + + + protected internal uint NWORDS_FIELD; // Number of words of a n-bit field element + protected internal uint PRIME_ZERO_WORDS; // Number of "0" digits in the least significant part of PRIME + 1 + protected internal uint NBITS_FIELD; + protected internal uint MAXBITS_FIELD; + protected uint MAXWORDS_FIELD; // Max. number of words to represent field elements + protected uint NWORDS64_FIELD; // Number of 64-bit words of a 434-bit field element + protected internal uint NBITS_ORDER; + protected internal uint NWORDS_ORDER; // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp. + protected uint NWORDS64_ORDER; // Number of 64-bit words of a x-bit element + protected internal uint MAXBITS_ORDER; + protected internal uint ALICE; + protected internal uint BOB; + protected internal uint OALICE_BITS; + protected internal uint OBOB_BITS; + protected internal uint OBOB_EXPON; + protected internal uint MASK_ALICE; + protected internal uint MASK_BOB; + protected uint PARAM_A; + protected uint PARAM_C; + + // Fixed parameters for isogeny tree computation + protected internal uint MAX_INT_POINTS_ALICE; + protected internal uint MAX_INT_POINTS_BOB; + protected internal uint MAX_Alice; + protected internal uint MAX_Bob; + protected internal uint MSG_BYTES; + protected internal uint SECRETKEY_A_BYTES; + protected internal uint SECRETKEY_B_BYTES; + protected internal uint FP2_ENCODED_BYTES; + + protected bool COMPRESS; + + // Compressed Parameters + protected internal uint MASK2_BOB; + protected internal uint MASK3_BOB; + protected internal uint ORDER_A_ENCODED_BYTES; + protected internal uint ORDER_B_ENCODED_BYTES; + protected internal uint PARTIALLY_COMPRESSED_CHUNK_CT; + protected uint COMPRESSED_CHUNK_CT; + protected uint UNCOMPRESSEDPK_BYTES; + // Table sizes used by the Entangled basis generation + protected uint TABLE_R_LEN; + protected internal uint TABLE_V_LEN; + protected uint TABLE_V3_LEN; + // Parameters for discrete log computations + // Binary Pohlig-Hellman reduced to smaller logs of order ell^W + protected internal uint W_2; + protected internal uint W_3; + // ell^w + protected internal uint ELL2_W; + protected internal uint ELL3_W; + // ell^(e mod w) + protected internal uint ELL2_EMODW; + protected internal uint ELL3_EMODW; + // # of digits in the discrete log + protected internal uint DLEN_2; // ceil(eA/W_2) + protected internal uint DLEN_3; // ceil(eB/W_3) + // Use compressed tables: FULL_SIGNED + + + // Encoding of field elements + protected internal uint PLEN_2; + protected internal uint PLEN_3; + + protected internal ulong[] PRIME; + protected internal ulong[] PRIMEx2; + protected internal ulong[] PRIMEx4; + protected internal ulong[] PRIMEp1; + protected ulong[] PRIMEx16p; + protected ulong[] PRIMEp1x64; + protected internal ulong[] Alice_order; // Order of Alice's subgroup + protected internal ulong[] Bob_order; // Order of Bob's subgroup + protected internal ulong[] A_gen; // Alice's generator values {XPA0 + XPA1*iL, XQA0 + xQA1*iL, XRA0 + XRA1*i} in GF(p^2)L, expressed in Montgomery representation + protected internal ulong[] B_gen; // Bob's generator values {XPB0L, XQB0L, XRB0 + XRB1*i} in GF(p^2)L, expressed in Montgomery representation + protected internal ulong[] Montgomery_R2; // Montgomery constant Montgomery_R2 = (2^448)^2 mod p434 + protected internal ulong[] Montgomery_one; // Value one in Montgomery representation + + // Fixed parameters for isogeny tree computation + protected internal uint[] strat_Alice; + protected internal uint[] strat_Bob; + + //Compressed Encodings + //todo: abstract this more? + protected internal ulong[] XQB3; + protected internal ulong[] A_basis_zero; + protected ulong[] B_basis_zero; + protected internal ulong[] B_gen_3_tors; + protected internal ulong[] g_R_S_im; + protected ulong[] g_phiR_phiS_re; + protected ulong[] g_phiR_phiS_im; + protected ulong[] Montgomery_R; + protected internal ulong[] Montgomery_RB1; + protected internal ulong[] Montgomery_RB2; + protected ulong[] threeinv; + protected internal uint[] ph2_path; + protected internal uint[] ph3_path; + protected ulong[] u_entang; + protected ulong[] u0_entang; + protected internal ulong[][] table_r_qr; + protected internal ulong[][] table_r_qnr; + protected internal ulong[][] table_v_qr; + protected internal ulong[][] table_v_qnr; + protected internal ulong[][][] v_3_torsion; + + protected internal ulong[] T_tate3; + protected internal ulong[] T_tate2_firststep_P; + protected internal ulong[] T_tate2_P; + protected internal ulong[] T_tate2_firststep_Q; + protected internal ulong[] T_tate2_Q; + + ///Compressed Dlogs + protected internal ulong[] ph2_T; + protected internal ulong[] ph2_T1; + protected internal ulong[] ph2_T2; + protected internal ulong[] ph3_T; + protected internal ulong[] ph3_T1; + protected internal ulong[] ph3_T2; + + + static protected uint[] ReadIntsFromProperty(string key, uint intSize) + { + uint[] ints = new uint[intSize]; + string s = _props[key]; + uint i = 0; + foreach (string number in s.Split(',')) + { + ints[i] = UInt32.Parse(number); + i++; + } + return ints; + } - static protected ulong[] ReadFromProperty(string key, uint ulongSize) - { - string s = _props[key]; - s = s.Replace(",", ""); - byte[] bytes = Hex.Decode(s); - ulong[] ulongs = new ulong[ulongSize]; - for (int i = 0; i < bytes.Length / 8; i++) - { - ulongs[i] = Pack.BE_To_UInt64(bytes, i * 8); - } - return ulongs; - } + static protected ulong[] ReadFromProperty(string key, uint ulongSize) + { + string s = _props[key]; + s = s.Replace(",", ""); + byte[] bytes = Hex.Decode(s); + ulong[] ulongs = new ulong[ulongSize]; + for (int i = 0; i < bytes.Length / 8; i++) + { + ulongs[i] = Pack.BE_To_UInt64(bytes, i * 8); + } + return ulongs; + } - static protected ulong[][] ReadFromProperty(string key, uint d1Size, uint d2Size) - { - string s = _props[key]; - s = s.Replace(",", ""); - byte[] bytes = Hex.Decode(s); - ulong[][] ulongs = new ulong[d1Size][]; //[d2Size]; - for (int k = 0; k < d1Size; k++) - { - ulongs[k] = new ulong[d2Size]; - } - uint i, j; - for (uint x = 0; x < bytes.Length / 8; x++) - { - i = x/d2Size; - j = x%d2Size; - ulongs[i][j] = Pack.BE_To_UInt64(bytes, (int)x * 8); - } - return ulongs; - } + static protected ulong[][] ReadFromProperty(string key, uint d1Size, uint d2Size) + { + string s = _props[key]; + s = s.Replace(",", ""); + byte[] bytes = Hex.Decode(s); + ulong[][] ulongs = new ulong[d1Size][]; //[d2Size]; + for (int k = 0; k < d1Size; k++) + { + ulongs[k] = new ulong[d2Size]; + } + uint i, j; + for (uint x = 0; x < bytes.Length / 8; x++) + { + i = x/d2Size; + j = x%d2Size; + ulongs[i][j] = Pack.BE_To_UInt64(bytes, (int)x * 8); + } + return ulongs; + } - static protected ulong[][][] ReadFromProperty(string key, uint d1Size, uint d2Size, uint d3Size) + static protected ulong[][][] ReadFromProperty(string key, uint d1Size, uint d2Size, uint d3Size) + { + string s = _props[key]; + s = s.Replace(",", ""); + byte[] bytes = Hex.Decode(s); + ulong[][][] ulongs = new ulong[d1Size][][]; //[d2Size][d3Size]; + for (int l = 0; l < d1Size; l++) + { + ulongs[l] = new ulong[d2Size][]; + for (int m = 0; m < d2Size; m++) { - string s = _props[key]; - s = s.Replace(",", ""); - byte[] bytes = Hex.Decode(s); - ulong[][][] ulongs = new ulong[d1Size][][]; //[d2Size][d3Size]; - for (int l = 0; l < d1Size; l++) - { - ulongs[l] = new ulong[d2Size][]; - for (int m = 0; m < d2Size; m++) - { - ulongs[l][m] = new ulong[d3Size]; - } - } - - uint i, j, k; - for (uint x = 0; x < bytes.Length / 8; x++) - { - i = x/(d2Size * d3Size); - j = x%(d2Size * d3Size)/d3Size; - k = x % d3Size; - ulongs[i][j][k] = Pack.BE_To_UInt64(bytes, (int)x * 8); - } - return ulongs; + ulongs[l][m] = new ulong[d3Size]; } - - + } + + uint i, j, k; + for (uint x = 0; x < bytes.Length / 8; x++) + { + i = x/(d2Size * d3Size); + j = x%(d2Size * d3Size)/d3Size; + k = x % d3Size; + ulongs[i][j][k] = Pack.BE_To_UInt64(bytes, (int)x * 8); + } + return ulongs; } - -} \ No newline at end of file + } +} diff --git a/crypto/src/pqc/crypto/sike/Isogeny.cs b/crypto/src/pqc/crypto/sike/Isogeny.cs index fc2b3e5ca..2d0ef1473 100644 --- a/crypto/src/pqc/crypto/sike/Isogeny.cs +++ b/crypto/src/pqc/crypto/sike/Isogeny.cs @@ -1,25 +1,25 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike { - internal class Isogeny +internal sealed class Isogeny { - SIKEEngine engine; + private readonly SikeEngine engine; - internal Isogeny(SIKEEngine engine) + internal Isogeny(SikeEngine engine) { this.engine = engine; } - + // Doubling of a Montgomery point in projective coordinates (X:Z) over affine curve coefficient A. // Input: projective Montgomery x-coordinates P = (X1:Z1), where x1=X1/Z1 and Montgomery curve constants (A+2)/4. // Output: projective Montgomery x-coordinates Q = 2*P = (X2:Z2). protected internal void Double(PointProj P, PointProj Q, ulong[][] A24, uint k) { - ulong[][] temp = Utils.InitArray(2, engine.param.NWORDS_FIELD), - a = Utils.InitArray(2, engine.param.NWORDS_FIELD), - b = Utils.InitArray(2, engine.param.NWORDS_FIELD), - c = Utils.InitArray(2, engine.param.NWORDS_FIELD), - aa = Utils.InitArray(2, engine.param.NWORDS_FIELD), - bb = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] temp = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + a = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + b = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + c = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + aa = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + bb = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2copy(P.X, Q.X); engine.fpx.fp2copy(P.Z, Q.Z); @@ -39,15 +39,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike protected internal void CompleteMPoint(ulong[][] A, PointProj P, PointProjFull R) { // Given an xz-only representation on a montgomery curve, compute its affine representation - ulong[][] zero = Utils.InitArray(2, engine.param.NWORDS_FIELD), - one = Utils.InitArray(2, engine.param.NWORDS_FIELD), - xz = Utils.InitArray(2, engine.param.NWORDS_FIELD), - yz = Utils.InitArray(2, engine.param.NWORDS_FIELD), - s2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - r2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - invz = Utils.InitArray(2, engine.param.NWORDS_FIELD), - temp0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - temp1 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] zero = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + one = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + xz = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + yz = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + s2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + r2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + invz = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + temp0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + temp1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fpcopy(engine.param.Montgomery_one,0, one[0]); @@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike { PointProj R0 = new PointProj(engine.param.NWORDS_FIELD), R1 = new PointProj(engine.param.NWORDS_FIELD); - ulong[][] A24 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] A24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); uint bit = 0; ulong mask; int j, swap, prevbit = 0; @@ -132,9 +132,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: projective Montgomery points P <- 2*P = (X2P:Z2P) such that x(2P)=X2P/Z2P, and Q <- P+Q = (XQP:ZQP) such that = x(Q+P)=XQP/ZQP. private void xDBLADD_proj(PointProj P, PointProj Q, ulong[][] XPQ, ulong[][] ZPQ, ulong[][] A24) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2add(P.X, P.Z, t0); // t0 = XP+ZP @@ -164,12 +164,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: projective Montgomery x-coordinates Q = 2*P = (X2:Z2). private void xDBL_e(PointProj P, PointProj Q, ulong[][] A24, int e) { - ulong[][] temp = Utils.InitArray(2, engine.param.NWORDS_FIELD), - a = Utils.InitArray(2, engine.param.NWORDS_FIELD), - b = Utils.InitArray(2, engine.param.NWORDS_FIELD), - c = Utils.InitArray(2, engine.param.NWORDS_FIELD), - aa = Utils.InitArray(2, engine.param.NWORDS_FIELD), - bb = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] temp = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + a = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + b = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + c = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + aa = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + bb = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2copy(P.X,Q.X); @@ -209,10 +209,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: projective Montgomery x-coordinates Q = 3*P = (X3:Z3). private void xTPL_fast(PointProj P, PointProj Q, ulong[][] A2) { - ulong[][] t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t3 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t4 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t3 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t4 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2sqr_mont(P.X, t1); // t1 = x^2 @@ -242,7 +242,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike { PointProj R0 = new PointProj(engine.param.NWORDS_FIELD), R2 = new PointProj(engine.param.NWORDS_FIELD); - ulong[][] A24 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] A24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); ulong mask; uint i, nbits, bit, swap, prevbit = 0; @@ -289,14 +289,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Complete point on A = 0 curve protected internal void CompletePoint(PointProj P, PointProjFull R) { - ulong[][] xz = Utils.InitArray(2, engine.param.NWORDS_FIELD), - s2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - r2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - yz = Utils.InitArray(2, engine.param.NWORDS_FIELD), - invz = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - one = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] xz = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + s2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + r2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + yz = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + invz = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + one = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fpcopy(engine.param.Montgomery_one, 0, one[0]); engine.fpx.fp2mul_mont(P.X, P.Z, xz); @@ -346,9 +346,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: projective Montgomery points P <- 2*P = (X2P:Z2P) such that x(2P)=X2P/Z2P, and Q <- P+Q = (XQP:ZQP) such that = x(Q+P)=XQP/ZQP. protected internal void xDBLADD(PointProj P, PointProj Q, ulong[][] xPQ, ulong[][] A24) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.mp2_add(P.X, P.Z, t0); // t0 = XP+ZP engine.fpx.mp2_sub_p2(P.X, P.Z, t1); // t1 = XP-ZP @@ -389,8 +389,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: projective Montgomery x-coordinates Q = 2*P = (X2:Z2). protected void xDBL(PointProj P, PointProj Q, ulong[][] A24plus, ulong[][] C24) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.mp2_sub_p2(P.X, P.Z, t0); // t0 = X1-Z1 engine.fpx.mp2_add(P.X, P.Z, t1); // t1 = X1+Z1 @@ -409,13 +409,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: projective Montgomery x-coordinates Q = 3*P = (X3:Z3). private void xTPL(PointProj P, PointProj Q, ulong[][] A24minus, ulong[][] A24plus) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t3 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t4 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t5 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t6 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t3 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t4 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t5 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t6 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.mp2_sub_p2(P.X, P.Z, t0); // t0 = X-Z engine.fpx.fp2sqr_mont(t0, t2); // t2 = (X-Z)^2 @@ -459,9 +459,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: the coefficient A corresponding to the curve E_A: y^2=x^3+A*x^2+x. protected internal void get_A(ulong[][] xP, ulong[][] xQ, ulong[][] xR, ulong[][] A) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - one = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + one = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fpcopy(engine.param.Montgomery_one, 0, one[0]); engine.fpx.fp2add(xP, xQ, t1); // t1 = xP+xQ @@ -484,8 +484,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: j=256*(A^2-3*C^2)^3/(C^4*(A^2-4*C^2)), which is the j-invariant of the Montgomery curve B*y^2=x^3+(A/C)*x^2+x or (equivalently) j-invariant of B'*y^2=C*x^3+A*x^2+C*x. protected internal void j_inv(ulong[][] A, ulong[][] C, ulong[][] jinv) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2sqr_mont(A, jinv); // jinv = A^2 engine.fpx.fp2sqr_mont(C, t1); // t1 = C^2 @@ -512,11 +512,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: the 3-isogenous Montgomery curve with projective coefficient A/C. protected internal void get_3_isog(PointProj P, ulong[][] A24minus, ulong[][] A24plus, ulong[][][] coeff) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t3 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t4 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t3 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t4 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.mp2_sub_p2(P.X, P.Z, coeff[0]); // coeff0 = X-Z engine.fpx.fp2sqr_mont(coeff[0], t0); // t0 = (X-Z)^2 @@ -542,9 +542,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: the projective point Q <- phi(Q) = (X3:Z3). protected internal void eval_3_isog(PointProj Q, ulong[][][] coeff) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.mp2_add(Q.X, Q.Z, t0); // t0 = X+Z engine.fpx.mp2_sub_p2(Q.X, Q.Z, t1); // t1 = X-Z @@ -563,10 +563,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: 1/z1,1/z2,1/z3 (override inputs). protected internal void inv_3_way(ulong[][] z1, ulong[][] z2, ulong[][] z3) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t3 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t3 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2mul_mont(z1, z2, t0); // t0 = z1*z2 engine.fpx.fp2mul_mont(z3, t0, t1); // t1 = z1*z2*z3 @@ -593,10 +593,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: the projective point P = phi(P) = (X:Z) in the codomain. protected internal void eval_2_isog(PointProj P, PointProj Q) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t3 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t3 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.mp2_add(Q.X, Q.Z, t0); // t0 = X2+Z2 engine.fpx.mp2_sub_p2(Q.X, Q.Z, t1); // t1 = X2-Z2 @@ -633,8 +633,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike // Output: the projective point P = phi(P) = (X:Z) in the codomain. protected internal void eval_4_isog(PointProj P, ulong[][][] coeff) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.mp2_add(P.X, P.Z, t0); // t0 = X+Z engine.fpx.mp2_sub_p2(P.X, P.Z, t1); // t1 = X-Z diff --git a/crypto/src/pqc/crypto/sike/PointProj.cs b/crypto/src/pqc/crypto/sike/PointProj.cs index 4f6e8b882..a9c82c249 100644 --- a/crypto/src/pqc/crypto/sike/PointProj.cs +++ b/crypto/src/pqc/crypto/sike/PointProj.cs @@ -1,14 +1,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike { -internal class PointProj -{ - internal PointProj(uint nwords_field) + internal sealed class PointProj { - X = Utils.InitArray(2, nwords_field); - Z = Utils.InitArray(2, nwords_field); + internal PointProj(uint nwords_field) + { + X = SikeUtilities.InitArray(2, nwords_field); + Z = SikeUtilities.InitArray(2, nwords_field); + } + internal ulong[][] X; + internal ulong[][] Z; } - public ulong[][] X; - public ulong[][] Z; } - -} \ No newline at end of file diff --git a/crypto/src/pqc/crypto/sike/PointProjFull.cs b/crypto/src/pqc/crypto/sike/PointProjFull.cs index 4e717f31a..8153d9c38 100644 --- a/crypto/src/pqc/crypto/sike/PointProjFull.cs +++ b/crypto/src/pqc/crypto/sike/PointProjFull.cs @@ -1,15 +1,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike { -internal class PointProjFull -{ - internal PointProjFull(uint nwords_field) + internal sealed class PointProjFull { - X = Utils.InitArray(2, nwords_field); - Y = Utils.InitArray(2, nwords_field); - Z = Utils.InitArray(2, nwords_field); + internal PointProjFull(uint nwords_field) + { + X = SikeUtilities.InitArray(2, nwords_field); + Y = SikeUtilities.InitArray(2, nwords_field); + Z = SikeUtilities.InitArray(2, nwords_field); + } + internal ulong[][] X; + internal ulong[][] Y; + internal ulong[][] Z; } - public ulong[][] X; - public ulong[][] Y; - public ulong[][] Z; -} } diff --git a/crypto/src/pqc/crypto/sike/SIDH.cs b/crypto/src/pqc/crypto/sike/SIDH.cs index d5a86d6b1..c1d1714f6 100644 --- a/crypto/src/pqc/crypto/sike/SIDH.cs +++ b/crypto/src/pqc/crypto/sike/SIDH.cs @@ -1,10 +1,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike { -internal class SIDH +internal sealed class Sidh { - private SIKEEngine engine; + private readonly SikeEngine engine; - public SIDH(SIKEEngine engine) + public Sidh(SikeEngine engine) { this.engine = engine; } @@ -32,14 +32,14 @@ internal class SIDH PointProj[] pts = new PointProj[engine.param.MAX_INT_POINTS_BOB]; - ulong[][] XPB = Utils.InitArray(2, engine.param.NWORDS_FIELD), - XQB = Utils.InitArray(2, engine.param.NWORDS_FIELD), - XRB = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24plus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24minus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] XPB = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + XQB = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + XRB = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24plus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24minus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); - ulong[][][] coeff = Utils.InitArray(3, 2, engine.param.NWORDS_FIELD); + ulong[][][] coeff = SikeUtilities.InitArray(3, 2, engine.param.NWORDS_FIELD); uint i, row, m, index = 0, npts = 0, ii = 0; uint[] pts_index = new uint[engine.param.MAX_INT_POINTS_BOB]; ulong[] SecretKeyB = new ulong[engine.param.NWORDS_ORDER]; @@ -116,14 +116,14 @@ internal class SIDH phiR = new PointProj(engine.param.NWORDS_FIELD); PointProj[] pts = new PointProj[engine.param.MAX_INT_POINTS_ALICE]; - ulong[][] XPA = Utils.InitArray(2, engine.param.NWORDS_FIELD), - XQA = Utils.InitArray(2, engine.param.NWORDS_FIELD), - XRA = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24plus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - C24 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A = Utils.InitArray(2, engine.param.NWORDS_FIELD); - - ulong[][][] coeff = Utils.InitArray(3, 2, engine.param.NWORDS_FIELD); + ulong[][] XPA = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + XQA = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + XRA = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24plus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + C24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); + + ulong[][][] coeff = SikeUtilities.InitArray(3, 2, engine.param.NWORDS_FIELD); uint index = 0, npts = 0, ii = 0, m, i, row; uint[] pts_index = new uint[engine.param.MAX_INT_POINTS_ALICE]; ulong[] SecretKeyA = new ulong[engine.param.NWORDS_ORDER]; @@ -213,12 +213,12 @@ internal class SIDH { PointProj R = new PointProj(engine.param.NWORDS_FIELD); PointProj[] pts = new PointProj[engine.param.MAX_INT_POINTS_ALICE]; - ulong[][][] PKB = Utils.InitArray(3, 2, engine.param.NWORDS_FIELD), - coeff = Utils.InitArray(3, 2, engine.param.NWORDS_FIELD); - ulong[][] jinv = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24plus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - C24 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][][] PKB = SikeUtilities.InitArray(3, 2, engine.param.NWORDS_FIELD), + coeff = SikeUtilities.InitArray(3, 2, engine.param.NWORDS_FIELD); + ulong[][] jinv = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24plus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + C24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); uint i = 0, row = 0, m = 0, index = 0, npts = 0, ii = 0; uint[] pts_index = new uint[engine.param.MAX_INT_POINTS_ALICE]; @@ -292,13 +292,13 @@ internal class SIDH { PointProj R = new PointProj(engine.param.NWORDS_FIELD); PointProj[] pts = new PointProj[engine.param.MAX_INT_POINTS_BOB]; - ulong[][][] coeff = Utils.InitArray(3, 2, engine.param.NWORDS_FIELD), - PKB = Utils.InitArray(3, 2, engine.param.NWORDS_FIELD); + ulong[][][] coeff = SikeUtilities.InitArray(3, 2, engine.param.NWORDS_FIELD), + PKB = SikeUtilities.InitArray(3, 2, engine.param.NWORDS_FIELD); - ulong[][] jinv = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24plus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24minus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] jinv = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24plus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24minus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); uint i, row, m, index = 0, npts = 0, ii = 0; uint[] pts_index = new uint[engine.param.MAX_INT_POINTS_BOB]; ulong[] SecretKeyB = new ulong[engine.param.NWORDS_ORDER]; diff --git a/crypto/src/pqc/crypto/sike/SIDH_Compressed.cs b/crypto/src/pqc/crypto/sike/SIDH_Compressed.cs index 46a289c97..ca140aa50 100644 --- a/crypto/src/pqc/crypto/sike/SIDH_Compressed.cs +++ b/crypto/src/pqc/crypto/sike/SIDH_Compressed.cs @@ -1,17 +1,19 @@ using System; + using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Sike { -internal class SIDH_Compressed +internal sealed class SidhCompressed { - private SIKEEngine engine; + private readonly SikeEngine engine; - public SIDH_Compressed(SIKEEngine engine) + public SidhCompressed(SikeEngine engine) { this.engine = engine; } + protected void init_basis(ulong[] gen, ulong[][] XP, ulong[][] XQ, ulong[][] XR) { // Initialization of basis points @@ -104,8 +106,8 @@ internal class SIDH_Compressed N = new ulong[engine.param.NWORDS_FIELD], temp0 = new ulong[engine.param.NWORDS_FIELD], temp1 = new ulong[engine.param.NWORDS_FIELD]; - ulong[][] A = Utils.InitArray(2, engine.param.NWORDS_FIELD), - y2 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + y2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); uint t_ptr = 0; // System.out.print("a24: "); @@ -214,12 +216,12 @@ internal class SIDH_Compressed protected void BiQuad_affine(ulong[][] a24, ulong[][] x0, ulong[][] x1, PointProj R) { - ulong[][] Ap2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - aa = Utils.InitArray(2, engine.param.NWORDS_FIELD), - bb = Utils.InitArray(2, engine.param.NWORDS_FIELD), - cc = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] Ap2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + aa = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + bb = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + cc = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2add(a24, a24, Ap2); engine.fpx.fp2add(Ap2, Ap2, Ap2); // Ap2 = a+2 = 4*a24 @@ -275,7 +277,7 @@ internal class SIDH_Compressed protected void eval_dual_2_isog(ulong[][] X2, ulong[][] Z2, PointProj P) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2add(P.X, P.Z, t0); engine.fpx.fp2sub(P.X, P.Z, P.Z); @@ -288,8 +290,8 @@ internal class SIDH_Compressed protected void eval_final_dual_2_isog(PointProj P) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); ulong[] t2 = new ulong[engine.param.NWORDS_FIELD]; engine.fpx.fp2add(P.X, P.Z, t0); @@ -341,10 +343,10 @@ internal class SIDH_Compressed protected void eval_dual_4_isog(ulong[][] A24, ulong[][] C24, ulong[][][] coeff, uint coeffOffset, PointProj P) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t3 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t3 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2add(P.X, P.Z, t0); engine.fpx.fp2sub(P.X, P.Z, t1); @@ -395,8 +397,8 @@ internal class SIDH_Compressed protected void Tate3_proj(PointProjFull P, PointProjFull Q, ulong[][] gX, ulong[][] gZ) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - l1x = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + l1x = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); TripleAndParabola_proj(P, l1x, gZ); engine.fpx.fp2sub(Q.X, P.X, gX); @@ -411,7 +413,7 @@ internal class SIDH_Compressed { uint i; - ulong[][] f_ = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] f_ = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2copy(gZ, f_); engine.fpx.fpnegPRIME(f_[1]); @@ -435,8 +437,8 @@ internal class SIDH_Compressed { uint i, j; - ulong[][][] f_ = Utils.InitArray(2, 2, engine.param.NWORDS_FIELD), - finv = Utils.InitArray(2, 2, engine.param.NWORDS_FIELD); + ulong[][][] f_ = SikeUtilities.InitArray(2, 2, engine.param.NWORDS_FIELD), + finv = SikeUtilities.InitArray(2, 2, engine.param.NWORDS_FIELD); for(i = 0; i < 2; i++) { @@ -467,8 +469,8 @@ internal class SIDH_Compressed PointProjFull R3 = new PointProjFull(engine.param.NWORDS_FIELD), S3 = new PointProjFull(engine.param.NWORDS_FIELD); - ulong[][][] gX = Utils.InitArray(2, 2, engine.param.NWORDS_FIELD), - gZ = Utils.InitArray(2, 2, engine.param.NWORDS_FIELD); + ulong[][][] gX = SikeUtilities.InitArray(2, 2, engine.param.NWORDS_FIELD), + gZ = SikeUtilities.InitArray(2, 2, engine.param.NWORDS_FIELD); ulong[] zero = new ulong[engine.param.NWORDS_FIELD]; uint nbytes = engine.param.NWORDS_FIELD;// (((engine.param.NBITS_FIELD)+7)/8); uint alpha,beta; @@ -583,8 +585,8 @@ internal class SIDH_Compressed { PointProjFull RS3 = new PointProjFull(engine.param.NWORDS_FIELD); - ulong[][] gX = Utils.InitArray(2, engine.param.NWORDS_FIELD), - gZ = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] gX = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + gZ = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); ulong[] zero = new ulong[engine.param.NWORDS_FIELD]; uint nbytes = engine.param.NWORDS_FIELD; @@ -725,9 +727,9 @@ internal class SIDH_Compressed protected void makeDiff(PointProjFull R, PointProjFull S, PointProj D) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); uint nbytes = engine.param.NWORDS_FIELD; engine.fpx.fp2sub(R.X, S.X, t0); @@ -752,7 +754,7 @@ internal class SIDH_Compressed { PointProj D = new PointProj(engine.param.NWORDS_FIELD); - ulong[][][] xs = Utils.InitArray(2, 2, engine.param.NWORDS_FIELD); + ulong[][][] xs = SikeUtilities.InitArray(2, 2, engine.param.NWORDS_FIELD); byte[] ind = new byte[1], bit = new byte[1]; @@ -815,14 +817,14 @@ internal class SIDH_Compressed PointProj R = new PointProj(engine.param.NWORDS_FIELD); PointProj[] pts = new PointProj[engine.param.MAX_INT_POINTS_ALICE]; - ulong[][] XPA = Utils.InitArray(2, engine.param.NWORDS_FIELD), - XQA = Utils.InitArray(2, engine.param.NWORDS_FIELD), - XRA = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - C24 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] XPA = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + XQA = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + XRA = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + C24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); - ulong[][][] coeff = Utils.InitArray(5, 2, engine.param.NWORDS_FIELD); + ulong[][][] coeff = SikeUtilities.InitArray(5, 2, engine.param.NWORDS_FIELD); uint i, row, m, index = 0, npts = 0, ii = 0; uint[] pts_index = new uint[engine.param.MAX_INT_POINTS_ALICE]; @@ -1074,7 +1076,7 @@ internal class SIDH_Compressed { byte bit; uint[] rs = new uint[3]; - ulong[][] A24 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] A24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); PointProj[] Rs = new PointProj[3]; Rs[0] = new PointProj(engine.param.NWORDS_FIELD); Rs[1] = new PointProj(engine.param.NWORDS_FIELD); @@ -1159,7 +1161,7 @@ internal class SIDH_Compressed uint bit; ulong[] temp = new ulong[engine.param.NWORDS_ORDER], inv = new ulong[engine.param.NWORDS_ORDER]; - ulong[][] A = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2add(a24,a24,A); engine.fpx.fp2add(A,A,A); @@ -1233,10 +1235,10 @@ internal class SIDH_Compressed { uint[] rs = new uint[3]; int[] D = new int[engine.param.DLEN_3]; - ulong[][] a24 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] a24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); - ulong[][][][] As = Utils.InitArray(engine.param.MAX_Alice + 1, 5, 2, engine.param.NWORDS_FIELD); - ulong[][][] f = Utils.InitArray(4, 2, engine.param.NWORDS_FIELD); + ulong[][][][] As = SikeUtilities.InitArray(engine.param.MAX_Alice + 1, 5, 2, engine.param.NWORDS_FIELD); + ulong[][][] f = SikeUtilities.InitArray(4, 2, engine.param.NWORDS_FIELD); ulong[] c0 = new ulong[engine.param.NWORDS_ORDER], d0 = new ulong[engine.param.NWORDS_ORDER], c1 = new ulong[engine.param.NWORDS_ORDER], @@ -1309,9 +1311,9 @@ internal class SIDH_Compressed d0 = new ulong[engine.param.NWORDS_ORDER], c1 = new ulong[engine.param.NWORDS_ORDER], d1 = new ulong[engine.param.NWORDS_ORDER]; - ulong[][] a24 = Utils.InitArray(2, engine.param.NWORDS_FIELD); - ulong[][][] f = Utils.InitArray(4, 2, engine.param.NWORDS_FIELD); - ulong[][][][] As = Utils.InitArray(engine.param.MAX_Alice + 1, 5, 2, engine.param.NWORDS_FIELD); + ulong[][] a24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][][] f = SikeUtilities.InitArray(4, 2, engine.param.NWORDS_FIELD); + ulong[][][][] As = SikeUtilities.InitArray(engine.param.MAX_Alice + 1, 5, 2, engine.param.NWORDS_FIELD); PointProjFull[] Rs = new PointProjFull[2]; FullIsogeny_A_dual(PrivateKeyA, As, a24, 0); @@ -1331,14 +1333,14 @@ internal class SIDH_Compressed { uint i, ii = 0, row, m, index = 0, npts = 0; uint[] pts_index = new uint[engine.param.MAX_INT_POINTS_BOB]; - ulong[][] A24plus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24minus = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] A24plus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24minus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); PointProj R = new PointProj(engine.param.NWORDS_FIELD); PointProj[] pts = new PointProj[engine.param.MAX_INT_POINTS_BOB]; - ulong[][] jinv = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A = Utils.InitArray(2, engine.param.NWORDS_FIELD); - ulong[][][] coeff = Utils.InitArray(3, 2, engine.param.NWORDS_FIELD); - ulong[][] param_A = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] jinv = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][][] coeff = SikeUtilities.InitArray(3, 2, engine.param.NWORDS_FIELD); + ulong[][] param_A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); PKADecompression_dual(PrivateKeyB, PKA, R, param_A); engine.fpx.fp2copy(param_A, A); @@ -1392,8 +1394,8 @@ internal class SIDH_Compressed { ulong[] s = new ulong[engine.param.NWORDS_FIELD]; ulong[][] t_ptr, - r = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t = Utils.InitArray(2, engine.param.NWORDS_FIELD); + r = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); uint t_ptrOffset = 0; // Select the correct table @@ -1457,11 +1459,11 @@ internal class SIDH_Compressed protected void RecoverY(ulong[][] A, PointProj[] xs, PointProjFull[] Rs) { - ulong[][] t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t3 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t4 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t3 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t4 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fp2mul_mont(xs[2].X, xs[1].Z, t0); engine.fpx.fp2mul_mont(xs[1].X, xs[2].Z, t1); @@ -1500,7 +1502,7 @@ internal class SIDH_Compressed { uint i; ulong[] t0 = new ulong[engine.param.NWORDS_FIELD]; - ulong[][] A6 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] A6 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); PointProj[] xs = new PointProj[3]; xs[0] = new PointProj(engine.param.NWORDS_FIELD); xs[1] = new PointProj(engine.param.NWORDS_FIELD); @@ -1566,12 +1568,12 @@ internal class SIDH_Compressed PointProj R = new PointProj(engine.param.NWORDS_FIELD), Q3 = new PointProj(engine.param.NWORDS_FIELD); PointProj[] pts = new PointProj[engine.param.MAX_INT_POINTS_BOB]; - ulong[][] XPB = Utils.InitArray(2, engine.param.NWORDS_FIELD), - XQB = Utils.InitArray(2, engine.param.NWORDS_FIELD), - XRB = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24plus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24minus = Utils.InitArray(2, engine.param.NWORDS_FIELD); - ulong[][][] coeff = Utils.InitArray(3, 2, engine.param.NWORDS_FIELD); + ulong[][] XPB = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + XQB = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + XRB = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24plus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24minus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][][] coeff = SikeUtilities.InitArray(3, 2, engine.param.NWORDS_FIELD); uint i, row, m, index = 0, npts = 0, ii = 0; uint[] pts_index = new uint[engine.param.MAX_INT_POINTS_BOB]; ulong[] SecretKeyB = new ulong[engine.param.NWORDS_ORDER]; @@ -1663,8 +1665,8 @@ internal class SIDH_Compressed protected void BuildEntangledXonly_Decomp(ulong[][] A, PointProj[] R, uint qnr, uint ind) { ulong[][] t_ptr, - r = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t = Utils.InitArray(2, engine.param.NWORDS_FIELD); + r = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); // Select the correct table if ( qnr == 1 ) @@ -1716,8 +1718,8 @@ internal class SIDH_Compressed { ulong mask = unchecked((ulong) -1L); uint qnr, ind; - ulong[][] A24 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - Adiv2 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] A24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + Adiv2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); ulong[] tmp1 = new ulong[2*engine.param.NWORDS_ORDER], tmp2 = new ulong[2*engine.param.NWORDS_ORDER], @@ -1879,7 +1881,7 @@ internal class SIDH_Compressed ulong mask = unchecked((ulong) -1L); uint bit,qnr,ind; - ulong[][] A24 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] A24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); ulong[] tmp1 = new ulong[2*engine.param.NWORDS_ORDER], tmp2 = new ulong[2*engine.param.NWORDS_ORDER], vone = new ulong[2*engine.param.NWORDS_ORDER], @@ -1996,9 +1998,9 @@ internal class SIDH_Compressed d0 = new ulong[engine.param.NWORDS_ORDER], c1 = new ulong[engine.param.NWORDS_ORDER], d1 = new ulong[engine.param.NWORDS_ORDER]; - ulong[][][][] Ds = Utils.InitArray(engine.param.MAX_Bob, 2, 2, engine.param.NWORDS_FIELD); - ulong[][][] f = Utils.InitArray(4, 2, engine.param.NWORDS_FIELD); - ulong[][] A = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][][][] Ds = SikeUtilities.InitArray(engine.param.MAX_Bob, 2, 2, engine.param.NWORDS_FIELD); + ulong[][][] f = SikeUtilities.InitArray(4, 2, engine.param.NWORDS_FIELD); + ulong[][] A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); PointProjFull[] Rs = new PointProjFull[2]; Rs[0] = new PointProjFull(engine.param.NWORDS_FIELD); @@ -2122,15 +2124,15 @@ internal class SIDH_Compressed { uint i, ii = 0, row, m, index = 0, npts = 0; uint[] pts_index = new uint[engine.param.MAX_INT_POINTS_ALICE]; - ulong[][] A24plus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - C24 = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] A24plus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + C24 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); PointProj R = new PointProj(engine.param.NWORDS_FIELD); PointProj[] pts = new PointProj[engine.param.MAX_INT_POINTS_ALICE]; - ulong[][] jinv = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A = Utils.InitArray(2, engine.param.NWORDS_FIELD), - param_A = Utils.InitArray(2, engine.param.NWORDS_FIELD); - ulong[][][] coeff = Utils.InitArray(5, 2, engine.param.NWORDS_FIELD); + ulong[][] jinv = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + param_A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][][] coeff = SikeUtilities.InitArray(5, 2, engine.param.NWORDS_FIELD); if (sike == 1) @@ -2216,16 +2218,16 @@ internal class SIDH_Compressed PointProj R = new PointProj(engine.param.NWORDS_FIELD), S = new PointProj(engine.param.NWORDS_FIELD); - ulong[][] XPB = Utils.InitArray(2, engine.param.NWORDS_FIELD), - XQB = Utils.InitArray(2, engine.param.NWORDS_FIELD), - XRB = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24plus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A24minus = Utils.InitArray(2, engine.param.NWORDS_FIELD), - A = Utils.InitArray(2, engine.param.NWORDS_FIELD), - comp1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - comp2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - one = Utils.InitArray(2, engine.param.NWORDS_FIELD); - ulong[][][] coeff = Utils.InitArray(3, 2, engine.param.NWORDS_FIELD);; + ulong[][] XPB = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + XQB = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + XRB = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24plus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A24minus = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + A = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + comp1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + comp2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + one = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][][] coeff = SikeUtilities.InitArray(3, 2, engine.param.NWORDS_FIELD);; uint i, row, m, index = 0, npts = 0, ii = 0; uint[] pts_index = new uint[engine.param.MAX_INT_POINTS_BOB]; @@ -2455,8 +2457,8 @@ internal class SIDH_Compressed void Traverse_w_notdiv_e_fullsigned(ulong[][] r, uint j, uint k, uint z, uint[] P, ulong[] CT1, ulong[] CT2, int[] D, uint Dlen, uint ell, uint ellw, uint ell_emodw, uint w, uint e) { - ulong[][] rp = Utils.InitArray(2, engine.param.NWORDS_FIELD), - alpha = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] rp = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + alpha = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); if (z > 1) @@ -2633,8 +2635,8 @@ internal class SIDH_Compressed // Assume the integer w divides the exponent e void Traverse_w_div_e_fullsigned(ulong[][] r, uint j, uint k, uint z, uint[] P, ulong[] CT, int[] D, uint Dlen, uint ellw, uint w) { - ulong[][] rp = Utils.InitArray(2, engine.param.NWORDS_FIELD), - alpha = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] rp = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + alpha = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); if (z > 1) { @@ -2729,18 +2731,18 @@ internal class SIDH_Compressed x23 = new ulong[engine.param.NWORDS_FIELD], x2p3 = new ulong[engine.param.NWORDS_FIELD]; - ulong[][][] xQ2s = Utils.InitArray(t_points, 2, engine.param.NWORDS_FIELD), - finv = Utils.InitArray(2*t_points, 2, engine.param.NWORDS_FIELD); - ulong[][] one = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t2 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t3 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t4 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t5 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - g = Utils.InitArray(2, engine.param.NWORDS_FIELD), - h = Utils.InitArray(2, engine.param.NWORDS_FIELD), - tf = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][][] xQ2s = SikeUtilities.InitArray(t_points, 2, engine.param.NWORDS_FIELD), + finv = SikeUtilities.InitArray(2*t_points, 2, engine.param.NWORDS_FIELD); + ulong[][] one = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t2 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t3 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t4 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t5 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + g = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + h = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + tf = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); engine.fpx.fpcopy(engine.param.Montgomery_one, 0, one[0]); @@ -2919,7 +2921,7 @@ internal class SIDH_Compressed private void final_exponentiation_3_torsion(ulong[][] f, ulong[][] finv, ulong[][] fout) { ulong[] one = new ulong[engine.param.NWORDS_FIELD]; - ulong[][] temp = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] temp = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); uint i; engine.fpx.fpcopy(engine.param.Montgomery_one, 0, one); @@ -2938,16 +2940,16 @@ internal class SIDH_Compressed private void Tate2_pairings(PointProj P, PointProj Q, PointProjFull[] Qj, ulong[][][] f) { ulong[] x, y, x_, y_, l1; - ulong[][][] finv = Utils.InitArray(2 * t_points, 2, engine.param.NWORDS_FIELD); + ulong[][][] finv = SikeUtilities.InitArray(2 * t_points, 2, engine.param.NWORDS_FIELD); ulong[][] x_first, y_first, - one = Utils.InitArray(2, engine.param.NWORDS_FIELD), - l1_first = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t0 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - t1 = Utils.InitArray(2, engine.param.NWORDS_FIELD), - g = Utils.InitArray(2, engine.param.NWORDS_FIELD), - h = Utils.InitArray(2, engine.param.NWORDS_FIELD); + one = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + l1_first = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t0 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + t1 = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + g = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD), + h = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); uint x_Offset, y_Offset, l1Offset, xOffset, yOffset; @@ -3141,7 +3143,7 @@ internal class SIDH_Compressed private void final_exponentiation_2_torsion(ulong[][] f, ulong[][] finv, ulong[][] fout) { ulong[] one = new ulong[engine.param.NWORDS_FIELD]; - ulong[][] temp = Utils.InitArray(2, engine.param.NWORDS_FIELD); + ulong[][] temp = SikeUtilities.InitArray(2, engine.param.NWORDS_FIELD); uint i; engine.fpx.fpcopy(engine.param.Montgomery_one, 0, one); diff --git a/crypto/src/pqc/crypto/sike/SIKEEngine.cs b/crypto/src/pqc/crypto/sike/SIKEEngine.cs index e7b218589..6a825fe44 100644 --- a/crypto/src/pqc/crypto/sike/SIKEEngine.cs +++ b/crypto/src/pqc/crypto/sike/SIKEEngine.cs @@ -4,16 +4,15 @@ using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Pqc.Crypto.Sike { - -internal class SIKEEngine +internal sealed class SikeEngine { - private SecureRandom random; - + //private readonly SecureRandom random; + protected internal Internal param; protected internal Isogeny isogeny; protected internal Fpx fpx; - private SIDH sidh; - private SIDH_Compressed sidhCompressed; + private Sidh sidh; + private SidhCompressed sidhCompressed; private bool isCompressed; public uint GetDefaultSessionKeySize() @@ -35,9 +34,9 @@ internal class SIKEEngine { return param.CRYPTO_PUBLICKEYBYTES; } - public SIKEEngine(int ver, bool isCompressed, SecureRandom random) + public SikeEngine(int ver, bool isCompressed, SecureRandom random) { - this.random = random; + //this.random = random; this.isCompressed = isCompressed; //todo switch for different parameters switch(ver) @@ -62,9 +61,9 @@ internal class SIKEEngine isogeny = new Isogeny(this); if(isCompressed) { - sidhCompressed = new SIDH_Compressed(this); + sidhCompressed = new SidhCompressed(this); } - sidh = new SIDH(this); + sidh = new Sidh(this); } // SIKE's key generation diff --git a/crypto/src/pqc/crypto/sike/SIKEKEMExtractor.cs b/crypto/src/pqc/crypto/sike/SIKEKEMExtractor.cs index 144b4649f..3c523ba8c 100644 --- a/crypto/src/pqc/crypto/sike/SIKEKEMExtractor.cs +++ b/crypto/src/pqc/crypto/sike/SIKEKEMExtractor.cs @@ -1,43 +1,42 @@ -using Org.BouncyCastle.Crypto; using System; +using Org.BouncyCastle.Crypto; + namespace Org.BouncyCastle.Pqc.Crypto.Sike { - public class SIKEKEMExtractor + public sealed class SikeKemExtractor : IEncapsulatedSecretExtractor { - private SIKEEngine engine; - - private SIKEKeyParameters key; - - public SIKEKEMExtractor(SIKEPrivateKeyParameters privParams) - { - this.key = privParams; - InitCipher(key.GetParameters()); - } - - private void InitCipher(SIKEParameters param) - { - engine = param.GetEngine(); - SIKEPrivateKeyParameters privateParams = (SIKEPrivateKeyParameters)key; - //todo: add compression check - } - - public byte[] ExtractSecret(byte[] encapsulation) - { - return ExtractSecret(encapsulation, engine.GetDefaultSessionKeySize()); - } - - public byte[] ExtractSecret(byte[] encapsulation, uint sessionKeySizeInBits) - { + private readonly SikeKeyParameters key; + + private SikeEngine engine; + + public SikeKemExtractor(SikePrivateKeyParameters privParams) + { + this.key = privParams; + InitCipher(key.Parameters); + } + + private void InitCipher(SikeParameters param) + { + engine = param.Engine; + SikePrivateKeyParameters privateParams = (SikePrivateKeyParameters)key; + //todo: add compression check + } + + public byte[] ExtractSecret(byte[] encapsulation) + { + return ExtractSecret(encapsulation, engine.GetDefaultSessionKeySize()); + } + + public byte[] ExtractSecret(byte[] encapsulation, uint sessionKeySizeInBits) + { Console.Error.WriteLine("WARNING: the SIKE algorithm is only for research purposes, insecure"); - byte[] session_key = new byte[sessionKeySizeInBits / 8]; - engine.crypto_kem_dec(session_key, encapsulation, ((SIKEPrivateKeyParameters)key).GetPrivateKey()); - return session_key; - } + byte[] session_key = new byte[sessionKeySizeInBits / 8]; + engine.crypto_kem_dec(session_key, encapsulation, ((SikePrivateKeyParameters)key).GetPrivateKey()); + return session_key; + } public int EncapsulationLength => (int)engine.GetCipherTextSize(); - } - -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/sike/SIKEKEMGenerator.cs b/crypto/src/pqc/crypto/sike/SIKEKEMGenerator.cs index cf98a0696..76689496f 100644 --- a/crypto/src/pqc/crypto/sike/SIKEKEMGenerator.cs +++ b/crypto/src/pqc/crypto/sike/SIKEKEMGenerator.cs @@ -1,40 +1,39 @@ +using System; + using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Pqc.Crypto.Utilities; using Org.BouncyCastle.Security; -using System; namespace Org.BouncyCastle.Pqc.Crypto.Sike { -public class SIKEKEMGenerator - : IEncapsulatedSecretGenerator -{ - // the source of randomness - private SecureRandom sr; - - - public SIKEKEMGenerator(SecureRandom random) + public sealed class SikeKemGenerator + : IEncapsulatedSecretGenerator { - this.sr = random; - } + // the source of randomness + private readonly SecureRandom sr; - public ISecretWithEncapsulation GenerateEncapsulated(AsymmetricKeyParameter recipientKey) - { - SIKEPublicKeyParameters key = (SIKEPublicKeyParameters)recipientKey; - SIKEEngine engine = key.GetParameters().GetEngine(); + public SikeKemGenerator(SecureRandom random) + { + this.sr = CryptoServicesRegistrar.GetSecureRandom(random); + } - return GenerateEncapsulated(recipientKey, engine.GetDefaultSessionKeySize()); - } + public ISecretWithEncapsulation GenerateEncapsulated(AsymmetricKeyParameter recipientKey) + { + SikePublicKeyParameters key = (SikePublicKeyParameters)recipientKey; + SikeEngine engine = key.Parameters.Engine; - public ISecretWithEncapsulation GenerateEncapsulated(AsymmetricKeyParameter recipientKey, uint sessionKeySizeInBits) - { + return GenerateEncapsulated(recipientKey, engine.GetDefaultSessionKeySize()); + } + + public ISecretWithEncapsulation GenerateEncapsulated(AsymmetricKeyParameter recipientKey, uint sessionKeySizeInBits) + { Console.Error.WriteLine("WARNING: the SIKE algorithm is only for research purposes, insecure"); - SIKEPublicKeyParameters key = (SIKEPublicKeyParameters)recipientKey; - SIKEEngine engine = key.GetParameters().GetEngine(); - byte[] cipher_text = new byte[engine.GetCipherTextSize()]; - byte[] sessionKey = new byte[sessionKeySizeInBits / 8]; - engine.crypto_kem_enc(cipher_text, sessionKey, key.GetPublicKey(), sr); - return new SecretWithEncapsulationImpl(sessionKey, cipher_text); + SikePublicKeyParameters key = (SikePublicKeyParameters)recipientKey; + SikeEngine engine = key.Parameters.Engine; + byte[] cipher_text = new byte[engine.GetCipherTextSize()]; + byte[] sessionKey = new byte[sessionKeySizeInBits / 8]; + engine.crypto_kem_enc(cipher_text, sessionKey, key.GetPublicKey(), sr); + return new SecretWithEncapsulationImpl(sessionKey, cipher_text); + } } } - -} \ No newline at end of file diff --git a/crypto/src/pqc/crypto/sike/SIKEKeyGenerationParameters.cs b/crypto/src/pqc/crypto/sike/SIKEKeyGenerationParameters.cs index 669a417b2..353587637 100644 --- a/crypto/src/pqc/crypto/sike/SIKEKeyGenerationParameters.cs +++ b/crypto/src/pqc/crypto/sike/SIKEKeyGenerationParameters.cs @@ -3,23 +3,17 @@ using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Pqc.Crypto.Sike { -public class SIKEKeyGenerationParameters - : KeyGenerationParameters -{ - private SIKEParameters param; - - public SIKEKeyGenerationParameters( - SecureRandom random, - SIKEParameters sikeParameters - ) - : base(random, 256) - { - this.param = sikeParameters; - } - public SIKEParameters GetParameters() + public sealed class SikeKeyGenerationParameters + : KeyGenerationParameters { - return param; + private readonly SikeParameters m_parameters; + + public SikeKeyGenerationParameters(SecureRandom random, SikeParameters sikeParameters) + : base(random, 256) + { + m_parameters = sikeParameters; + } + + public SikeParameters Parameters => m_parameters; } } - -} \ No newline at end of file diff --git a/crypto/src/pqc/crypto/sike/SIKEKeyPairGenerator.cs b/crypto/src/pqc/crypto/sike/SIKEKeyPairGenerator.cs index 3945fe8c8..3ba67faa9 100644 --- a/crypto/src/pqc/crypto/sike/SIKEKeyPairGenerator.cs +++ b/crypto/src/pqc/crypto/sike/SIKEKeyPairGenerator.cs @@ -3,30 +3,29 @@ using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Pqc.Crypto.Sike { - public class SIKEKeyPairGenerator + public sealed class SikeKeyPairGenerator : IAsymmetricCipherKeyPairGenerator { - private SIKEKeyGenerationParameters sikeParams; + private SikeKeyGenerationParameters sikeParams; private SecureRandom random; private void Initialize(KeyGenerationParameters param) { - this.sikeParams = (SIKEKeyGenerationParameters) param; + this.sikeParams = (SikeKeyGenerationParameters) param; this.random = param.Random; } private AsymmetricCipherKeyPair GenKeyPair() { - SIKEEngine engine = sikeParams.GetParameters().GetEngine(); + SikeEngine engine = sikeParams.Parameters.Engine; byte[] sk = new byte[engine.GetPrivateKeySize()]; byte[] pk = new byte[engine.GetPublicKeySize()]; engine.crypto_kem_keypair(pk, sk, random); - - SIKEPublicKeyParameters pubKey = new SIKEPublicKeyParameters(sikeParams.GetParameters(), pk); - SIKEPrivateKeyParameters privKey = new SIKEPrivateKeyParameters(sikeParams.GetParameters(), sk); + SikePublicKeyParameters pubKey = new SikePublicKeyParameters(sikeParams.Parameters, pk); + SikePrivateKeyParameters privKey = new SikePrivateKeyParameters(sikeParams.Parameters, sk); return new AsymmetricCipherKeyPair(pubKey, privKey); } @@ -40,5 +39,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike return GenKeyPair(); } } - -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/sike/SIKEKeyParameters.cs b/crypto/src/pqc/crypto/sike/SIKEKeyParameters.cs index 29ef6114d..5d515eb1d 100644 --- a/crypto/src/pqc/crypto/sike/SIKEKeyParameters.cs +++ b/crypto/src/pqc/crypto/sike/SIKEKeyParameters.cs @@ -2,24 +2,17 @@ using Org.BouncyCastle.Crypto; namespace Org.BouncyCastle.Pqc.Crypto.Sike { -public class SIKEKeyParameters - : AsymmetricKeyParameter -{ - private SIKEParameters param; - - public SIKEKeyParameters( - bool isPrivate, - SIKEParameters param - ) - :base(isPrivate) + public abstract class SikeKeyParameters + : AsymmetricKeyParameter { - this.param = param; - } + private readonly SikeParameters m_parameters; - public SIKEParameters GetParameters() - { - return param; + public SikeKeyParameters(bool isPrivate, SikeParameters param) + : base(isPrivate) + { + this.m_parameters = param; + } + + public SikeParameters Parameters => m_parameters; } } - -} \ No newline at end of file diff --git a/crypto/src/pqc/crypto/sike/SIKEParameters.cs b/crypto/src/pqc/crypto/sike/SIKEParameters.cs index d687871ec..3aa332341 100644 --- a/crypto/src/pqc/crypto/sike/SIKEParameters.cs +++ b/crypto/src/pqc/crypto/sike/SIKEParameters.cs @@ -1,33 +1,30 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike { -public class SIKEParameters -{ + public sealed class SikeParameters + { + public static readonly SikeParameters sikep434 = new SikeParameters(434, false, "sikep434"); + public static readonly SikeParameters sikep503 = new SikeParameters(503, false, "sikep503"); + public static readonly SikeParameters sikep610 = new SikeParameters(610, false, "sikep610"); + public static readonly SikeParameters sikep751 = new SikeParameters(751, false, "sikep751"); - public static SIKEParameters sikep434 = new SIKEParameters(434, false,"sikep434"); - public static SIKEParameters sikep503 = new SIKEParameters(503, false,"sikep503"); - public static SIKEParameters sikep610 = new SIKEParameters(610, false,"sikep610"); - public static SIKEParameters sikep751 = new SIKEParameters(751, false,"sikep751"); + public static readonly SikeParameters sikep434_compressed = new SikeParameters(434, true, "sikep434_compressed"); + public static readonly SikeParameters sikep503_compressed = new SikeParameters(503, true, "sikep503_compressed"); + public static readonly SikeParameters sikep610_compressed = new SikeParameters(610, true, "sikep610_compressed"); + public static readonly SikeParameters sikep751_compressed = new SikeParameters(751, true, "sikep751_compressed"); - public static SIKEParameters sikep434_compressed = new SIKEParameters(434, true,"sikep434_compressed"); - public static SIKEParameters sikep503_compressed = new SIKEParameters(503, true,"sikep503_compressed"); - public static SIKEParameters sikep610_compressed = new SIKEParameters(610, true,"sikep610_compressed"); - public static SIKEParameters sikep751_compressed = new SIKEParameters(751, true,"sikep751_compressed"); + private readonly string name; + private readonly SikeEngine engine; - private string name; - private SIKEEngine engine; - public SIKEParameters(int ver, bool isCompressed, string name) - { - this.name = name; - this.engine = new SIKEEngine(ver, isCompressed, null); - } + public SikeParameters(int ver, bool isCompressed, string name) + { + this.name = name; + this.engine = new SikeEngine(ver, isCompressed, null); + } - internal SIKEEngine GetEngine() - { - return engine; - } + internal SikeEngine Engine => engine; public string Name => name; + public int DefaultKeySize => (int)this.engine.GetDefaultSessionKeySize(); } - -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/sike/SIKEPrivateKeyParameters.cs b/crypto/src/pqc/crypto/sike/SIKEPrivateKeyParameters.cs index e3e791e71..0666ffb72 100644 --- a/crypto/src/pqc/crypto/sike/SIKEPrivateKeyParameters.cs +++ b/crypto/src/pqc/crypto/sike/SIKEPrivateKeyParameters.cs @@ -2,26 +2,25 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Sike { -public class SIKEPrivateKeyParameters - : SIKEKeyParameters -{ - private byte[] privateKey; - - public byte[] GetPrivateKey() + public sealed class SikePrivateKeyParameters + : SikeKeyParameters { - return Arrays.Clone(privateKey); - } + private readonly byte[] privateKey; - public SIKEPrivateKeyParameters(SIKEParameters param, byte[] privateKey) - :base(true, param) - { - this.privateKey = Arrays.Clone(privateKey); - } + public SikePrivateKeyParameters(SikeParameters param, byte[] privateKey) + : base(true, param) + { + this.privateKey = Arrays.Clone(privateKey); + } - public byte[] GetEncoded() - { - return Arrays.Clone(privateKey); + public byte[] GetEncoded() + { + return Arrays.Clone(privateKey); + } + + public byte[] GetPrivateKey() + { + return Arrays.Clone(privateKey); + } } } - -} \ No newline at end of file diff --git a/crypto/src/pqc/crypto/sike/SIKEPublicKeyParameters.cs b/crypto/src/pqc/crypto/sike/SIKEPublicKeyParameters.cs index a777d7896..b567e979c 100644 --- a/crypto/src/pqc/crypto/sike/SIKEPublicKeyParameters.cs +++ b/crypto/src/pqc/crypto/sike/SIKEPublicKeyParameters.cs @@ -2,26 +2,25 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Sike { -public class SIKEPublicKeyParameters - : SIKEKeyParameters -{ - public byte[] publicKey; - - public byte[] GetPublicKey() + public sealed class SikePublicKeyParameters + : SikeKeyParameters { - return Arrays.Clone(publicKey); - } + public readonly byte[] publicKey; - public byte[] GetEncoded() - { - return GetPublicKey(); - } + public SikePublicKeyParameters(SikeParameters param, byte[] publicKey) + : base(false, param) + { + this.publicKey = Arrays.Clone(publicKey); + } - public SIKEPublicKeyParameters(SIKEParameters param, byte[] publicKey) - : base(false, param) - { - this.publicKey = Arrays.Clone(publicKey); + public byte[] GetEncoded() + { + return Arrays.Clone(publicKey); + } + + public byte[] GetPublicKey() + { + return Arrays.Clone(publicKey); + } } } - -} \ No newline at end of file diff --git a/crypto/src/pqc/crypto/sike/Utils.cs b/crypto/src/pqc/crypto/sike/SikeUtilities.cs index 013e39316..ca5ee67a0 100644 --- a/crypto/src/pqc/crypto/sike/Utils.cs +++ b/crypto/src/pqc/crypto/sike/SikeUtilities.cs @@ -1,8 +1,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike { - internal class Utils + internal static class SikeUtilities { - public static ulong[][] InitArray(uint size1, uint size2) + internal static ulong[][] InitArray(uint size1, uint size2) { ulong[][] res = new ulong[size1][]; for (int i = 0; i < size1; i++) @@ -12,8 +12,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike return res; } - - public static ulong[][][] InitArray(uint size1, uint size2, uint size3) + + internal static ulong[][][] InitArray(uint size1, uint size2, uint size3) { ulong[][][] res = new ulong[size1][][]; for (int i = 0; i < size1; i++) @@ -27,8 +27,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike return res; } - - public static ulong[][][][] InitArray(uint size1, uint size2, uint size3, uint size4) + + internal static ulong[][][][] InitArray(uint size1, uint size2, uint size3, uint size4) { ulong[][][][] res = new ulong[size1][][][]; for (int i = 0; i < size1; i++) @@ -47,4 +47,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Sike return res; } } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs index 5efafc1db..2134c5c73 100644 --- a/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs +++ b/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs @@ -3,6 +3,7 @@ using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus { @@ -14,6 +15,61 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus */ internal abstract class HarakaSBase { + private static readonly byte[] RC0 = Hex.DecodeStrict("0684704ce620c00ab2c5fef075817b9d"); + private static readonly byte[] RC1 = Hex.DecodeStrict("8b66b4e188f3a06b640f6ba42f08f717"); + private static readonly byte[] RC2 = Hex.DecodeStrict("3402de2d53f28498cf029d609f029114"); + private static readonly byte[] RC3 = Hex.DecodeStrict("0ed6eae62e7b4f08bbf3bcaffd5b4f79"); + private static readonly byte[] RC4 = Hex.DecodeStrict("cbcfb0cb4872448b79eecd1cbe397044"); + private static readonly byte[] RC5 = Hex.DecodeStrict("7eeacdee6e9032b78d5335ed2b8a057b"); + private static readonly byte[] RC6 = Hex.DecodeStrict("67c28f435e2e7cd0e2412761da4fef1b"); + private static readonly byte[] RC7 = Hex.DecodeStrict("2924d9b0afcacc07675ffde21fc70b3b"); + private static readonly byte[] RC8 = Hex.DecodeStrict("ab4d63f1e6867fe9ecdb8fcab9d465ee"); + private static readonly byte[] RC9 = Hex.DecodeStrict("1c30bf84d4b7cd645b2a404fad037e33"); + private static readonly byte[] RC10 = Hex.DecodeStrict("b2cc0bb9941723bf69028b2e8df69800"); + private static readonly byte[] RC11 = Hex.DecodeStrict("fa0478a6de6f55724aaa9ec85c9d2d8a"); + private static readonly byte[] RC12 = Hex.DecodeStrict("dfb49f2b6b772a120efa4f2e29129fd4"); + private static readonly byte[] RC13 = Hex.DecodeStrict("1ea10344f449a23632d611aebb6a12ee"); + private static readonly byte[] RC14 = Hex.DecodeStrict("af0449884b0500845f9600c99ca8eca6"); + private static readonly byte[] RC15 = Hex.DecodeStrict("21025ed89d199c4f78a2c7e327e593ec"); + private static readonly byte[] RC16 = Hex.DecodeStrict("bf3aaaf8a759c9b7b9282ecd82d40173"); + private static readonly byte[] RC17 = Hex.DecodeStrict("6260700d6186b01737f2efd910307d6b"); + private static readonly byte[] RC18 = Hex.DecodeStrict("5aca45c22130044381c29153f6fc9ac6"); + private static readonly byte[] RC19 = Hex.DecodeStrict("9223973c226b68bb2caf92e836d1943a"); + private static readonly byte[] RC20 = Hex.DecodeStrict("d3bf9238225886eb6cbab958e51071b4"); + private static readonly byte[] RC21 = Hex.DecodeStrict("db863ce5aef0c677933dfddd24e1128d"); + private static readonly byte[] RC22 = Hex.DecodeStrict("bb606268ffeba09c83e48de3cb2212b1"); + private static readonly byte[] RC23 = Hex.DecodeStrict("734bd3dce2e4d19c2db91a4ec72bf77d"); + private static readonly byte[] RC24 = Hex.DecodeStrict("43bb47c361301b434b1415c42cb3924e"); + private static readonly byte[] RC25 = Hex.DecodeStrict("dba775a8e707eff603b231dd16eb6899"); + private static readonly byte[] RC26 = Hex.DecodeStrict("6df3614b3c7559778e5e23027eca472c"); + private static readonly byte[] RC27 = Hex.DecodeStrict("cda75a17d6de7d776d1be5b9b88617f9"); + private static readonly byte[] RC28 = Hex.DecodeStrict("ec6b43f06ba8e9aa9d6c069da946ee5d"); + private static readonly byte[] RC29 = Hex.DecodeStrict("cb1e6950f957332ba25311593bf327c1"); + private static readonly byte[] RC30 = Hex.DecodeStrict("2cee0c7500da619ce4ed0353600ed0d9"); + private static readonly byte[] RC31 = Hex.DecodeStrict("f0b1a5a196e90cab80bbbabc63a4a350"); + private static readonly byte[] RC32 = Hex.DecodeStrict("ae3db1025e962988ab0dde30938dca39"); + private static readonly byte[] RC33 = Hex.DecodeStrict("17bb8f38d554a40b8814f3a82e75b442"); + private static readonly byte[] RC34 = Hex.DecodeStrict("34bb8a5b5f427fd7aeb6b779360a16f6"); + private static readonly byte[] RC35 = Hex.DecodeStrict("26f65241cbe5543843ce5918ffbaafde"); + private static readonly byte[] RC36 = Hex.DecodeStrict("4ce99a54b9f3026aa2ca9cf7839ec978"); + private static readonly byte[] RC37 = Hex.DecodeStrict("ae51a51a1bdff7be40c06e2822901235"); + private static readonly byte[] RC38 = Hex.DecodeStrict("a0c1613cba7ed22bc173bc0f48a659cf"); + private static readonly byte[] RC39 = Hex.DecodeStrict("756acc03022882884ad6bdfde9c59da1"); + + private static readonly byte[][] RoundConstants = + { + RC0 , RC1 , RC2 , RC3 , + RC4 , RC5 , RC6 , RC7 , + RC8 , RC9 , RC10, RC11, + RC12, RC13, RC14, RC15, + RC16, RC17, RC18, RC19, + RC20, RC21, RC22, RC23, + RC24, RC25, RC26, RC27, + RC28, RC29, RC30, RC31, + RC32, RC33, RC34, RC35, + RC36, RC37, RC38, RC39, + }; + internal ulong[][] haraka512_rc = new ulong[][]{ new ulong[]{0x24cf0ab9086f628bL, 0xbdd6eeecc83b8382L, 0xd96fb0306cdad0a7L, 0xaace082ac8f95f89L, 0x449d8e8870d7041fL, 0x49bb2f80b2b3e2f8L, 0x0569ae98d93bb258L, 0x23dc9691e7d6a4b1L}, new ulong[]{0xd8ba10ede0fe5b6eL, 0x7ecf7dbe424c7b8eL, 0x6ea9949c6df62a31L, 0xbf3f3c97ec9c313eL, 0x241d03a196a1861eL, 0xead3a51116e5a2eaL, 0x77d479fcad9574e3L, 0x18657a1af894b7a0L}, @@ -36,6 +92,23 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus { this.buffer = new byte[64]; off = 0; + + byte[] buf = new byte[640]; + byte[] tmp = new byte[16]; + for (int rc = 0; rc < 40; ++rc) + { + Arrays.Reverse(RoundConstants[rc]).CopyTo(buf, rc << 4); + } + for (int round = 0; round < 10; ++round) + { + InterleaveConstant(haraka512_rc[round], buf, round << 6); + //for (int j = 0; j < 8; ++j) + //{ + // Console.Write(haraka512_rc[round][j].ToString("X") + ", "); + //} + //Console.WriteLine(); + } + //Console.WriteLine("-----"); } protected void Reset() diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaS_X86.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaS_X86.cs index 3975f02ff..87681c484 100644 --- a/crypto/src/pqc/crypto/sphincsplus/HarakaS_X86.cs +++ b/crypto/src/pqc/crypto/sphincsplus/HarakaS_X86.cs @@ -1,7 +1,9 @@ #if NETCOREAPP3_0_OR_GREATER using System; +using System.Buffers.Binary; using System.Diagnostics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using Org.BouncyCastle.Crypto; @@ -185,15 +187,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus [MethodImpl(MethodImplOptions.AggressiveInlining)] 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 Unsafe.AsRef(t[0])); + return MemoryMarshal.Read<Vector128<byte>>(t); - 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]); -#endif + return Vector128.Create( + BinaryPrimitives.ReadUInt64LittleEndian(t[..8]), + BinaryPrimitives.ReadUInt64LittleEndian(t[8..]) + ).AsByte(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/crypto/src/pqc/crypto/utils/PqcUtilities.cs b/crypto/src/pqc/crypto/utils/PqcUtilities.cs index 8d73333c9..1f1da5e74 100644 --- a/crypto/src/pqc/crypto/utils/PqcUtilities.cs +++ b/crypto/src/pqc/crypto/utils/PqcUtilities.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using Org.BouncyCastle.Asn1; @@ -27,8 +26,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities private readonly static Dictionary<PicnicParameters, DerObjectIdentifier> picnicOids = new Dictionary<PicnicParameters, DerObjectIdentifier>(); private readonly static Dictionary<DerObjectIdentifier, PicnicParameters> picnicParams = new Dictionary<DerObjectIdentifier, PicnicParameters>(); - private readonly static Dictionary<SIKEParameters, DerObjectIdentifier> sikeOids = new Dictionary<SIKEParameters, DerObjectIdentifier>(); - private readonly static Dictionary<DerObjectIdentifier, SIKEParameters> sikeParams = new Dictionary<DerObjectIdentifier, SIKEParameters>(); + private readonly static Dictionary<SikeParameters, DerObjectIdentifier> sikeOids = new Dictionary<SikeParameters, DerObjectIdentifier>(); + private readonly static Dictionary<DerObjectIdentifier, SikeParameters> sikeParams = new Dictionary<DerObjectIdentifier, SikeParameters>(); private readonly static Dictionary<KyberParameters, DerObjectIdentifier> kyberOids = new Dictionary<KyberParameters, DerObjectIdentifier>(); private readonly static Dictionary<DerObjectIdentifier, KyberParameters> kyberParams = new Dictionary<DerObjectIdentifier, KyberParameters>(); @@ -79,7 +78,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities saberOids[SaberParameters.lightsaberkem256r3] = BCObjectIdentifiers.lightsaberkem256r3; saberOids[SaberParameters.saberkem256r3] = BCObjectIdentifiers.saberkem256r3; saberOids[SaberParameters.firesaberkem256r3] = BCObjectIdentifiers.firesaberkem256r3; - + saberOids[SaberParameters.ulightsaberkemr3] = BCObjectIdentifiers.ulightsaberkemr3; + saberOids[SaberParameters.usaberkemr3] = BCObjectIdentifiers.usaberkemr3; + saberOids[SaberParameters.ufiresaberkemr3] = BCObjectIdentifiers.ufiresaberkemr3; + saberOids[SaberParameters.lightsaberkem90sr3] = BCObjectIdentifiers.lightsaberkem90sr3; + saberOids[SaberParameters.saberkem90sr3] = BCObjectIdentifiers.saberkem90sr3; + saberOids[SaberParameters.firesaberkem90sr3] = BCObjectIdentifiers.firesaberkem90sr3; + saberOids[SaberParameters.ulightsaberkem90sr3] = BCObjectIdentifiers.ulightsaberkem90sr3; + saberOids[SaberParameters.usaberkem90sr3] = BCObjectIdentifiers.usaberkem90sr3; + saberOids[SaberParameters.ufiresaberkem90sr3] = BCObjectIdentifiers.ufiresaberkem90sr3; + saberParams[BCObjectIdentifiers.lightsaberkem128r3] = SaberParameters.lightsaberkem128r3; saberParams[BCObjectIdentifiers.saberkem128r3] = SaberParameters.saberkem128r3; saberParams[BCObjectIdentifiers.firesaberkem128r3] = SaberParameters.firesaberkem128r3; @@ -89,7 +97,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities saberParams[BCObjectIdentifiers.lightsaberkem256r3] = SaberParameters.lightsaberkem256r3; saberParams[BCObjectIdentifiers.saberkem256r3] = SaberParameters.saberkem256r3; saberParams[BCObjectIdentifiers.firesaberkem256r3] = SaberParameters.firesaberkem256r3; - + saberParams[BCObjectIdentifiers.ulightsaberkemr3] = SaberParameters.ulightsaberkemr3; + saberParams[BCObjectIdentifiers.usaberkemr3] = SaberParameters.usaberkemr3; + saberParams[BCObjectIdentifiers.ufiresaberkemr3] = SaberParameters.ufiresaberkemr3; + saberParams[BCObjectIdentifiers.lightsaberkem90sr3] = SaberParameters.lightsaberkem90sr3; + saberParams[BCObjectIdentifiers.saberkem90sr3] = SaberParameters.saberkem90sr3; + saberParams[BCObjectIdentifiers.firesaberkem90sr3] = SaberParameters.firesaberkem90sr3; + saberParams[BCObjectIdentifiers.ulightsaberkem90sr3] = SaberParameters.ulightsaberkem90sr3; + saberParams[BCObjectIdentifiers.usaberkem90sr3] = SaberParameters.usaberkem90sr3; + saberParams[BCObjectIdentifiers.ufiresaberkem90sr3] = SaberParameters.ufiresaberkem90sr3; picnicOids[PicnicParameters.picnicl1fs] = BCObjectIdentifiers.picnicl1fs; picnicOids[PicnicParameters.picnicl1ur] = BCObjectIdentifiers.picnicl1ur; @@ -117,23 +133,23 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities picnicParams[BCObjectIdentifiers.picnicl3full] = PicnicParameters.picnicl3full; picnicParams[BCObjectIdentifiers.picnicl5full] = PicnicParameters.picnicl5full; - sikeParams[BCObjectIdentifiers.sikep434] = SIKEParameters.sikep434; - sikeParams[BCObjectIdentifiers.sikep503] = SIKEParameters.sikep503; - sikeParams[BCObjectIdentifiers.sikep610] = SIKEParameters.sikep610; - sikeParams[BCObjectIdentifiers.sikep751] = SIKEParameters.sikep751; - sikeParams[BCObjectIdentifiers.sikep434_compressed] = SIKEParameters.sikep434_compressed; - sikeParams[BCObjectIdentifiers.sikep503_compressed] = SIKEParameters.sikep503_compressed; - sikeParams[BCObjectIdentifiers.sikep610_compressed] = SIKEParameters.sikep610_compressed; - sikeParams[BCObjectIdentifiers.sikep751_compressed] = SIKEParameters.sikep751_compressed; + sikeParams[BCObjectIdentifiers.sikep434] = SikeParameters.sikep434; + sikeParams[BCObjectIdentifiers.sikep503] = SikeParameters.sikep503; + sikeParams[BCObjectIdentifiers.sikep610] = SikeParameters.sikep610; + sikeParams[BCObjectIdentifiers.sikep751] = SikeParameters.sikep751; + sikeParams[BCObjectIdentifiers.sikep434_compressed] = SikeParameters.sikep434_compressed; + sikeParams[BCObjectIdentifiers.sikep503_compressed] = SikeParameters.sikep503_compressed; + sikeParams[BCObjectIdentifiers.sikep610_compressed] = SikeParameters.sikep610_compressed; + sikeParams[BCObjectIdentifiers.sikep751_compressed] = SikeParameters.sikep751_compressed; - sikeOids[SIKEParameters.sikep434] = BCObjectIdentifiers.sikep434; - sikeOids[SIKEParameters.sikep503] = BCObjectIdentifiers.sikep503; - sikeOids[SIKEParameters.sikep610] = BCObjectIdentifiers.sikep610; - sikeOids[SIKEParameters.sikep751] = BCObjectIdentifiers.sikep751; - sikeOids[SIKEParameters.sikep434_compressed] = BCObjectIdentifiers.sikep434_compressed; - sikeOids[SIKEParameters.sikep503_compressed] = BCObjectIdentifiers.sikep503_compressed; - sikeOids[SIKEParameters.sikep610_compressed] = BCObjectIdentifiers.sikep610_compressed; - sikeOids[SIKEParameters.sikep751_compressed] = BCObjectIdentifiers.sikep751_compressed; + sikeOids[SikeParameters.sikep434] = BCObjectIdentifiers.sikep434; + sikeOids[SikeParameters.sikep503] = BCObjectIdentifiers.sikep503; + sikeOids[SikeParameters.sikep610] = BCObjectIdentifiers.sikep610; + sikeOids[SikeParameters.sikep751] = BCObjectIdentifiers.sikep751; + sikeOids[SikeParameters.sikep434_compressed] = BCObjectIdentifiers.sikep434_compressed; + sikeOids[SikeParameters.sikep503_compressed] = BCObjectIdentifiers.sikep503_compressed; + sikeOids[SikeParameters.sikep610_compressed] = BCObjectIdentifiers.sikep610_compressed; + sikeOids[SikeParameters.sikep751_compressed] = BCObjectIdentifiers.sikep751_compressed; kyberOids[KyberParameters.kyber512] = BCObjectIdentifiers.kyber512; kyberOids[KyberParameters.kyber768] = BCObjectIdentifiers.kyber768; @@ -170,21 +186,21 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities dilithiumParams[BCObjectIdentifiers.dilithium3_aes] = DilithiumParameters.Dilithium3Aes; dilithiumParams[BCObjectIdentifiers.dilithium5_aes] = DilithiumParameters.Dilithium5Aes; - bikeOids[BikeParameters.bike128] = BCObjectIdentifiers.bike128; - bikeOids[BikeParameters.bike192] = BCObjectIdentifiers.bike192; - bikeOids[BikeParameters.bike256] = BCObjectIdentifiers.bike256; - bikeParams[BCObjectIdentifiers.bike128] = BikeParameters.bike128; bikeParams[BCObjectIdentifiers.bike192] = BikeParameters.bike192; bikeParams[BCObjectIdentifiers.bike256] = BikeParameters.bike256; - hqcOids[HqcParameters.hqc128] = BCObjectIdentifiers.hqc128; - hqcOids[HqcParameters.hqc192] = BCObjectIdentifiers.hqc192; - hqcOids[HqcParameters.hqc256] = BCObjectIdentifiers.hqc256; + bikeOids[BikeParameters.bike128] = BCObjectIdentifiers.bike128; + bikeOids[BikeParameters.bike192] = BCObjectIdentifiers.bike192; + bikeOids[BikeParameters.bike256] = BCObjectIdentifiers.bike256; hqcParams[BCObjectIdentifiers.hqc128] = HqcParameters.hqc128; hqcParams[BCObjectIdentifiers.hqc192] = HqcParameters.hqc192; hqcParams[BCObjectIdentifiers.hqc256] = HqcParameters.hqc256; + + hqcOids[HqcParameters.hqc128] = BCObjectIdentifiers.hqc128; + hqcOids[HqcParameters.hqc192] = BCObjectIdentifiers.hqc192; + hqcOids[HqcParameters.hqc256] = BCObjectIdentifiers.hqc256; } public static DerObjectIdentifier McElieceOidLookup(CmceParameters parameters) @@ -256,12 +272,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities { return picnicParams[oid]; } - internal static DerObjectIdentifier SikeOidLookup(SIKEParameters parameters) + internal static DerObjectIdentifier SikeOidLookup(SikeParameters parameters) { return sikeOids[parameters]; } - internal static SIKEParameters SikeParamsLookup(DerObjectIdentifier oid) + internal static SikeParameters SikeParamsLookup(DerObjectIdentifier oid) { return sikeParams[oid]; } diff --git a/crypto/src/pqc/crypto/utils/PrivateKeyFactory.cs b/crypto/src/pqc/crypto/utils/PrivateKeyFactory.cs index 7b0039d63..7db65dbfb 100644 --- a/crypto/src/pqc/crypto/utils/PrivateKeyFactory.cs +++ b/crypto/src/pqc/crypto/utils/PrivateKeyFactory.cs @@ -24,9 +24,8 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Utilities { - public class PrivateKeyFactory + public static class PrivateKeyFactory { - /// <summary> Create a private key parameter from a PKCS8 PrivateKeyInfo encoding.</summary> /// <param name="privateKeyInfoData"> the PrivateKeyInfo encoding</param> /// <returns> a suitable private key parameter</returns> @@ -45,7 +44,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities return CreateKey(PrivateKeyInfo.GetInstance(new Asn1InputStream(inStr).ReadObject())); } - /// <summary> Create a private key parameter from the passed in PKCS8 PrivateKeyInfo object.</summary> /// <param name="keyInfo"> the PrivateKeyInfo object containing the key material</param> /// <returns> a suitable private key parameter</returns> @@ -66,14 +64,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities { byte[] pubEnc = pubKey.GetOctets(); - return LMSPrivateKeyParameters.GetInstance(Arrays.CopyOfRange(keyEnc, 4, keyEnc.Length), + return LmsPrivateKeyParameters.GetInstance(Arrays.CopyOfRange(keyEnc, 4, keyEnc.Length), Arrays.CopyOfRange(pubEnc, 4, pubEnc.Length)); } - return LMSPrivateKeyParameters.GetInstance(Arrays.CopyOfRange(keyEnc, 4, keyEnc.Length)); + return LmsPrivateKeyParameters.GetInstance(Arrays.CopyOfRange(keyEnc, 4, keyEnc.Length)); } } - if (algOID.On(BCObjectIdentifiers.pqc_kem_mceliece)) { CmcePrivateKey cmceKey = CmcePrivateKey.GetInstance(keyInfo.ParsePrivateKey()); @@ -81,7 +78,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities return new CmcePrivateKeyParameters(spParams, cmceKey.Delta, cmceKey.C, cmceKey.G, cmceKey.Alpha, cmceKey.S); } - if (algOID.On(BCObjectIdentifiers.sphincsPlus)) { byte[] keyEnc = Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets(); @@ -106,9 +102,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities if (algOID.On(BCObjectIdentifiers.pqc_kem_sike)) { byte[] keyEnc = Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets(); - SIKEParameters sikeParams = PqcUtilities.SikeParamsLookup(keyInfo.PrivateKeyAlgorithm.Algorithm); + SikeParameters sikeParams = PqcUtilities.SikeParamsLookup(keyInfo.PrivateKeyAlgorithm.Algorithm); - return new SIKEPrivateKeyParameters(sikeParams, keyEnc); + return new SikePrivateKeyParameters(sikeParams, keyEnc); } if (algOID.On(BCObjectIdentifiers.pqc_kem_bike)) { @@ -119,7 +115,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities byte[] h1 = Arrays.CopyOfRange(keyEnc, bikeParams.RByte, 2 * bikeParams.RByte); byte[] sigma = Arrays.CopyOfRange(keyEnc, 2 * bikeParams.RByte, keyEnc.Length); - return new BikePrivateKeyParameters(bikeParams, h0, h1, sigma); } if (algOID.On(BCObjectIdentifiers.pqc_kem_hqc)) @@ -179,9 +174,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities int version = DerInteger.GetInstance(keyEnc[0]).Value.IntValue; if (version != 0) - { throw new IOException("unknown private key version: " + version); - } if (keyInfo.PublicKeyData != null) { @@ -208,39 +201,35 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities } } if (algOID.Equals(BCObjectIdentifiers.falcon_512) || algOID.Equals(BCObjectIdentifiers.falcon_1024)) - { - Asn1Sequence keyEnc = Asn1Sequence.GetInstance(keyInfo.ParsePrivateKey()); - FalconParameters spParams = PqcUtilities.FalconParamsLookup(keyInfo.PrivateKeyAlgorithm.Algorithm); + { + Asn1Sequence keyEnc = Asn1Sequence.GetInstance(keyInfo.ParsePrivateKey()); + FalconParameters spParams = PqcUtilities.FalconParamsLookup(keyInfo.PrivateKeyAlgorithm.Algorithm); - DerBitString publicKeyData = keyInfo.PublicKeyData; - int version = DerInteger.GetInstance(keyEnc[0]).Value.IntValue; - if (version != 1) - { - throw new IOException("unknown private key version: " + version); - } + DerBitString publicKeyData = keyInfo.PublicKeyData; + int version = DerInteger.GetInstance(keyEnc[0]).Value.IntValue; + if (version != 1) + throw new IOException("unknown private key version: " + version); - if (keyInfo.PublicKeyData != null) - { - //ASN1Sequence pubKey = ASN1Sequence.getInstance(keyInfo.getPublicKeyData().getOctets()); - return new FalconPrivateKeyParameters(spParams, - Asn1OctetString.GetInstance(keyEnc[1]).GetOctets(), - Asn1OctetString.GetInstance(keyEnc[2]).GetOctets(), - Asn1OctetString.GetInstance(keyEnc[3]).GetOctets(), - publicKeyData.GetOctets()); // encT1 - } - else - { - return new FalconPrivateKeyParameters(spParams, - Asn1OctetString.GetInstance(keyEnc[1]).GetOctets(), - Asn1OctetString.GetInstance(keyEnc[2]).GetOctets(), - Asn1OctetString.GetInstance(keyEnc[3]).GetOctets(), - null); - } + if (keyInfo.PublicKeyData != null) + { + //ASN1Sequence pubKey = ASN1Sequence.getInstance(keyInfo.getPublicKeyData().getOctets()); + return new FalconPrivateKeyParameters(spParams, + Asn1OctetString.GetInstance(keyEnc[1]).GetOctets(), + Asn1OctetString.GetInstance(keyEnc[2]).GetOctets(), + Asn1OctetString.GetInstance(keyEnc[3]).GetOctets(), + publicKeyData.GetOctets()); // encT1 } - - - throw new Exception("algorithm identifier in private key not recognised"); + else + { + return new FalconPrivateKeyParameters(spParams, + Asn1OctetString.GetInstance(keyEnc[1]).GetOctets(), + Asn1OctetString.GetInstance(keyEnc[2]).GetOctets(), + Asn1OctetString.GetInstance(keyEnc[3]).GetOctets(), + null); + } + } + throw new Exception("algorithm identifier in private key not recognised"); } } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/utils/PrivateKeyInfoFactory.cs b/crypto/src/pqc/crypto/utils/PrivateKeyInfoFactory.cs index e4ae51361..806eae8b7 100644 --- a/crypto/src/pqc/crypto/utils/PrivateKeyInfoFactory.cs +++ b/crypto/src/pqc/crypto/utils/PrivateKeyInfoFactory.cs @@ -5,28 +5,23 @@ using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Pqc.Asn1; +using Org.BouncyCastle.Pqc.Crypto.Bike; using Org.BouncyCastle.Pqc.Crypto.Cmce; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; using Org.BouncyCastle.Pqc.Crypto.Falcon; +using Org.BouncyCastle.Pqc.Crypto.Hqc; using Org.BouncyCastle.Pqc.Crypto.Lms; using Org.BouncyCastle.Pqc.Crypto.Picnic; using Org.BouncyCastle.Pqc.Crypto.Saber; using Org.BouncyCastle.Pqc.Crypto.Sike; -using Org.BouncyCastle.Pqc.Crypto.Bike; -using Org.BouncyCastle.Pqc.Crypto.Hqc; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Utilities { - public class PrivateKeyInfoFactory + public static class PrivateKeyInfoFactory { - private PrivateKeyInfoFactory() - { - - } - /// <summary> Create a PrivateKeyInfo representation of a private key.</summary> /// <param name="privateKey"> the key to be encoded into the info object.</param> /// <returns> the appropriate PrivateKeyInfo</returns> @@ -43,154 +38,142 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities /// <exception cref="ArgumentException"> on an error encoding the key</exception> public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter privateKey, Asn1Set attributes) { - if (privateKey is LMSPrivateKeyParameters) + if (privateKey is LmsPrivateKeyParameters lmsPrivateKeyParameters) { - LMSPrivateKeyParameters parameters = (LMSPrivateKeyParameters)privateKey; - - byte[] encoding = Composer.Compose().U32Str(1).Bytes(parameters).Build(); - byte[] pubEncoding = Composer.Compose().U32Str(1).Bytes(parameters.GetPublicKey()).Build(); + byte[] encoding = Composer.Compose().U32Str(1).Bytes(lmsPrivateKeyParameters).Build(); + byte[] pubEncoding = Composer.Compose().U32Str(1).Bytes(lmsPrivateKeyParameters.GetPublicKey()).Build(); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdAlgHssLmsHashsig); return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(encoding), attributes, pubEncoding); } - if (privateKey is HSSPrivateKeyParameters) + if (privateKey is HssPrivateKeyParameters hssPrivateKeyParameters) { - HSSPrivateKeyParameters parameters = (HSSPrivateKeyParameters)privateKey; - - byte[] encoding = Composer.Compose().U32Str(parameters.L).Bytes(parameters).Build(); - byte[] pubEncoding = Composer.Compose().U32Str(parameters.L).Bytes(parameters.GetPublicKey().LmsPublicKey).Build(); + int L = hssPrivateKeyParameters.L; + byte[] encoding = Composer.Compose().U32Str(L).Bytes(hssPrivateKeyParameters).Build(); + byte[] pubEncoding = Composer.Compose().U32Str(L).Bytes(hssPrivateKeyParameters.GetPublicKey().LmsPublicKey).Build(); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdAlgHssLmsHashsig); return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(encoding), attributes, pubEncoding); } - if (privateKey is SphincsPlusPrivateKeyParameters) + if (privateKey is SphincsPlusPrivateKeyParameters sphincsPlusPrivateKeyParameters) { - SphincsPlusPrivateKeyParameters parameters = (SphincsPlusPrivateKeyParameters)privateKey; - - byte[] encoding = parameters.GetEncoded(); - byte[] pubEncoding = parameters.GetEncodedPublicKey(); + byte[] encoding = sphincsPlusPrivateKeyParameters.GetEncoded(); + byte[] pubEncoding = sphincsPlusPrivateKeyParameters.GetEncodedPublicKey(); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( - PqcUtilities.SphincsPlusOidLookup(parameters.Parameters)); + PqcUtilities.SphincsPlusOidLookup(sphincsPlusPrivateKeyParameters.Parameters)); return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(encoding), attributes, pubEncoding); } - if (privateKey is CmcePrivateKeyParameters) + if (privateKey is CmcePrivateKeyParameters cmcePrivateKeyParameters) { - CmcePrivateKeyParameters parameters = (CmcePrivateKeyParameters) privateKey; - - byte[] encoding = parameters.GetEncoded(); + byte[] encoding = cmcePrivateKeyParameters.GetEncoded(); AlgorithmIdentifier algorithmIdentifier = - new AlgorithmIdentifier(PqcUtilities.McElieceOidLookup(parameters.Parameters)); + new AlgorithmIdentifier(PqcUtilities.McElieceOidLookup(cmcePrivateKeyParameters.Parameters)); - CmcePublicKey CmcePub = new CmcePublicKey(parameters.ReconstructPublicKey()); - CmcePrivateKey CmcePriv = new CmcePrivateKey(0, parameters.Delta, parameters.C, parameters.G, - parameters.Alpha, parameters.S, CmcePub); + CmcePublicKey CmcePub = new CmcePublicKey(cmcePrivateKeyParameters.ReconstructPublicKey()); + CmcePrivateKey CmcePriv = new CmcePrivateKey(0, cmcePrivateKeyParameters.Delta, + cmcePrivateKeyParameters.C, cmcePrivateKeyParameters.G, cmcePrivateKeyParameters.Alpha, + cmcePrivateKeyParameters.S, CmcePub); return new PrivateKeyInfo(algorithmIdentifier, CmcePriv, attributes); } - if (privateKey is SaberPrivateKeyParameters) + if (privateKey is SaberPrivateKeyParameters saberPrivateKeyParameters) { - SaberPrivateKeyParameters parameters = (SaberPrivateKeyParameters)privateKey; - - byte[] encoding = parameters.GetEncoded(); + byte[] encoding = saberPrivateKeyParameters.GetEncoded(); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.SaberOidLookup(parameters.GetParameters())); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.SaberOidLookup(saberPrivateKeyParameters.Parameters)); return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(encoding), attributes); } - if (privateKey is PicnicPrivateKeyParameters) + if (privateKey is PicnicPrivateKeyParameters picnicPrivateKeyParameters) { - PicnicPrivateKeyParameters parameters = (PicnicPrivateKeyParameters)privateKey; + byte[] encoding = picnicPrivateKeyParameters.GetEncoded(); - byte[] encoding = parameters.GetEncoded(); - - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.PicnicOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.PicnicOidLookup(picnicPrivateKeyParameters.Parameters)); return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(encoding), attributes); } - if (privateKey is SIKEPrivateKeyParameters) + if (privateKey is SikePrivateKeyParameters sikePrivateKeyParameters) { - SIKEPrivateKeyParameters parameters = (SIKEPrivateKeyParameters)privateKey; + byte[] encoding = sikePrivateKeyParameters.GetEncoded(); - byte[] encoding = parameters.GetEncoded(); - - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.SikeOidLookup(parameters.GetParameters())); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.SikeOidLookup(sikePrivateKeyParameters.Parameters)); return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(encoding), attributes); } - if (privateKey is FalconPrivateKeyParameters) + if (privateKey is FalconPrivateKeyParameters falconPrivateKeyParameters) { - FalconPrivateKeyParameters parameters = (FalconPrivateKeyParameters)privateKey; - Asn1EncodableVector v = new Asn1EncodableVector(); v.Add(new DerInteger(1)); - v.Add(new DerOctetString(parameters.GetSpolyf())); - v.Add(new DerOctetString(parameters.GetG())); - v.Add(new DerOctetString(parameters.GetSpolyF())); + v.Add(new DerOctetString(falconPrivateKeyParameters.GetSpolyf())); + v.Add(new DerOctetString(falconPrivateKeyParameters.GetG())); + v.Add(new DerOctetString(falconPrivateKeyParameters.GetSpolyF())); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.FalconOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.FalconOidLookup(falconPrivateKeyParameters.Parameters)); - return new PrivateKeyInfo(algorithmIdentifier, new DerSequence(v), attributes, parameters.GetPublicKey()); + return new PrivateKeyInfo(algorithmIdentifier, new DerSequence(v), attributes, + falconPrivateKeyParameters.GetPublicKey()); } - if (privateKey is KyberPrivateKeyParameters) + if (privateKey is KyberPrivateKeyParameters kyberPrivateKeyParameters) { - KyberPrivateKeyParameters parameters = (KyberPrivateKeyParameters)privateKey; - Asn1EncodableVector v = new Asn1EncodableVector(); v.Add(new DerInteger(0)); - v.Add(new DerOctetString(parameters.S)); - v.Add(new DerOctetString(parameters.Hpk)); - v.Add(new DerOctetString(parameters.Nonce)); + v.Add(new DerOctetString(kyberPrivateKeyParameters.S)); + v.Add(new DerOctetString(kyberPrivateKeyParameters.Hpk)); + v.Add(new DerOctetString(kyberPrivateKeyParameters.Nonce)); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.KyberOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.KyberOidLookup(kyberPrivateKeyParameters.Parameters)); Asn1EncodableVector vPub = new Asn1EncodableVector(); - vPub.Add(new DerOctetString(parameters.T)); - vPub.Add(new DerOctetString(parameters.Rho)); + vPub.Add(new DerOctetString(kyberPrivateKeyParameters.T)); + vPub.Add(new DerOctetString(kyberPrivateKeyParameters.Rho)); - return new PrivateKeyInfo(algorithmIdentifier, new DerSequence(v), attributes, new DerSequence(vPub).GetEncoded()); + return new PrivateKeyInfo(algorithmIdentifier, new DerSequence(v), attributes, + new DerSequence(vPub).GetEncoded()); } - if (privateKey is DilithiumPrivateKeyParameters) + if (privateKey is DilithiumPrivateKeyParameters dilithiumPrivateKeyParameters) { - DilithiumPrivateKeyParameters parameters = (DilithiumPrivateKeyParameters)privateKey; - Asn1EncodableVector v = new Asn1EncodableVector(); v.Add(new DerInteger(0)); - v.Add(new DerBitString(parameters.Rho)); - v.Add(new DerBitString(parameters.K)); - v.Add(new DerBitString(parameters.Tr)); - v.Add(new DerBitString(parameters.S1)); - v.Add(new DerBitString(parameters.S2)); - v.Add(new DerBitString(parameters.T0)); + v.Add(new DerBitString(dilithiumPrivateKeyParameters.Rho)); + v.Add(new DerBitString(dilithiumPrivateKeyParameters.K)); + v.Add(new DerBitString(dilithiumPrivateKeyParameters.Tr)); + v.Add(new DerBitString(dilithiumPrivateKeyParameters.S1)); + v.Add(new DerBitString(dilithiumPrivateKeyParameters.S2)); + v.Add(new DerBitString(dilithiumPrivateKeyParameters.T0)); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.DilithiumOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.DilithiumOidLookup(dilithiumPrivateKeyParameters.Parameters)); Asn1EncodableVector vPub = new Asn1EncodableVector(); - vPub.Add(new DerOctetString(parameters.Rho)); - vPub.Add(new DerOctetString(parameters.T1)); + vPub.Add(new DerOctetString(dilithiumPrivateKeyParameters.Rho)); + vPub.Add(new DerOctetString(dilithiumPrivateKeyParameters.T1)); - return new PrivateKeyInfo(algorithmIdentifier, new DerSequence(v), attributes, new DerSequence(vPub).GetEncoded()); + return new PrivateKeyInfo(algorithmIdentifier, new DerSequence(v), attributes, + new DerSequence(vPub).GetEncoded()); } - if (privateKey is BikePrivateKeyParameters) + if (privateKey is BikePrivateKeyParameters bikePrivateKeyParameters) { - BikePrivateKeyParameters parameters = (BikePrivateKeyParameters)privateKey; + byte[] encoding = bikePrivateKeyParameters.GetEncoded(); - byte[] encoding = parameters.GetEncoded(); - - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.BikeOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.BikeOidLookup(bikePrivateKeyParameters.Parameters)); return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(encoding), attributes); } - if (privateKey is HqcPrivateKeyParameters) + else if (privateKey is HqcPrivateKeyParameters hqcPrivateKeyParameters) { - HqcPrivateKeyParameters parameters = (HqcPrivateKeyParameters)privateKey; - - byte[] encoding = parameters.GetEncoded(); - - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.HqcOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.HqcOidLookup(hqcPrivateKeyParameters.Parameters)); + byte[] encoding = hqcPrivateKeyParameters.PrivateKey; return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(encoding), attributes); } throw new ArgumentException("Class provided is not convertible: " + Platform.GetTypeName(privateKey)); } } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs b/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs index 53aa28c36..5d55a73aa 100644 --- a/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs +++ b/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs @@ -4,6 +4,7 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.BC; +using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Utilities; @@ -15,6 +16,7 @@ using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; using Org.BouncyCastle.Pqc.Crypto.Falcon; using Org.BouncyCastle.Pqc.Crypto.Hqc; +using Org.BouncyCastle.Pqc.Crypto.Lms; using Org.BouncyCastle.Pqc.Crypto.Picnic; using Org.BouncyCastle.Pqc.Crypto.Saber; using Org.BouncyCastle.Pqc.Crypto.Sike; @@ -23,88 +25,99 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Utilities { - public class PublicKeyFactory + public static class PublicKeyFactory { - private static Dictionary<DerObjectIdentifier, SubjectPublicKeyInfoConverter> converters = new Dictionary<DerObjectIdentifier, SubjectPublicKeyInfoConverter>(); - + private static Dictionary<DerObjectIdentifier, SubjectPublicKeyInfoConverter> Converters = + new Dictionary<DerObjectIdentifier, SubjectPublicKeyInfoConverter>(); static PublicKeyFactory() { - converters[BCObjectIdentifiers.sphincsPlus] = new SphincsPlusConverter(); - converters[BCObjectIdentifiers.sphincsPlus_shake_256] = new SphincsPlusConverter(); - converters[BCObjectIdentifiers.sphincsPlus_sha_256] = new SphincsPlusConverter(); - converters[BCObjectIdentifiers.sphincsPlus_sha_512] = new SphincsPlusConverter(); + Converters[PkcsObjectIdentifiers.IdAlgHssLmsHashsig] = new LmsConverter(); + + Converters[BCObjectIdentifiers.sphincsPlus] = new SphincsPlusConverter(); + Converters[BCObjectIdentifiers.sphincsPlus_shake_256] = new SphincsPlusConverter(); + Converters[BCObjectIdentifiers.sphincsPlus_sha_256] = new SphincsPlusConverter(); + Converters[BCObjectIdentifiers.sphincsPlus_sha_512] = new SphincsPlusConverter(); - converters[BCObjectIdentifiers.mceliece348864_r3] = new CmceConverter(); - converters[BCObjectIdentifiers.mceliece348864f_r3] = new CmceConverter(); - converters[BCObjectIdentifiers.mceliece460896_r3] = new CmceConverter(); - converters[BCObjectIdentifiers.mceliece460896f_r3] = new CmceConverter(); - converters[BCObjectIdentifiers.mceliece6688128_r3] = new CmceConverter(); - converters[BCObjectIdentifiers.mceliece6688128f_r3] = new CmceConverter(); - converters[BCObjectIdentifiers.mceliece6960119_r3] = new CmceConverter(); - converters[BCObjectIdentifiers.mceliece6960119f_r3] = new CmceConverter(); - converters[BCObjectIdentifiers.mceliece8192128_r3] = new CmceConverter(); - converters[BCObjectIdentifiers.mceliece8192128f_r3] = new CmceConverter(); + Converters[BCObjectIdentifiers.mceliece348864_r3] = new CmceConverter(); + Converters[BCObjectIdentifiers.mceliece348864f_r3] = new CmceConverter(); + Converters[BCObjectIdentifiers.mceliece460896_r3] = new CmceConverter(); + Converters[BCObjectIdentifiers.mceliece460896f_r3] = new CmceConverter(); + Converters[BCObjectIdentifiers.mceliece6688128_r3] = new CmceConverter(); + Converters[BCObjectIdentifiers.mceliece6688128f_r3] = new CmceConverter(); + Converters[BCObjectIdentifiers.mceliece6960119_r3] = new CmceConverter(); + Converters[BCObjectIdentifiers.mceliece6960119f_r3] = new CmceConverter(); + Converters[BCObjectIdentifiers.mceliece8192128_r3] = new CmceConverter(); + Converters[BCObjectIdentifiers.mceliece8192128f_r3] = new CmceConverter(); - converters[BCObjectIdentifiers.lightsaberkem128r3] = new SaberConverter(); - converters[BCObjectIdentifiers.saberkem128r3] = new SaberConverter(); - converters[BCObjectIdentifiers.firesaberkem128r3] = new SaberConverter(); - converters[BCObjectIdentifiers.lightsaberkem192r3] = new SaberConverter(); - converters[BCObjectIdentifiers.saberkem192r3] = new SaberConverter(); - converters[BCObjectIdentifiers.firesaberkem192r3] = new SaberConverter(); - converters[BCObjectIdentifiers.lightsaberkem256r3] = new SaberConverter(); - converters[BCObjectIdentifiers.saberkem256r3] = new SaberConverter(); - converters[BCObjectIdentifiers.firesaberkem256r3] = new SaberConverter(); + Converters[BCObjectIdentifiers.lightsaberkem128r3] = new SaberConverter(); + Converters[BCObjectIdentifiers.saberkem128r3] = new SaberConverter(); + Converters[BCObjectIdentifiers.firesaberkem128r3] = new SaberConverter(); + Converters[BCObjectIdentifiers.lightsaberkem192r3] = new SaberConverter(); + Converters[BCObjectIdentifiers.saberkem192r3] = new SaberConverter(); + Converters[BCObjectIdentifiers.firesaberkem192r3] = new SaberConverter(); + Converters[BCObjectIdentifiers.lightsaberkem256r3] = new SaberConverter(); + Converters[BCObjectIdentifiers.saberkem256r3] = new SaberConverter(); + Converters[BCObjectIdentifiers.firesaberkem256r3] = new SaberConverter(); + Converters[BCObjectIdentifiers.ulightsaberkemr3] = new SaberConverter(); + Converters[BCObjectIdentifiers.usaberkemr3] = new SaberConverter(); + Converters[BCObjectIdentifiers.ufiresaberkemr3] = new SaberConverter(); + Converters[BCObjectIdentifiers.lightsaberkem90sr3] = new SaberConverter(); + Converters[BCObjectIdentifiers.saberkem90sr3] = new SaberConverter(); + Converters[BCObjectIdentifiers.firesaberkem90sr3] = new SaberConverter(); + Converters[BCObjectIdentifiers.ulightsaberkem90sr3] = new SaberConverter(); + Converters[BCObjectIdentifiers.usaberkem90sr3] = new SaberConverter(); + Converters[BCObjectIdentifiers.ufiresaberkem90sr3] = new SaberConverter(); - converters[BCObjectIdentifiers.picnic] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnicl1fs] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnicl1ur] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnicl3fs] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnicl3ur] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnicl5fs] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnicl5ur] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnic3l1] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnic3l3] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnic3l5] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnicl1full] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnicl3full] = new PicnicConverter(); - converters[BCObjectIdentifiers.picnicl5full] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnic] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnicl1fs] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnicl1ur] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnicl3fs] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnicl3ur] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnicl5fs] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnicl5ur] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnic3l1] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnic3l3] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnic3l5] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnicl1full] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnicl3full] = new PicnicConverter(); + Converters[BCObjectIdentifiers.picnicl5full] = new PicnicConverter(); - converters[BCObjectIdentifiers.sikep434] = new SikeConverter(); - converters[BCObjectIdentifiers.sikep503] = new SikeConverter(); - converters[BCObjectIdentifiers.sikep610] = new SikeConverter(); - converters[BCObjectIdentifiers.sikep751] = new SikeConverter(); - converters[BCObjectIdentifiers.sikep434_compressed] = new SikeConverter(); - converters[BCObjectIdentifiers.sikep503_compressed] = new SikeConverter(); - converters[BCObjectIdentifiers.sikep610_compressed] = new SikeConverter(); - converters[BCObjectIdentifiers.sikep751_compressed] = new SikeConverter(); + Converters[BCObjectIdentifiers.sikep434] = new SikeConverter(); + Converters[BCObjectIdentifiers.sikep503] = new SikeConverter(); + Converters[BCObjectIdentifiers.sikep610] = new SikeConverter(); + Converters[BCObjectIdentifiers.sikep751] = new SikeConverter(); + Converters[BCObjectIdentifiers.sikep434_compressed] = new SikeConverter(); + Converters[BCObjectIdentifiers.sikep503_compressed] = new SikeConverter(); + Converters[BCObjectIdentifiers.sikep610_compressed] = new SikeConverter(); + Converters[BCObjectIdentifiers.sikep751_compressed] = new SikeConverter(); - converters[BCObjectIdentifiers.dilithium2] = new DilithiumConverter(); - converters[BCObjectIdentifiers.dilithium3] = new DilithiumConverter(); - converters[BCObjectIdentifiers.dilithium5] = new DilithiumConverter(); - converters[BCObjectIdentifiers.dilithium2_aes] = new DilithiumConverter(); - converters[BCObjectIdentifiers.dilithium3_aes] = new DilithiumConverter(); - converters[BCObjectIdentifiers.dilithium5_aes] = new DilithiumConverter(); + Converters[BCObjectIdentifiers.dilithium2] = new DilithiumConverter(); + Converters[BCObjectIdentifiers.dilithium3] = new DilithiumConverter(); + Converters[BCObjectIdentifiers.dilithium5] = new DilithiumConverter(); + Converters[BCObjectIdentifiers.dilithium2_aes] = new DilithiumConverter(); + Converters[BCObjectIdentifiers.dilithium3_aes] = new DilithiumConverter(); + Converters[BCObjectIdentifiers.dilithium5_aes] = new DilithiumConverter(); - converters[BCObjectIdentifiers.falcon_512] = new FalconConverter(); - converters[BCObjectIdentifiers.falcon_1024] = new FalconConverter(); + Converters[BCObjectIdentifiers.falcon_512] = new FalconConverter(); + Converters[BCObjectIdentifiers.falcon_1024] = new FalconConverter(); - converters[BCObjectIdentifiers.kyber512] = new KyberConverter(); - converters[BCObjectIdentifiers.kyber512_aes] = new KyberConverter(); - converters[BCObjectIdentifiers.kyber768] = new KyberConverter(); - converters[BCObjectIdentifiers.kyber768_aes] = new KyberConverter(); - converters[BCObjectIdentifiers.kyber1024] = new KyberConverter(); - converters[BCObjectIdentifiers.kyber1024_aes] = new KyberConverter(); - - converters[BCObjectIdentifiers.bike128] = new BikeConverter(); - converters[BCObjectIdentifiers.bike192] = new BikeConverter(); - converters[BCObjectIdentifiers.bike256] = new BikeConverter(); - - converters[BCObjectIdentifiers.hqc128] = new HqcConverter(); - converters[BCObjectIdentifiers.hqc192] = new HqcConverter(); - converters[BCObjectIdentifiers.hqc256] = new HqcConverter(); + Converters[BCObjectIdentifiers.kyber512] = new KyberConverter(); + Converters[BCObjectIdentifiers.kyber512_aes] = new KyberConverter(); + Converters[BCObjectIdentifiers.kyber768] = new KyberConverter(); + Converters[BCObjectIdentifiers.kyber768_aes] = new KyberConverter(); + Converters[BCObjectIdentifiers.kyber1024] = new KyberConverter(); + Converters[BCObjectIdentifiers.kyber1024_aes] = new KyberConverter(); + + Converters[BCObjectIdentifiers.bike128] = new BikeConverter(); + Converters[BCObjectIdentifiers.bike192] = new BikeConverter(); + Converters[BCObjectIdentifiers.bike256] = new BikeConverter(); + + Converters[BCObjectIdentifiers.hqc128] = new HqcConverter(); + Converters[BCObjectIdentifiers.hqc192] = new HqcConverter(); + Converters[BCObjectIdentifiers.hqc256] = new HqcConverter(); } - + /// <summary> Create a public key from a SubjectPublicKeyInfo encoding</summary> /// <param name="keyInfoData"> the SubjectPublicKeyInfo encoding</param> /// <returns> the appropriate key parameter</returns> @@ -140,7 +153,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities public static AsymmetricKeyParameter CreateKey(SubjectPublicKeyInfo keyInfo, object defaultParams) { AlgorithmIdentifier algId = keyInfo.AlgorithmID; - SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters[algId.Algorithm]; + SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)Converters[algId.Algorithm]; if (converter != null) { @@ -155,7 +168,30 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities { internal abstract AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams); } - + + private class LmsConverter + : SubjectPublicKeyInfoConverter + { + internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams) + { + byte[] keyEnc = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); + + if (Pack.BE_To_UInt32(keyEnc, 0) == 1U) + { + return LmsPublicKeyParameters.GetInstance(Arrays.CopyOfRange(keyEnc, 4, keyEnc.Length)); + } + else + { + // public key with extra tree height + if (keyEnc.Length == 64) + { + keyEnc = Arrays.CopyOfRange(keyEnc, 4, keyEnc.Length); + } + return HssPublicKeyParameters.GetInstance(keyEnc); + } + } + } + private class SphincsPlusConverter : SubjectPublicKeyInfoConverter { @@ -215,9 +251,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities { byte[] keyEnc = DerOctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); - SIKEParameters sikeParams = PqcUtilities.SikeParamsLookup(keyInfo.AlgorithmID.Algorithm); + SikeParameters sikeParams = PqcUtilities.SikeParamsLookup(keyInfo.AlgorithmID.Algorithm); - return new SIKEPublicKeyParameters(sikeParams, keyEnc); + return new SikePublicKeyParameters(sikeParams, keyEnc); } } private class DilithiumConverter @@ -302,7 +338,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities { internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams) { - byte[] keyEnc = DerOctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); + byte[] keyEnc = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); BikeParameters bikeParams = PqcUtilities.BikeParamsLookup(keyInfo.AlgorithmID.Algorithm); @@ -314,7 +350,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities { internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams) { - byte[] keyEnc = DerOctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); + byte[] keyEnc = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); HqcParameters hqcParams = PqcUtilities.HqcParamsLookup(keyInfo.AlgorithmID.Algorithm); @@ -322,4 +358,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities } } } -} \ No newline at end of file +} diff --git a/crypto/src/pqc/crypto/utils/SecretWithEncapsulationImpl.cs b/crypto/src/pqc/crypto/utils/SecretWithEncapsulationImpl.cs index 17057ebfd..c4d3eb44f 100644 --- a/crypto/src/pqc/crypto/utils/SecretWithEncapsulationImpl.cs +++ b/crypto/src/pqc/crypto/utils/SecretWithEncapsulationImpl.cs @@ -1,59 +1,59 @@ using System; + using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Utilities { public class SecretWithEncapsulationImpl - : ISecretWithEncapsulation - { - private volatile bool hasBeenDestroyed = false; + : ISecretWithEncapsulation + { + private volatile bool hasBeenDestroyed = false; - private byte[] sessionKey; - private byte[] cipher_text; + private byte[] sessionKey; + private byte[] cipher_text; - public SecretWithEncapsulationImpl(byte[] sessionKey, byte[] cipher_text) - { - this.sessionKey = sessionKey; - this.cipher_text = cipher_text; - } + public SecretWithEncapsulationImpl(byte[] sessionKey, byte[] cipher_text) + { + this.sessionKey = sessionKey; + this.cipher_text = cipher_text; + } - public byte[] GetSecret() - { - CheckDestroyed(); + public byte[] GetSecret() + { + CheckDestroyed(); - return Arrays.Clone(sessionKey); - } + return Arrays.Clone(sessionKey); + } - public byte[] GetEncapsulation() - { - CheckDestroyed(); + public byte[] GetEncapsulation() + { + CheckDestroyed(); - return Arrays.Clone(cipher_text); - } + return Arrays.Clone(cipher_text); + } - public void Dispose() + public void Dispose() + { + if (!hasBeenDestroyed) { - if (!hasBeenDestroyed) - { - hasBeenDestroyed = true; - Arrays.Clear(sessionKey); - Arrays.Clear(cipher_text); - } + hasBeenDestroyed = true; + Arrays.Clear(sessionKey); + Arrays.Clear(cipher_text); } + } - public bool IsDestroyed() - { - return hasBeenDestroyed; - } + public bool IsDestroyed() + { + return hasBeenDestroyed; + } - void CheckDestroyed() + void CheckDestroyed() + { + if (IsDestroyed()) { - if (IsDestroyed()) - { - throw new Exception("data has been destroyed"); - } + throw new Exception("data has been destroyed"); } } - -} \ No newline at end of file + } +} diff --git a/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs b/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs index 47cb3e4cb..39d437320 100644 --- a/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs +++ b/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs @@ -1,9 +1,9 @@ using System; using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Math; using Org.BouncyCastle.Pqc.Asn1; using Org.BouncyCastle.Pqc.Crypto.Bike; using Org.BouncyCastle.Pqc.Crypto.Cmce; @@ -11,6 +11,7 @@ using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; using Org.BouncyCastle.Pqc.Crypto.Falcon; using Org.BouncyCastle.Pqc.Crypto.Hqc; +using Org.BouncyCastle.Pqc.Crypto.Lms; using Org.BouncyCastle.Pqc.Crypto.Picnic; using Org.BouncyCastle.Pqc.Crypto.Saber; using Org.BouncyCastle.Pqc.Crypto.Sike; @@ -19,161 +20,127 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Utilities { - /// <summary> /// A factory to produce Public Key Info Objects. /// </summary> - public class SubjectPublicKeyInfoFactory + public static class SubjectPublicKeyInfoFactory { - private SubjectPublicKeyInfoFactory() - { - } - /// <summary> /// Create a Subject Public Key Info object for a given public key. /// </summary> /// <param name="publicKey">One of ElGammalPublicKeyParameters, DSAPublicKeyParameter, DHPublicKeyParameters, RsaKeyParameters or ECPublicKeyParameters</param> /// <returns>A subject public key info object.</returns> /// <exception cref="Exception">Throw exception if object provided is not one of the above.</exception> - public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo( - AsymmetricKeyParameter publicKey) + public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo(AsymmetricKeyParameter publicKey) { if (publicKey == null) throw new ArgumentNullException("publicKey"); if (publicKey.IsPrivate) throw new ArgumentException("Private key passed - public key expected.", "publicKey"); - - if (publicKey is SphincsPlusPublicKeyParameters) + + if (publicKey is LmsPublicKeyParameters lmsPublicKeyParameters) { - SphincsPlusPublicKeyParameters parameters = (SphincsPlusPublicKeyParameters)publicKey; + byte[] encoding = Composer.Compose().U32Str(1).Bytes(lmsPublicKeyParameters).Build(); - byte[] encoding = parameters.GetEncoded(); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdAlgHssLmsHashsig); + return new SubjectPublicKeyInfo(algorithmIdentifier, new DerOctetString(encoding)); + } + if (publicKey is HssPublicKeyParameters hssPublicKeyParameters) + { + int L = hssPublicKeyParameters.L; + byte[] encoding = Composer.Compose().U32Str(L).Bytes(hssPublicKeyParameters.LmsPublicKey).Build(); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( - PqcUtilities.SphincsPlusOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdAlgHssLmsHashsig); return new SubjectPublicKeyInfo(algorithmIdentifier, new DerOctetString(encoding)); } - if (publicKey is CmcePublicKeyParameters) + if (publicKey is SphincsPlusPublicKeyParameters sphincsPlusPublicKeyParameters) { - CmcePublicKeyParameters key = (CmcePublicKeyParameters)publicKey; + byte[] encoding = sphincsPlusPublicKeyParameters.GetEncoded(); - byte[] encoding = key.GetEncoded(); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.SphincsPlusOidLookup(sphincsPlusPublicKeyParameters.Parameters)); + return new SubjectPublicKeyInfo(algorithmIdentifier, new DerOctetString(encoding)); + } + if (publicKey is CmcePublicKeyParameters cmcePublicKeyParameters) + { + byte[] encoding = cmcePublicKeyParameters.GetEncoded(); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.McElieceOidLookup(key.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.McElieceOidLookup(cmcePublicKeyParameters.Parameters)); // https://datatracker.ietf.org/doc/draft-uni-qsckeys/ return new SubjectPublicKeyInfo(algorithmIdentifier, new CmcePublicKey(encoding)); } - if (publicKey is SaberPublicKeyParameters) + if (publicKey is SaberPublicKeyParameters saberPublicKeyParameters) { - SaberPublicKeyParameters parameters = (SaberPublicKeyParameters)publicKey; - - byte[] encoding = parameters.GetEncoded(); + byte[] encoding = saberPublicKeyParameters.GetEncoded(); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.SaberOidLookup(parameters.GetParameters())); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.SaberOidLookup(saberPublicKeyParameters.Parameters)); // https://datatracker.ietf.org/doc/draft-uni-qsckeys/ return new SubjectPublicKeyInfo(algorithmIdentifier, new DerSequence(new DerOctetString(encoding))); } - if (publicKey is PicnicPublicKeyParameters) + if (publicKey is PicnicPublicKeyParameters picnicPublicKeyParameters) { - PicnicPublicKeyParameters parameters = (PicnicPublicKeyParameters)publicKey; - - byte[] encoding = parameters.GetEncoded(); + byte[] encoding = picnicPublicKeyParameters.GetEncoded(); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.PicnicOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.PicnicOidLookup(picnicPublicKeyParameters.Parameters)); return new SubjectPublicKeyInfo(algorithmIdentifier, new DerOctetString(encoding)); } - if (publicKey is SIKEPublicKeyParameters) + if (publicKey is SikePublicKeyParameters sikePublicKeyParameters) { - SIKEPublicKeyParameters parameters = (SIKEPublicKeyParameters)publicKey; + byte[] encoding = sikePublicKeyParameters.GetEncoded(); - byte[] encoding = parameters.GetEncoded(); - - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.SikeOidLookup(parameters.GetParameters())); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.SikeOidLookup(sikePublicKeyParameters.Parameters)); return new SubjectPublicKeyInfo(algorithmIdentifier, new DerOctetString(encoding)); } - if (publicKey is FalconPublicKeyParameters) + if (publicKey is FalconPublicKeyParameters falconPublicKeyParameters) { - FalconPublicKeyParameters parameters = (FalconPublicKeyParameters)publicKey; - - byte[] encoding = parameters.GetEncoded(); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.FalconOidLookup(parameters.Parameters)); + byte[] encoding = falconPublicKeyParameters.GetEncoded(); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.FalconOidLookup(falconPublicKeyParameters.Parameters)); return new SubjectPublicKeyInfo(algorithmIdentifier, new DerSequence(new DerOctetString(encoding))); } - if (publicKey is KyberPublicKeyParameters) + if (publicKey is KyberPublicKeyParameters kyberPublicKeyParameters) { - KyberPublicKeyParameters parameters = (KyberPublicKeyParameters)publicKey; - - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.KyberOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.KyberOidLookup(kyberPublicKeyParameters.Parameters)); Asn1EncodableVector v = new Asn1EncodableVector(); - v.Add(new DerOctetString(parameters.T)); - v.Add(new DerOctetString(parameters.Rho)); + v.Add(new DerOctetString(kyberPublicKeyParameters.T)); + v.Add(new DerOctetString(kyberPublicKeyParameters.Rho)); return new SubjectPublicKeyInfo(algorithmIdentifier, new DerSequence(v)); } - if (publicKey is DilithiumPublicKeyParameters) + if (publicKey is DilithiumPublicKeyParameters dilithiumPublicKeyParameters) { - DilithiumPublicKeyParameters parameters = (DilithiumPublicKeyParameters)publicKey; - - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.DilithiumOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.DilithiumOidLookup(dilithiumPublicKeyParameters.Parameters)); - return new SubjectPublicKeyInfo(algorithmIdentifier, new DerOctetString(Arrays.Concatenate(parameters.Rho, parameters.T1))); + return new SubjectPublicKeyInfo(algorithmIdentifier, + new DerOctetString(Arrays.Concatenate(dilithiumPublicKeyParameters.Rho, dilithiumPublicKeyParameters.T1))); } - if (publicKey is BikePublicKeyParameters) + if (publicKey is BikePublicKeyParameters bikePublicKeyParameters) { - BikePublicKeyParameters parameters = (BikePublicKeyParameters)publicKey; - - - byte[] encoding = parameters.GetEncoded(); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.BikeOidLookup(parameters.Parameters)); + byte[] encoding = bikePublicKeyParameters.GetEncoded(); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.BikeOidLookup(bikePublicKeyParameters.Parameters)); return new SubjectPublicKeyInfo(algorithmIdentifier, new DerOctetString(encoding)); } - if (publicKey is HqcPublicKeyParameters) + if (publicKey is HqcPublicKeyParameters hqcPublicKeyParameters) { - HqcPublicKeyParameters parameters = (HqcPublicKeyParameters)publicKey; - + byte[] encoding = hqcPublicKeyParameters.GetEncoded(); - byte[] encoding = parameters.GetEncoded(); - AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PqcUtilities.HqcOidLookup(parameters.Parameters)); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( + PqcUtilities.HqcOidLookup(hqcPublicKeyParameters.Parameters)); return new SubjectPublicKeyInfo(algorithmIdentifier, new DerOctetString(encoding)); } throw new ArgumentException("Class provided no convertible: " + Platform.GetTypeName(publicKey)); } - - private static void ExtractBytes( - byte[] encKey, - int offset, - BigInteger bI) - { - byte[] val = bI.ToByteArray(); - int n = (bI.BitLength + 7) / 8; - - for (int i = 0; i < n; ++i) - { - encKey[offset + i] = val[val.Length - 1 - i]; - } - } - - - private static void ExtractBytes(byte[] encKey, int size, int offSet, BigInteger bI) - { - byte[] val = bI.ToByteArray(); - if (val.Length < size) - { - byte[] tmp = new byte[size]; - Array.Copy(val, 0, tmp, tmp.Length - val.Length, val.Length); - val = tmp; - } - - for (int i = 0; i != size; i++) - { - encKey[offSet + i] = val[val.Length - 1 - i]; - } - } - } -} \ No newline at end of file +} diff --git a/crypto/src/security/CipherUtilities.cs b/crypto/src/security/CipherUtilities.cs index 8fbf19218..11bf45680 100644 --- a/crypto/src/security/CipherUtilities.cs +++ b/crypto/src/security/CipherUtilities.cs @@ -246,7 +246,7 @@ namespace Org.BouncyCastle.Security Algorithms["GOST"] = "GOST28147"; Algorithms["GOST-28147"] = "GOST28147"; - Algorithms[CryptoProObjectIdentifiers.GostR28147Cbc.Id] = "GOST28147/CBC/PKCS7PADDING"; + Algorithms[CryptoProObjectIdentifiers.GostR28147Gcfb.Id] = "GOST28147/CBC/PKCS7PADDING"; Algorithms["RC5-32"] = "RC5"; diff --git a/crypto/src/security/DotNetUtilities.cs b/crypto/src/security/DotNetUtilities.cs index ccfb2b2b8..3a7c5f0cb 100644 --- a/crypto/src/security/DotNetUtilities.cs +++ b/crypto/src/security/DotNetUtilities.cs @@ -18,9 +18,6 @@ namespace Org.BouncyCastle.Security /// <summary> /// A class containing methods to interface the BouncyCastle world to the .NET Crypto world. /// </summary> -#if NET5_0_OR_GREATER - [SupportedOSPlatform("windows")] -#endif public static class DotNetUtilities { /// <summary> @@ -153,33 +150,51 @@ namespace Org.BouncyCastle.Security throw new ArgumentException("Unsupported algorithm specified", "privateKey"); } +#if NET5_0_OR_GREATER + [SupportedOSPlatform("windows")] +#endif public static RSA ToRSA(RsaKeyParameters rsaKey) { // TODO This appears to not work for private keys (when no CRT info) return CreateRSAProvider(ToRSAParameters(rsaKey)); } +#if NET5_0_OR_GREATER + [SupportedOSPlatform("windows")] +#endif public static RSA ToRSA(RsaKeyParameters rsaKey, CspParameters csp) { // TODO This appears to not work for private keys (when no CRT info) return CreateRSAProvider(ToRSAParameters(rsaKey), csp); } +#if NET5_0_OR_GREATER + [SupportedOSPlatform("windows")] +#endif public static RSA ToRSA(RsaPrivateCrtKeyParameters privKey) { return CreateRSAProvider(ToRSAParameters(privKey)); } +#if NET5_0_OR_GREATER + [SupportedOSPlatform("windows")] +#endif public static RSA ToRSA(RsaPrivateCrtKeyParameters privKey, CspParameters csp) { return CreateRSAProvider(ToRSAParameters(privKey), csp); } +#if NET5_0_OR_GREATER + [SupportedOSPlatform("windows")] +#endif public static RSA ToRSA(RsaPrivateKeyStructure privKey) { return CreateRSAProvider(ToRSAParameters(privKey)); } +#if NET5_0_OR_GREATER + [SupportedOSPlatform("windows")] +#endif public static RSA ToRSA(RsaPrivateKeyStructure privKey, CspParameters csp) { return CreateRSAProvider(ToRSAParameters(privKey), csp); @@ -229,6 +244,9 @@ namespace Org.BouncyCastle.Security return BigIntegers.AsUnsignedByteArray(size, n); } +#if NET5_0_OR_GREATER + [SupportedOSPlatform("windows")] +#endif private static RSACryptoServiceProvider CreateRSAProvider(RSAParameters rp) { CspParameters csp = new CspParameters(); @@ -236,6 +254,9 @@ namespace Org.BouncyCastle.Security return CreateRSAProvider(rp, csp); } +#if NET5_0_OR_GREATER + [SupportedOSPlatform("windows")] +#endif private static RSACryptoServiceProvider CreateRSAProvider(RSAParameters rp, CspParameters csp) { RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp); diff --git a/crypto/src/security/GeneratorUtilities.cs b/crypto/src/security/GeneratorUtilities.cs index c48a71f2e..26898aaf8 100644 --- a/crypto/src/security/GeneratorUtilities.cs +++ b/crypto/src/security/GeneratorUtilities.cs @@ -127,7 +127,7 @@ namespace Org.BouncyCastle.Security AddKgAlgorithm("GOST28147", "GOST", "GOST-28147", - CryptoProObjectIdentifiers.GostR28147Cbc); + CryptoProObjectIdentifiers.GostR28147Gcfb); AddKgAlgorithm("HC128"); AddKgAlgorithm("HC256"); AddKgAlgorithm("IDEA", @@ -222,6 +222,8 @@ namespace Org.BouncyCastle.Security AddKpgAlgorithm("ECGOST3410", "ECGOST-3410", "GOST-3410-2001"); + AddKpgAlgorithm("ECGOST3410-2012", + "GOST-3410-2012"); AddKpgAlgorithm("Ed25519", "Ed25519ctx", "Ed25519ph", @@ -358,7 +360,7 @@ namespace Org.BouncyCastle.Security if (canonicalName == "DSA") return new DsaKeyPairGenerator(); - // "EC", "ECDH", "ECDHC", "ECDSA", "ECGOST3410", "ECMQV" + // "EC", "ECDH", "ECDHC", "ECDSA", "ECGOST3410", "ECGOST3410-2012", "ECMQV" if (Platform.StartsWith(canonicalName, "EC")) return new ECKeyPairGenerator(canonicalName); diff --git a/crypto/src/security/JksStore.cs b/crypto/src/security/JksStore.cs index 9b4269278..30b21fad2 100644 --- a/crypto/src/security/JksStore.cs +++ b/crypto/src/security/JksStore.cs @@ -38,7 +38,7 @@ namespace Org.BouncyCastle.Security using (var br = new BinaryReader(stream)) try { - return Magic == ReadInt32(br); + return Magic == BinaryReaders.ReadInt32BigEndian(br); } catch (EndOfStreamException) { @@ -154,7 +154,7 @@ namespace Org.BouncyCastle.Security byte[] pkcs8Key = PrivateKeyInfoFactory.CreatePrivateKeyInfo(key).GetEncoded(); byte[] protectedKey = new byte[pkcs8Key.Length + 40]; - SecureRandom rnd = new SecureRandom(); + SecureRandom rnd = CryptoServicesRegistrar.GetSecureRandom(); rnd.NextBytes(protectedKey, 0, 20); IDigest digest = DigestUtilities.GetDigest("SHA-1"); @@ -263,24 +263,24 @@ namespace Org.BouncyCastle.Security IDigest checksumDigest = CreateChecksumDigest(password); BinaryWriter bw = new BinaryWriter(new DigestStream(stream, null, checksumDigest)); - WriteInt32(bw, Magic); - WriteInt32(bw, 2); + BinaryWriters.WriteInt32BigEndian(bw, Magic); + BinaryWriters.WriteInt32BigEndian(bw, 2); - WriteInt32(bw, Count); + BinaryWriters.WriteInt32BigEndian(bw, Count); foreach (var entry in m_keyEntries) { string alias = entry.Key; JksKeyEntry keyEntry = entry.Value; - WriteInt32(bw, 1); + BinaryWriters.WriteInt32BigEndian(bw, 1); WriteUtf(bw, alias); WriteDateTime(bw, keyEntry.date); - WriteBufferWithLength(bw, keyEntry.keyData.GetEncoded()); + WriteBufferWithInt32Length(bw, keyEntry.keyData.GetEncoded()); X509Certificate[] chain = keyEntry.chain; int chainLength = chain == null ? 0 : chain.Length; - WriteInt32(bw, chainLength); + BinaryWriters.WriteInt32BigEndian(bw, chainLength); for (int i = 0; i < chainLength; ++i) { WriteTypedCertificate(bw, chain[i]); @@ -292,7 +292,7 @@ namespace Org.BouncyCastle.Security string alias = entry.Key; JksTrustedCertEntry certEntry = entry.Value; - WriteInt32(bw, 2); + BinaryWriters.WriteInt32BigEndian(bw, 2); WriteUtf(bw, alias); WriteDateTime(bw, certEntry.date); WriteTypedCertificate(bw, certEntry.cert); @@ -314,39 +314,39 @@ namespace Org.BouncyCastle.Security using (var storeStream = ValidateStream(stream, password)) { - BinaryReader dIn = new BinaryReader(storeStream); + BinaryReader br = new BinaryReader(storeStream); - int magic = ReadInt32(dIn); - int storeVersion = ReadInt32(dIn); + int magic = BinaryReaders.ReadInt32BigEndian(br); + int storeVersion = BinaryReaders.ReadInt32BigEndian(br); if (!(magic == Magic && (storeVersion == 1 || storeVersion == 2))) throw new IOException("Invalid keystore format"); - int numEntries = ReadInt32(dIn); + int numEntries = BinaryReaders.ReadInt32BigEndian(br); for (int t = 0; t < numEntries; t++) { - int tag = ReadInt32(dIn); + int tag = BinaryReaders.ReadInt32BigEndian(br); switch (tag) { case 1: // keys { - string alias = ReadUtf(dIn); - DateTime date = ReadDateTime(dIn); + string alias = ReadUtf(br); + DateTime date = ReadDateTime(br); // encrypted key data - byte[] keyData = ReadBufferWithLength(dIn); + byte[] keyData = ReadBufferWithInt32Length(br); // certificate chain - int chainLength = ReadInt32(dIn); + int chainLength = BinaryReaders.ReadInt32BigEndian(br); X509Certificate[] chain = null; if (chainLength > 0) { var certs = new List<X509Certificate>(System.Math.Min(10, chainLength)); for (int certNo = 0; certNo != chainLength; certNo++) { - certs.Add(ReadTypedCertificate(dIn, storeVersion)); + certs.Add(ReadTypedCertificate(br, storeVersion)); } chain = certs.ToArray(); } @@ -355,10 +355,10 @@ namespace Org.BouncyCastle.Security } case 2: // certificate { - string alias = ReadUtf(dIn); - DateTime date = ReadDateTime(dIn); + string alias = ReadUtf(br); + DateTime date = ReadDateTime(br); - X509Certificate cert = ReadTypedCertificate(dIn, storeVersion); + X509Certificate cert = ReadTypedCertificate(br, storeVersion); m_certificateEntries.Add(alias, new JksTrustedCertEntry(date, cert)); break; @@ -446,29 +446,22 @@ namespace Org.BouncyCastle.Security return digest; } - private static byte[] ReadBufferWithLength(BinaryReader br) + private static byte[] ReadBufferWithInt16Length(BinaryReader br) { - int length = ReadInt32(br); - return br.ReadBytes(length); + int length = BinaryReaders.ReadInt16BigEndian(br); + return BinaryReaders.ReadBytesFully(br, length); } - private static DateTime ReadDateTime(BinaryReader br) - { - DateTime unixMs = DateTimeUtilities.UnixMsToDateTime(Longs.ReverseBytes(br.ReadInt64())); - DateTime utc = new DateTime(unixMs.Ticks, DateTimeKind.Utc); - return utc; - } - - private static short ReadInt16(BinaryReader br) + private static byte[] ReadBufferWithInt32Length(BinaryReader br) { - short n = br.ReadInt16(); - n = (short)(((n & 0xFF) << 8) | ((n >> 8) & 0xFF)); - return n; + int length = BinaryReaders.ReadInt32BigEndian(br); + return BinaryReaders.ReadBytesFully(br, length); } - private static int ReadInt32(BinaryReader br) + private static DateTime ReadDateTime(BinaryReader br) { - return Integers.ReverseBytes(br.ReadInt32()); + long unixMS = BinaryReaders.ReadInt64BigEndian(br); + return DateTimeUtilities.UnixMsToDateTime(unixMS); } private static X509Certificate ReadTypedCertificate(BinaryReader br, int storeVersion) @@ -480,7 +473,7 @@ namespace Org.BouncyCastle.Security throw new IOException("Unsupported certificate format: " + certFormat); } - byte[] certData = ReadBufferWithLength(br); + byte[] certData = ReadBufferWithInt32Length(br); try { return new X509Certificate(certData); @@ -493,8 +486,7 @@ namespace Org.BouncyCastle.Security private static string ReadUtf(BinaryReader br) { - short length = ReadInt16(br); - byte[] utfBytes = br.ReadBytes(length); + byte[] utfBytes = ReadBufferWithInt16Length(br); /* * FIXME JKS actually uses a "modified UTF-8" format. For the moment we will just support single-byte @@ -510,32 +502,28 @@ namespace Org.BouncyCastle.Security return Encoding.UTF8.GetString(utfBytes); } - private static void WriteBufferWithLength(BinaryWriter bw, byte[] buffer) + private static void WriteBufferWithInt16Length(BinaryWriter bw, byte[] buffer) { - WriteInt32(bw, buffer.Length); + BinaryWriters.WriteInt16BigEndian(bw, Convert.ToInt16(buffer.Length)); bw.Write(buffer); } - private static void WriteDateTime(BinaryWriter bw, DateTime dateTime) + private static void WriteBufferWithInt32Length(BinaryWriter bw, byte[] buffer) { - bw.Write(Longs.ReverseBytes(DateTimeUtilities.DateTimeToUnixMs(dateTime.ToUniversalTime()))); - } - - private static void WriteInt16(BinaryWriter bw, short n) - { - n = (short)(((n & 0xFF) << 8) | ((n >> 8) & 0xFF)); - bw.Write(n); + BinaryWriters.WriteInt32BigEndian(bw, buffer.Length); + bw.Write(buffer); } - private static void WriteInt32(BinaryWriter bw, int n) + private static void WriteDateTime(BinaryWriter bw, DateTime dateTime) { - bw.Write(Integers.ReverseBytes(n)); + long unixMS = DateTimeUtilities.DateTimeToUnixMs(dateTime); + BinaryWriters.WriteInt64BigEndian(bw, unixMS); } private static void WriteTypedCertificate(BinaryWriter bw, X509Certificate cert) { WriteUtf(bw, "X.509"); - WriteBufferWithLength(bw, cert.GetEncoded()); + WriteBufferWithInt32Length(bw, cert.GetEncoded()); } private static void WriteUtf(BinaryWriter bw, string s) @@ -553,8 +541,7 @@ namespace Org.BouncyCastle.Security throw new NotSupportedException("Currently missing support for modified UTF-8 encoding in JKS"); } - WriteInt16(bw, Convert.ToInt16(utfBytes.Length)); - bw.Write(utfBytes); + WriteBufferWithInt16Length(bw, utfBytes); } /** diff --git a/crypto/src/security/ParameterUtilities.cs b/crypto/src/security/ParameterUtilities.cs index 5a407fc9d..d79f15359 100644 --- a/crypto/src/security/ParameterUtilities.cs +++ b/crypto/src/security/ParameterUtilities.cs @@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Security AddAlgorithm("GOST28147", "GOST", "GOST-28147", - CryptoProObjectIdentifiers.GostR28147Cbc); + CryptoProObjectIdentifiers.GostR28147Gcfb); AddAlgorithm("HC128"); AddAlgorithm("HC256"); AddAlgorithm("IDEA", diff --git a/crypto/src/security/SecureRandom.cs b/crypto/src/security/SecureRandom.cs index 10b837b03..521e7db0e 100644 --- a/crypto/src/security/SecureRandom.cs +++ b/crypto/src/security/SecureRandom.cs @@ -17,7 +17,8 @@ namespace Org.BouncyCastle.Security return Interlocked.Increment(ref counter); } - private static readonly SecureRandom Master = new SecureRandom(new CryptoApiRandomGenerator()); + private static readonly SecureRandom MasterRandom = new SecureRandom(new CryptoApiRandomGenerator()); + internal static readonly SecureRandom ArbitraryRandom = new SecureRandom(new VmpcRandomGenerator(), 16); private static DigestRandomGenerator CreatePrng(string digestName, bool autoSeed) { @@ -27,18 +28,7 @@ namespace Org.BouncyCastle.Security DigestRandomGenerator prng = new DigestRandomGenerator(digest); if (autoSeed) { - prng.AddSeedMaterial(NextCounterValue()); - - int seedLength = digest.GetDigestSize(); -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - Span<byte> seed = seedLength <= 128 - ? stackalloc byte[seedLength] - : new byte[seedLength]; -#else - byte[] seed = new byte[seedLength]; -#endif - Master.NextBytes(seed); - prng.AddSeedMaterial(seed); + AutoSeed(prng, digest.GetDigestSize()); } return prng; } @@ -103,15 +93,23 @@ namespace Org.BouncyCastle.Security this.generator = generator; } + public SecureRandom(IRandomGenerator generator, int autoSeedLengthInBytes) + : base(0) + { + AutoSeed(generator, autoSeedLengthInBytes); + + this.generator = generator; + } + public virtual byte[] GenerateSeed(int length) { - return GetNextBytes(Master, length); + return GetNextBytes(MasterRandom, length); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public virtual void GenerateSeed(Span<byte> seed) { - Master.NextBytes(seed); + MasterRandom.NextBytes(seed); } #endif @@ -246,5 +244,20 @@ namespace Org.BouncyCastle.Security NextBytes(bytes); return (long)Pack.BE_To_UInt64(bytes); } + + private static void AutoSeed(IRandomGenerator generator, int seedLength) + { + generator.AddSeedMaterial(NextCounterValue()); + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Span<byte> seed = seedLength <= 128 + ? stackalloc byte[seedLength] + : new byte[seedLength]; +#else + byte[] seed = new byte[seedLength]; +#endif + MasterRandom.NextBytes(seed); + generator.AddSeedMaterial(seed); + } } } diff --git a/crypto/src/security/SignerUtilities.cs b/crypto/src/security/SignerUtilities.cs index e42e217cc..e6210dad7 100644 --- a/crypto/src/security/SignerUtilities.cs +++ b/crypto/src/security/SignerUtilities.cs @@ -19,6 +19,7 @@ using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Signers; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Asn1.Rosstandart; namespace Org.BouncyCastle.Security { @@ -367,13 +368,29 @@ namespace Org.BouncyCastle.Security AlgorithmMap["GOST-3410"] = "GOST3410"; AlgorithmMap["GOST-3410-94"] = "GOST3410"; AlgorithmMap["GOST3411WITHGOST3410"] = "GOST3410"; + AlgorithmMap["GOST3411/GOST3410"] = "GOST3410"; AlgorithmMap[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94.Id] = "GOST3410"; AlgorithmMap["ECGOST-3410"] = "ECGOST3410"; - AlgorithmMap["ECGOST-3410-2001"] = "ECGOST3410"; + AlgorithmMap["GOST-3410-2001"] = "ECGOST3410"; AlgorithmMap["GOST3411WITHECGOST3410"] = "ECGOST3410"; + AlgorithmMap["GOST3411/ECGOST3410"] = "ECGOST3410"; AlgorithmMap[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001.Id] = "ECGOST3410"; + AlgorithmMap["GOST-3410-2012-256"] = "ECGOST3410-2012-256"; + AlgorithmMap["GOST3411WITHECGOST3410-2012-256"] = "ECGOST3410-2012-256"; + AlgorithmMap["GOST3411-2012-256WITHECGOST3410-2012-256"] = "ECGOST3410-2012-256"; + AlgorithmMap["GOST3411-2012-256/ECGOST3410-2012-256"] = "ECGOST3410-2012-256"; + AlgorithmMap[RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256.Id] = + "ECGOST3410-2012-256"; + + AlgorithmMap["GOST-3410-2012-512"] = "ECGOST3410-2012-512"; + AlgorithmMap["GOST3411WITHECGOST3410-2012-512"] = "ECGOST3410-2012-512"; + AlgorithmMap["GOST3411-2012-512WITHECGOST3410-2012-512"] = "ECGOST3410-2012-512"; + AlgorithmMap["GOST3411-2012-512/ECGOST3410-2012-512"] = "ECGOST3410-2012-512"; + AlgorithmMap[RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512.Id] = + "ECGOST3410-2012-512"; + AlgorithmMap["ED25519"] = "Ed25519"; AlgorithmMap[EdECObjectIdentifiers.id_Ed25519.Id] = "Ed25519"; AlgorithmMap["ED25519CTX"] = "Ed25519ctx"; @@ -439,6 +456,9 @@ namespace Org.BouncyCastle.Security Oids["GOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94; Oids["ECGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001; + Oids["ECGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256; + Oids["ECGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512; + Oids["Ed25519"] = EdECObjectIdentifiers.id_Ed25519; Oids["Ed448"] = EdECObjectIdentifiers.id_Ed448; @@ -618,6 +638,14 @@ namespace Org.BouncyCastle.Security { return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest()); } + if (mechanism.Equals("ECGOST3410-2012-256")) + { + return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_256Digest()); + } + if (mechanism.Equals("ECGOST3410-2012-512")) + { + return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_512Digest()); + } if (mechanism.Equals("SHA1WITHRSA/ISO9796-2")) { diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs index 66f47c091..8e193f187 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs @@ -28,12 +28,15 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC private readonly SecureRandom m_entropySource; public BcTlsCrypto() - : this(new SecureRandom()) + : this(CryptoServicesRegistrar.GetSecureRandom()) { } public BcTlsCrypto(SecureRandom entropySource) { + if (entropySource == null) + throw new ArgumentNullException(nameof(entropySource)); + this.m_entropySource = entropySource; } diff --git a/crypto/src/tsp/TimeStampTokenGenerator.cs b/crypto/src/tsp/TimeStampTokenGenerator.cs index 79b8c6a3a..9e6a21f9c 100644 --- a/crypto/src/tsp/TimeStampTokenGenerator.cs +++ b/crypto/src/tsp/TimeStampTokenGenerator.cs @@ -334,21 +334,18 @@ namespace Org.BouncyCastle.Tsp respExtensions = extGen.Generate(); } - - - DerGeneralizedTime generalizedTime; - if (resolution != Resolution.R_SECONDS) + Asn1GeneralizedTime timeStampTime; + if (resolution == Resolution.R_SECONDS) { - generalizedTime = new DerGeneralizedTime(createGeneralizedTime(genTime)); - } + timeStampTime = new Asn1GeneralizedTime(genTime); + } else { - generalizedTime = new DerGeneralizedTime(genTime); - } - + timeStampTime = CreateGeneralizedTime(genTime); + } TstInfo tstInfo = new TstInfo(tsaPolicy, messageImprint, - new DerInteger(serialNumber), generalizedTime, accuracy, + new DerInteger(serialNumber), timeStampTime, accuracy, derOrdering, nonce, tsa, respExtensions); try @@ -382,13 +379,13 @@ namespace Org.BouncyCastle.Tsp { throw new TspException("Exception encoding info", e); } - // catch (InvalidAlgorithmParameterException e) - // { - // throw new TspException("Exception handling CertStore CRLs", e); - // } + //catch (InvalidAlgorithmParameterException e) + //{ + // throw new TspException("Exception handling CertStore CRLs", e); + //} } - private string createGeneralizedTime(DateTime genTime) + private Asn1GeneralizedTime CreateGeneralizedTime(DateTime genTime) { string format = "yyyyMMddHHmmss.fff"; @@ -398,33 +395,31 @@ namespace Org.BouncyCastle.Tsp if (dotIndex <0) { sBuild.Append("Z"); - return sBuild.ToString(); + return new Asn1GeneralizedTime(sBuild.ToString()); } switch(resolution) { - case Resolution.R_TENTHS_OF_SECONDS: - if (sBuild.Length > dotIndex + 2) - { - sBuild.Remove(dotIndex + 2, sBuild.Length-(dotIndex+2)); - } - break; - case Resolution.R_HUNDREDTHS_OF_SECONDS: - if (sBuild.Length > dotIndex + 3) - { - sBuild.Remove(dotIndex + 3, sBuild.Length-(dotIndex+3)); - } - break; + case Resolution.R_TENTHS_OF_SECONDS: + if (sBuild.Length > dotIndex + 2) + { + sBuild.Remove(dotIndex + 2, sBuild.Length-(dotIndex+2)); + } + break; + case Resolution.R_HUNDREDTHS_OF_SECONDS: + if (sBuild.Length > dotIndex + 3) + { + sBuild.Remove(dotIndex + 3, sBuild.Length-(dotIndex+3)); + } + break; - case Resolution.R_SECONDS: - case Resolution.R_MILLISECONDS: - // do nothing. - break; - + case Resolution.R_SECONDS: + case Resolution.R_MILLISECONDS: + // do nothing. + break; } - while (sBuild[sBuild.Length - 1] == '0') { sBuild.Remove(sBuild.Length - 1,1); @@ -436,7 +431,7 @@ namespace Org.BouncyCastle.Tsp } sBuild.Append("Z"); - return sBuild.ToString(); + return new Asn1GeneralizedTime(sBuild.ToString()); } private class TableGen diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs index e8dd02148..936e510be 100644 --- a/crypto/src/util/Arrays.cs +++ b/crypto/src/util/Arrays.cs @@ -631,10 +631,7 @@ namespace Org.BouncyCastle.Utilities #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Fill<T>(Span<T> ts, T t) { - for (int i = 0; i < ts.Length; ++i) - { - ts[i] = t; - } + ts.Fill(t); } #endif diff --git a/crypto/src/util/BigIntegers.cs b/crypto/src/util/BigIntegers.cs index 93dc8e8eb..e63af7c7c 100644 --- a/crypto/src/util/BigIntegers.cs +++ b/crypto/src/util/BigIntegers.cs @@ -9,7 +9,7 @@ namespace Org.BouncyCastle.Utilities /** * BigInteger utilities. */ - public abstract class BigIntegers + public static class BigIntegers { public static readonly BigInteger Zero = BigInteger.Zero; public static readonly BigInteger One = BigInteger.One; diff --git a/crypto/src/util/Bytes.cs b/crypto/src/util/Bytes.cs index ecde85dde..466eba576 100644 --- a/crypto/src/util/Bytes.cs +++ b/crypto/src/util/Bytes.cs @@ -2,7 +2,7 @@ namespace Org.BouncyCastle.Utilities { - public abstract class Bytes + public static class Bytes { public const int NumBits = 8; public const int NumBytes = 1; diff --git a/crypto/src/util/Integers.cs b/crypto/src/util/Integers.cs index 75ba566e3..ab1868b74 100644 --- a/crypto/src/util/Integers.cs +++ b/crypto/src/util/Integers.cs @@ -1,4 +1,7 @@ using System; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +using System.Buffers.Binary; +#endif #if NETCOREAPP3_0_OR_GREATER using System.Numerics; using System.Runtime.Intrinsics.X86; @@ -8,7 +11,7 @@ using Org.BouncyCastle.Math.Raw; namespace Org.BouncyCastle.Utilities { - public abstract class Integers + public static class Integers { public const int NumBits = 32; public const int NumBytes = 4; @@ -96,14 +99,22 @@ namespace Org.BouncyCastle.Utilities public static int ReverseBytes(int i) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return BinaryPrimitives.ReverseEndianness(i); +#else return (int)ReverseBytes((uint)i); +#endif } [CLSCompliant(false)] public static uint ReverseBytes(uint i) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return BinaryPrimitives.ReverseEndianness(i); +#else return RotateLeft(i & 0xFF00FF00U, 8) | RotateLeft(i & 0x00FF00FFU, 24); +#endif } public static int RotateLeft(int i, int distance) diff --git a/crypto/src/util/Longs.cs b/crypto/src/util/Longs.cs index 9e34dab99..02ffb7676 100644 --- a/crypto/src/util/Longs.cs +++ b/crypto/src/util/Longs.cs @@ -1,4 +1,7 @@ using System; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +using System.Buffers.Binary; +#endif #if NETCOREAPP3_0_OR_GREATER using System.Numerics; using System.Runtime.Intrinsics.X86; @@ -8,7 +11,7 @@ using Org.BouncyCastle.Math.Raw; namespace Org.BouncyCastle.Utilities { - public abstract class Longs + public static class Longs { public const int NumBits = 64; public const int NumBytes = 8; @@ -95,16 +98,24 @@ namespace Org.BouncyCastle.Utilities public static long ReverseBytes(long i) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return BinaryPrimitives.ReverseEndianness(i); +#else return (long)ReverseBytes((ulong)i); +#endif } [CLSCompliant(false)] public static ulong ReverseBytes(ulong i) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return BinaryPrimitives.ReverseEndianness(i); +#else return RotateLeft(i & 0xFF000000FF000000UL, 8) | RotateLeft(i & 0x00FF000000FF0000UL, 24) | RotateLeft(i & 0x0000FF000000FF00UL, 40) | RotateLeft(i & 0x000000FF000000FFUL, 56); +#endif } public static long RotateLeft(long i, int distance) diff --git a/crypto/src/util/Platform.cs b/crypto/src/util/Platform.cs index 75b728bd9..118c29918 100644 --- a/crypto/src/util/Platform.cs +++ b/crypto/src/util/Platform.cs @@ -3,7 +3,7 @@ using System.Globalization; namespace Org.BouncyCastle.Utilities { - internal abstract class Platform + internal static class Platform { private static readonly CompareInfo InvariantCompareInfo = CultureInfo.InvariantCulture.CompareInfo; diff --git a/crypto/src/util/Shorts.cs b/crypto/src/util/Shorts.cs new file mode 100644 index 000000000..eb9f13fa1 --- /dev/null +++ b/crypto/src/util/Shorts.cs @@ -0,0 +1,54 @@ +using System; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +using System.Buffers.Binary; +#endif + +namespace Org.BouncyCastle.Utilities +{ + public static class Shorts + { + public const int NumBits = 16; + public const int NumBytes = 2; + + public static short ReverseBytes(short i) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return BinaryPrimitives.ReverseEndianness(i); +#else + return RotateLeft(i, 8); +#endif + } + + [CLSCompliant(false)] + public static ushort ReverseBytes(ushort i) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return BinaryPrimitives.ReverseEndianness(i); +#else + return RotateLeft(i, 8); +#endif + } + + public static short RotateLeft(short i, int distance) + { + return (short)RotateLeft((ushort)i, distance); + } + + [CLSCompliant(false)] + public static ushort RotateLeft(ushort i, int distance) + { + return (ushort)((i << distance) | (i >> (16 - distance))); + } + + public static short RotateRight(short i, int distance) + { + return (short)RotateRight((ushort)i, distance); + } + + [CLSCompliant(false)] + public static ushort RotateRight(ushort i, int distance) + { + return (ushort)((i >> distance) | (i << (16 - distance))); + } + } +} diff --git a/crypto/src/util/Strings.cs b/crypto/src/util/Strings.cs index baee573be..12eafd21e 100644 --- a/crypto/src/util/Strings.cs +++ b/crypto/src/util/Strings.cs @@ -4,7 +4,7 @@ using System.Text; namespace Org.BouncyCastle.Utilities { /// <summary> General string utilities.</summary> - public abstract class Strings + public static class Strings { internal static bool IsOneOf(string s, params string[] candidates) { diff --git a/crypto/src/bzip2/BZip2Constants.cs b/crypto/src/util/bzip2/BZip2Constants.cs index 81db7fa57..6fc15e55f 100644 --- a/crypto/src/bzip2/BZip2Constants.cs +++ b/crypto/src/util/bzip2/BZip2Constants.cs @@ -22,9 +22,7 @@ * great code. */ -using System; - -namespace Org.BouncyCastle.Bzip2 +namespace Org.BouncyCastle.Utilities.Bzip2 { /** * Base class for both the compress and decompress classes. diff --git a/crypto/src/bzip2/CBZip2InputStream.cs b/crypto/src/util/bzip2/CBZip2InputStream.cs index b73e52a01..7879f28af 100644 --- a/crypto/src/bzip2/CBZip2InputStream.cs +++ b/crypto/src/util/bzip2/CBZip2InputStream.cs @@ -26,10 +26,9 @@ using System; using System.Diagnostics; using System.IO; -using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; -namespace Org.BouncyCastle.Bzip2 +namespace Org.BouncyCastle.Utilities.Bzip2 { /** * An input stream that decompresses from the BZip2 format (with the file diff --git a/crypto/src/bzip2/CBZip2OutputStream.cs b/crypto/src/util/bzip2/CBZip2OutputStream.cs index 5521dce56..b896f36c6 100644 --- a/crypto/src/bzip2/CBZip2OutputStream.cs +++ b/crypto/src/util/bzip2/CBZip2OutputStream.cs @@ -27,10 +27,9 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; -namespace Org.BouncyCastle.Bzip2 +namespace Org.BouncyCastle.Utilities.Bzip2 { /** * An output stream that compresses into the BZip2 format (with the file @@ -1598,4 +1597,23 @@ namespace Org.BouncyCastle.Bzip2 return a; } } + + public class CBZip2OutputStreamLeaveOpen + : CBZip2OutputStream + { + public CBZip2OutputStreamLeaveOpen(Stream outStream) + : base(outStream) + { + } + + public CBZip2OutputStreamLeaveOpen(Stream outStream, int blockSize) + : base(outStream, blockSize) + { + } + + protected override void Dispose(bool disposing) + { + Detach(disposing); + } + } } diff --git a/crypto/src/bzip2/CRC.cs b/crypto/src/util/bzip2/CRC.cs index 70d05e084..30c7e9c7d 100644 --- a/crypto/src/bzip2/CRC.cs +++ b/crypto/src/util/bzip2/CRC.cs @@ -22,12 +22,9 @@ * great code. */ -using System; using System.Diagnostics; -using Org.BouncyCastle.Utilities; - -namespace Org.BouncyCastle.Bzip2 +namespace Org.BouncyCastle.Utilities.Bzip2 { /** * A simple class the hold and calculate the CRC for sanity checking diff --git a/crypto/src/util/date/DateTimeUtilities.cs b/crypto/src/util/date/DateTimeUtilities.cs index 72e5123a2..3660e29c2 100644 --- a/crypto/src/util/date/DateTimeUtilities.cs +++ b/crypto/src/util/date/DateTimeUtilities.cs @@ -2,38 +2,48 @@ using System; namespace Org.BouncyCastle.Utilities.Date { - public class DateTimeUtilities + public static class DateTimeUtilities { - public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static readonly DateTime UnixEpoch = DateTime.UnixEpoch; +#else + public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); +#endif - private DateTimeUtilities() - { - } + public static readonly long MaxUnixMs = + (DateTime.MaxValue.Ticks - UnixEpoch.Ticks) / TimeSpan.TicksPerMillisecond; + public static readonly long MinUnixMs = 0L; - /// <summary> - /// Return the number of milliseconds since the Unix epoch (1 Jan., 1970 UTC) for a given DateTime value. - /// </summary> - /// <param name="dateTime">A UTC DateTime value not before epoch.</param> - /// <returns>Number of whole milliseconds after epoch.</returns> - /// <exception cref="ArgumentException">'dateTime' is before epoch.</exception> - public static long DateTimeToUnixMs( - DateTime dateTime) + /// <summary> + /// Return the number of milliseconds since the Unix epoch (1 Jan., 1970 UTC) for a given DateTime value. + /// </summary> + /// <remarks>The DateTime value will be converted to UTC (using <see cref="DateTime.ToUniversalTime"/> before + /// conversion.</remarks> + /// <param name="dateTime">A DateTime value not before the epoch.</param> + /// <returns>Number of whole milliseconds after epoch.</returns> + /// <exception cref="ArgumentOutOfRangeException">'dateTime' is before the epoch.</exception> + public static long DateTimeToUnixMs(DateTime dateTime) { - if (dateTime.CompareTo(UnixEpoch) < 0) - throw new ArgumentException("DateTime value may not be before the epoch", "dateTime"); + DateTime utc = dateTime.ToUniversalTime(); + if (utc.CompareTo(UnixEpoch) < 0) + throw new ArgumentOutOfRangeException(nameof(dateTime), "DateTime value may not be before the epoch"); - return (dateTime.Ticks - UnixEpoch.Ticks) / TimeSpan.TicksPerMillisecond; + return (utc.Ticks - UnixEpoch.Ticks) / TimeSpan.TicksPerMillisecond; } - /// <summary> - /// Create a DateTime value from the number of milliseconds since the Unix epoch (1 Jan., 1970 UTC). - /// </summary> - /// <param name="unixMs">Number of milliseconds since the epoch.</param> - /// <returns>A UTC DateTime value</returns> - public static DateTime UnixMsToDateTime( - long unixMs) + /// <summary> + /// Create a UTC DateTime value from the number of milliseconds since the Unix epoch (1 Jan., 1970 UTC). + /// </summary> + /// <param name="unixMs">Number of milliseconds since the epoch.</param> + /// <returns>A UTC DateTime value</returns> + /// <exception cref="ArgumentOutOfRangeException">'unixMs' is before 'MinUnixMs' or after 'MaxUnixMs'. + /// </exception> + public static DateTime UnixMsToDateTime(long unixMs) { - return new DateTime(unixMs * TimeSpan.TicksPerMillisecond + UnixEpoch.Ticks, DateTimeKind.Utc); + if (unixMs < MinUnixMs || unixMs > MaxUnixMs) + throw new ArgumentOutOfRangeException(nameof(unixMs)); + + return new DateTime(unixMs * TimeSpan.TicksPerMillisecond + UnixEpoch.Ticks, DateTimeKind.Utc); } /// <summary> diff --git a/crypto/src/util/io/BinaryReaders.cs b/crypto/src/util/io/BinaryReaders.cs new file mode 100644 index 000000000..c5f99a712 --- /dev/null +++ b/crypto/src/util/io/BinaryReaders.cs @@ -0,0 +1,94 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public static class BinaryReaders + { + public static byte[] ReadBytesFully(BinaryReader binaryReader, int count) + { + byte[] bytes = binaryReader.ReadBytes(count); + if (bytes == null || bytes.Length != count) + throw new EndOfStreamException(); + return bytes; + } + + public static short ReadInt16BigEndian(BinaryReader binaryReader) + { + short n = binaryReader.ReadInt16(); + return BitConverter.IsLittleEndian ? Shorts.ReverseBytes(n) : n; + } + + public static short ReadInt16LittleEndian(BinaryReader binaryReader) + { + short n = binaryReader.ReadInt16(); + return BitConverter.IsLittleEndian ? n : Shorts.ReverseBytes(n); + } + + public static int ReadInt32BigEndian(BinaryReader binaryReader) + { + int n = binaryReader.ReadInt32(); + return BitConverter.IsLittleEndian ? Integers.ReverseBytes(n) : n; + } + + public static int ReadInt32LittleEndian(BinaryReader binaryReader) + { + int n = binaryReader.ReadInt32(); + return BitConverter.IsLittleEndian ? n : Integers.ReverseBytes(n); + } + + public static long ReadInt64BigEndian(BinaryReader binaryReader) + { + long n = binaryReader.ReadInt64(); + return BitConverter.IsLittleEndian ? Longs.ReverseBytes(n) : n; + } + + public static long ReadInt64LittleEndian(BinaryReader binaryReader) + { + long n = binaryReader.ReadInt64(); + return BitConverter.IsLittleEndian ? n : Longs.ReverseBytes(n); + } + + [CLSCompliant(false)] + public static ushort ReadUInt16BigEndian(BinaryReader binaryReader) + { + ushort n = binaryReader.ReadUInt16(); + return BitConverter.IsLittleEndian ? Shorts.ReverseBytes(n) : n; + } + + [CLSCompliant(false)] + public static ushort ReadUInt16LittleEndian(BinaryReader binaryReader) + { + ushort n = binaryReader.ReadUInt16(); + return BitConverter.IsLittleEndian ? n : Shorts.ReverseBytes(n); + } + + [CLSCompliant(false)] + public static uint ReadUInt32BigEndian(BinaryReader binaryReader) + { + uint n = binaryReader.ReadUInt32(); + return BitConverter.IsLittleEndian ? Integers.ReverseBytes(n) : n; + } + + [CLSCompliant(false)] + public static uint ReadUInt32LittleEndian(BinaryReader binaryReader) + { + uint n = binaryReader.ReadUInt32(); + return BitConverter.IsLittleEndian ? n : Integers.ReverseBytes(n); + } + + [CLSCompliant(false)] + public static ulong ReadUInt64BigEndian(BinaryReader binaryReader) + { + ulong n = binaryReader.ReadUInt64(); + return BitConverter.IsLittleEndian ? Longs.ReverseBytes(n) : n; + } + + [CLSCompliant(false)] + public static ulong ReadUInt64LittleEndian(BinaryReader binaryReader) + { + ulong n = binaryReader.ReadUInt64(); + return BitConverter.IsLittleEndian ? n : Longs.ReverseBytes(n); + } + } +} diff --git a/crypto/src/util/io/BinaryWriters.cs b/crypto/src/util/io/BinaryWriters.cs new file mode 100644 index 000000000..6650dcda5 --- /dev/null +++ b/crypto/src/util/io/BinaryWriters.cs @@ -0,0 +1,86 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public static class BinaryWriters + { + public static void WriteInt16BigEndian(BinaryWriter binaryWriter, short n) + { + short bigEndian = BitConverter.IsLittleEndian ? Shorts.ReverseBytes(n) : n; + binaryWriter.Write(bigEndian); + } + + public static void WriteInt16LittleEndian(BinaryWriter binaryWriter, short n) + { + short littleEndian = BitConverter.IsLittleEndian ? n : Shorts.ReverseBytes(n); + binaryWriter.Write(littleEndian); + } + + public static void WriteInt32BigEndian(BinaryWriter binaryWriter, int n) + { + int bigEndian = BitConverter.IsLittleEndian ? Integers.ReverseBytes(n) : n; + binaryWriter.Write(bigEndian); + } + + public static void WriteInt32LittleEndian(BinaryWriter binaryWriter, int n) + { + int littleEndian = BitConverter.IsLittleEndian ? n : Integers.ReverseBytes(n); + binaryWriter.Write(littleEndian); + } + + public static void WriteInt64BigEndian(BinaryWriter binaryWriter, long n) + { + long bigEndian = BitConverter.IsLittleEndian ? Longs.ReverseBytes(n) : n; + binaryWriter.Write(bigEndian); + } + + public static void WriteInt64LittleEndian(BinaryWriter binaryWriter, long n) + { + long littleEndian = BitConverter.IsLittleEndian ? n : Longs.ReverseBytes(n); + binaryWriter.Write(littleEndian); + } + + [CLSCompliant(false)] + public static void WriteUInt16BigEndian(BinaryWriter binaryWriter, ushort n) + { + ushort bigEndian = BitConverter.IsLittleEndian ? Shorts.ReverseBytes(n) : n; + binaryWriter.Write(bigEndian); + } + + [CLSCompliant(false)] + public static void WriteUInt16LittleEndian(BinaryWriter binaryWriter, ushort n) + { + ushort littleEndian = BitConverter.IsLittleEndian ? n : Shorts.ReverseBytes(n); + binaryWriter.Write(littleEndian); + } + + [CLSCompliant(false)] + public static void WriteUInt32BigEndian(BinaryWriter binaryWriter, uint n) + { + uint bigEndian = BitConverter.IsLittleEndian ? Integers.ReverseBytes(n) : n; + binaryWriter.Write(bigEndian); + } + + [CLSCompliant(false)] + public static void WriteUInt32LittleEndian(BinaryWriter binaryWriter, uint n) + { + uint littleEndian = BitConverter.IsLittleEndian ? n : Integers.ReverseBytes(n); + binaryWriter.Write(littleEndian); + } + + [CLSCompliant(false)] + public static void WriteUInt64BigEndian(BinaryWriter binaryWriter, ulong n) + { + ulong bigEndian = BitConverter.IsLittleEndian ? Longs.ReverseBytes(n) : n; + binaryWriter.Write(bigEndian); + } + + [CLSCompliant(false)] + public static void WriteUInt64LittleEndian(BinaryWriter binaryWriter, ulong n) + { + ulong littleEndian = BitConverter.IsLittleEndian ? n : Longs.ReverseBytes(n); + binaryWriter.Write(littleEndian); + } + } +} diff --git a/crypto/src/util/io/Streams.cs b/crypto/src/util/io/Streams.cs index c23332909..da8f01068 100644 --- a/crypto/src/util/io/Streams.cs +++ b/crypto/src/util/io/Streams.cs @@ -3,14 +3,10 @@ using System.IO; namespace Org.BouncyCastle.Utilities.IO { - public sealed class Streams + public static class Streams { private const int BufferSize = 4096; - private Streams() - { - } - public static void Drain(Stream inStr) { inStr.CopyTo(Stream.Null, BufferSize); @@ -64,7 +60,12 @@ namespace Org.BouncyCastle.Utilities.IO return buf.ToArray(); } - public static byte[] ReadAllLimited(Stream inStr, int limit) + public static byte[] ReadAll(MemoryStream inStr) + { + return inStr.ToArray(); + } + + public static byte[] ReadAllLimited(Stream inStr, int limit) { MemoryStream buf = new MemoryStream(); PipeAllLimited(inStr, limit, buf); diff --git a/crypto/src/util/io/compression/Bzip2.cs b/crypto/src/util/io/compression/Bzip2.cs new file mode 100644 index 000000000..72b006dc9 --- /dev/null +++ b/crypto/src/util/io/compression/Bzip2.cs @@ -0,0 +1,21 @@ +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO.Compression +{ + using Impl = Utilities.Bzip2; + + internal static class Bzip2 + { + internal static Stream CompressOutput(Stream stream, bool leaveOpen = false) + { + return leaveOpen + ? new Impl.CBZip2OutputStreamLeaveOpen(stream) + : new Impl.CBZip2OutputStream(stream); + } + + internal static Stream DecompressInput(Stream stream) + { + return new Impl.CBZip2InputStream(stream); + } + } +} diff --git a/crypto/src/util/io/compression/ZLib.cs b/crypto/src/util/io/compression/ZLib.cs new file mode 100644 index 000000000..1254da012 --- /dev/null +++ b/crypto/src/util/io/compression/ZLib.cs @@ -0,0 +1,46 @@ +using System.IO; + +#if NET6_0_OR_GREATER +using System.IO.Compression; +#else +using Org.BouncyCastle.Utilities.Zlib; +#endif + +namespace Org.BouncyCastle.Utilities.IO.Compression +{ + internal static class ZLib + { + internal static Stream CompressOutput(Stream stream, int zlibCompressionLevel, bool leaveOpen = false) + { +#if NET6_0_OR_GREATER + return new ZLibStream(stream, GetCompressionLevel(zlibCompressionLevel), leaveOpen); +#else + return leaveOpen + ? new ZOutputStreamLeaveOpen(stream, zlibCompressionLevel, false) + : new ZOutputStream(stream, zlibCompressionLevel, false); +#endif + } + + internal static Stream DecompressInput(Stream stream) + { +#if NET6_0_OR_GREATER + return new ZLibStream(stream, CompressionMode.Decompress, leaveOpen: false); +#else + return new ZInputStream(stream); +#endif + } + +#if NET6_0_OR_GREATER + internal static CompressionLevel GetCompressionLevel(int zlibCompressionLevel) + { + return zlibCompressionLevel switch + { + 0 => CompressionLevel.NoCompression, + 1 or 2 or 3 => CompressionLevel.Fastest, + 7 or 8 or 9 => CompressionLevel.SmallestSize, + _ => CompressionLevel.Optimal, + }; + } +#endif + } +} diff --git a/crypto/src/util/io/compression/Zip.cs b/crypto/src/util/io/compression/Zip.cs new file mode 100644 index 000000000..f2773d63b --- /dev/null +++ b/crypto/src/util/io/compression/Zip.cs @@ -0,0 +1,33 @@ +using System.IO; + +#if NET6_0_OR_GREATER +using System.IO.Compression; +#else +using Org.BouncyCastle.Utilities.Zlib; +#endif + +namespace Org.BouncyCastle.Utilities.IO.Compression +{ + internal static class Zip + { + internal static Stream CompressOutput(Stream stream, int zlibCompressionLevel, bool leaveOpen = false) + { +#if NET6_0_OR_GREATER + return new DeflateStream(stream, ZLib.GetCompressionLevel(zlibCompressionLevel), leaveOpen); +#else + return leaveOpen + ? new ZOutputStreamLeaveOpen(stream, zlibCompressionLevel, true) + : new ZOutputStream(stream, zlibCompressionLevel, true); +#endif + } + + internal static Stream DecompressInput(Stream stream) + { +#if NET6_0_OR_GREATER + return new DeflateStream(stream, CompressionMode.Decompress, leaveOpen: false); +#else + return new ZInputStream(stream, true); +#endif + } + } +} diff --git a/crypto/src/util/zlib/ZOutputStream.cs b/crypto/src/util/zlib/ZOutputStream.cs index 301516e57..51a5050dd 100644 --- a/crypto/src/util/zlib/ZOutputStream.cs +++ b/crypto/src/util/zlib/ZOutputStream.cs @@ -264,4 +264,38 @@ namespace Org.BouncyCastle.Utilities.Zlib Write(buf1, 0, 1); } } + + public class ZOutputStreamLeaveOpen + : ZOutputStream + { + public ZOutputStreamLeaveOpen(Stream output) + : base(output) + { + } + + public ZOutputStreamLeaveOpen(Stream output, bool nowrap) + : base(output, nowrap) + { + } + + public ZOutputStreamLeaveOpen(Stream output, ZStream z) + : base(output, z) + { + } + + public ZOutputStreamLeaveOpen(Stream output, int level) + : base(output, level) + { + } + + public ZOutputStreamLeaveOpen(Stream output, int level, bool nowrap) + : base(output, level, nowrap) + { + } + + protected override void Dispose(bool disposing) + { + Detach(disposing); + } + } } diff --git a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs index 1cb239e87..3a0a02ea9 100644 --- a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs +++ b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs @@ -54,13 +54,13 @@ namespace Org.BouncyCastle.X509 public void SetNotBefore( DateTime date) { - acInfoGen.SetStartDate(new DerGeneralizedTime(date)); + acInfoGen.SetStartDate(new Asn1GeneralizedTime(date)); } public void SetNotAfter( DateTime date) { - acInfoGen.SetEndDate(new DerGeneralizedTime(date)); + acInfoGen.SetEndDate(new Asn1GeneralizedTime(date)); } /// <summary>Add an attribute.</summary> diff --git a/crypto/src/x509/X509V2CRLGenerator.cs b/crypto/src/x509/X509V2CRLGenerator.cs index dc3f8c662..a57383613 100644 --- a/crypto/src/x509/X509V2CRLGenerator.cs +++ b/crypto/src/x509/X509V2CRLGenerator.cs @@ -79,7 +79,8 @@ namespace Org.BouncyCastle.X509 int reason, DateTime invalidityDate) { - tbsGen.AddCrlEntry(new DerInteger(userCertificate), new Time(revocationDate), reason, new DerGeneralizedTime(invalidityDate)); + tbsGen.AddCrlEntry(new DerInteger(userCertificate), new Time(revocationDate), reason, + new Asn1GeneralizedTime(invalidityDate)); } /** |