diff options
author | Oren Novotny <oren@novotny.org> | 2019-08-22 08:01:33 -0400 |
---|---|---|
committer | Oren Novotny <oren@novotny.org> | 2019-08-22 08:01:33 -0400 |
commit | 92975859b63738a249cd6065b085eb16da197d26 (patch) | |
tree | 4e6b75594f9dbb3a3c5ab579f4d0fc67f72a537f /crypto | |
parent | single hit to true (diff) | |
parent | Fix circular dependence of statics (diff) | |
download | BouncyCastle.NET-ed25519-92975859b63738a249cd6065b085eb16da197d26.tar.xz |
merge master into netstandard
Diffstat (limited to 'crypto')
186 files changed, 4108 insertions, 1859 deletions
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index 1b4cccd52..ca6dba5ff 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -5949,6 +5949,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\math\ec\AbstractECLookupTable.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\ECAlgorithms.cs" SubType = "Code" BuildAction = "Compile" @@ -5984,11 +5989,21 @@ BuildAction = "Compile" /> <File + RelPath = "src\math\ec\ScaleXNegateYPointMap.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\ScaleXPointMap.cs" SubType = "Code" BuildAction = "Compile" /> <File + RelPath = "src\math\ec\ScaleYNegateXPointMap.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\ScaleYPointMap.cs" SubType = "Code" BuildAction = "Compile" @@ -6559,11 +6574,31 @@ BuildAction = "Compile" /> <File + RelPath = "src\math\ec\endo\EndoPreCompInfo.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\math\ec\endo\EndoUtilities.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\endo\GlvEndomorphism.cs" SubType = "Code" BuildAction = "Compile" /> <File + RelPath = "src\math\ec\endo\GlvTypeAEndomorphism.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\math\ec\endo\GlvTypeAParameters.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\endo\GlvTypeBEndomorphism.cs" SubType = "Code" BuildAction = "Compile" @@ -6574,6 +6609,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\math\ec\endo\ScalarSplitParameters.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\multiplier\AbstractECMultiplier.cs" SubType = "Code" BuildAction = "Compile" diff --git a/crypto/src/asn1/ASN1StreamParser.cs b/crypto/src/asn1/ASN1StreamParser.cs index 0c6b4413a..3eaaadaee 100644 --- a/crypto/src/asn1/ASN1StreamParser.cs +++ b/crypto/src/asn1/ASN1StreamParser.cs @@ -218,17 +218,19 @@ namespace Org.BouncyCastle.Asn1 } } - internal Asn1EncodableVector ReadVector() - { - Asn1EncodableVector v = new Asn1EncodableVector(); - - IAsn1Convertible obj; - while ((obj = ReadObject()) != null) - { - v.Add(obj.ToAsn1Object()); - } - - return v; - } + internal Asn1EncodableVector ReadVector() + { + IAsn1Convertible obj = ReadObject(); + if (null == obj) + return new Asn1EncodableVector(0); + + Asn1EncodableVector v = new Asn1EncodableVector(); + do + { + v.Add(obj.ToAsn1Object()); + } + while ((obj = ReadObject()) != null); + return v; + } } } diff --git a/crypto/src/asn1/Asn1Encodable.cs b/crypto/src/asn1/Asn1Encodable.cs index e3dd9a14c..12628082d 100644 --- a/crypto/src/asn1/Asn1Encodable.cs +++ b/crypto/src/asn1/Asn1Encodable.cs @@ -70,7 +70,7 @@ namespace Org.BouncyCastle.Asn1 Asn1Object o1 = ToAsn1Object(); Asn1Object o2 = other.ToAsn1Object(); - return o1 == o2 || o1.CallAsn1Equals(o2); + return o1 == o2 || (null != o2 && o1.CallAsn1Equals(o2)); } public abstract Asn1Object ToAsn1Object(); diff --git a/crypto/src/asn1/Asn1EncodableVector.cs b/crypto/src/asn1/Asn1EncodableVector.cs index 8a97e8b4f..987aa5298 100644 --- a/crypto/src/asn1/Asn1EncodableVector.cs +++ b/crypto/src/asn1/Asn1EncodableVector.cs @@ -1,101 +1,191 @@ using System; using System.Collections; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1 { + /** + * Mutable class for building ASN.1 constructed objects such as SETs or SEQUENCEs. + */ public class Asn1EncodableVector - : IEnumerable + : IEnumerable { - private IList v = Platform.CreateArrayList(); - - public static Asn1EncodableVector FromEnumerable( - IEnumerable e) - { - Asn1EncodableVector v = new Asn1EncodableVector(); - foreach (Asn1Encodable obj in e) - { - v.Add(obj); - } - return v; - } - -// public Asn1EncodableVector() -// { -// } - - public Asn1EncodableVector( - params Asn1Encodable[] v) - { - Add(v); - } - -// public void Add( -// Asn1Encodable obj) -// { -// v.Add(obj); -// } - - public void Add( - params Asn1Encodable[] objs) - { - foreach (Asn1Encodable obj in objs) - { - v.Add(obj); - } - } - - public void AddOptional( - params Asn1Encodable[] objs) - { - if (objs != null) - { - foreach (Asn1Encodable obj in objs) - { - if (obj != null) - { - v.Add(obj); - } - } - } - } + internal static readonly Asn1Encodable[] EmptyElements = new Asn1Encodable[0]; + + private const int DefaultCapacity = 10; + + private Asn1Encodable[] elements; + private int elementCount; + private bool copyOnWrite; + + public static Asn1EncodableVector FromEnumerable(IEnumerable e) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + foreach (Asn1Encodable obj in e) + { + v.Add(obj); + } + return v; + } + + public Asn1EncodableVector() + : this(DefaultCapacity) + { + } + + public Asn1EncodableVector(int initialCapacity) + { + if (initialCapacity < 0) + throw new ArgumentException("must not be negative", "initialCapacity"); + + this.elements = (initialCapacity == 0) ? EmptyElements : new Asn1Encodable[initialCapacity]; + this.elementCount = 0; + this.copyOnWrite = false; + } + + public Asn1EncodableVector(params Asn1Encodable[] v) + : this() + { + Add(v); + } + + public void Add(Asn1Encodable element) + { + if (null == element) + throw new ArgumentNullException("element"); + + int capacity = elements.Length; + int minCapacity = elementCount + 1; + if ((minCapacity > capacity) | copyOnWrite) + { + Reallocate(minCapacity); + } + + this.elements[elementCount] = element; + this.elementCount = minCapacity; + } + + public void Add(params Asn1Encodable[] objs) + { + foreach (Asn1Encodable obj in objs) + { + Add(obj); + } + } + + public void AddOptional(params Asn1Encodable[] objs) + { + if (objs != null) + { + foreach (Asn1Encodable obj in objs) + { + if (obj != null) + { + Add(obj); + } + } + } + } public void AddOptionalTagged(bool isExplicit, int tagNo, Asn1Encodable obj) { if (null != obj) { - v.Add(new DerTaggedObject(isExplicit, tagNo, obj)); + Add(new DerTaggedObject(isExplicit, tagNo, obj)); } } - public Asn1Encodable this[ - int index] - { - get { return (Asn1Encodable) v[index]; } - } + public void AddAll(Asn1EncodableVector other) + { + if (null == other) + throw new ArgumentNullException("other"); - [Obsolete("Use 'object[index]' syntax instead")] - public Asn1Encodable Get( - int index) + int otherElementCount = other.Count; + if (otherElementCount < 1) + return; + + int capacity = elements.Length; + int minCapacity = elementCount + otherElementCount; + if ((minCapacity > capacity) | copyOnWrite) + { + Reallocate(minCapacity); + } + + int i = 0; + do + { + Asn1Encodable otherElement = other[i]; + if (null == otherElement) + throw new NullReferenceException("'other' elements cannot be null"); + + this.elements[elementCount + i] = otherElement; + } + while (++i < otherElementCount); + + this.elementCount = minCapacity; + } + + public Asn1Encodable this[int index] { - return this[index]; + get + { + if (index >= elementCount) + throw new IndexOutOfRangeException(index + " >= " + elementCount); + + return elements[index]; + } } - [Obsolete("Use 'Count' property instead")] - public int Size - { - get { return v.Count; } - } + public int Count + { + get { return elementCount; } + } - public int Count - { - get { return v.Count; } - } + public IEnumerator GetEnumerator() + { + return CopyElements().GetEnumerator(); + } - public IEnumerator GetEnumerator() - { - return v.GetEnumerator(); - } - } + internal Asn1Encodable[] CopyElements() + { + if (0 == elementCount) + return EmptyElements; + + Asn1Encodable[] copy = new Asn1Encodable[elementCount]; + Array.Copy(elements, 0, copy, 0, elementCount); + return copy; + } + + internal Asn1Encodable[] TakeElements() + { + if (0 == elementCount) + return EmptyElements; + + if (elements.Length == elementCount) + { + this.copyOnWrite = true; + return elements; + } + + Asn1Encodable[] copy = new Asn1Encodable[elementCount]; + Array.Copy(elements, 0, copy, 0, elementCount); + return copy; + } + + private void Reallocate(int minCapacity) + { + int oldCapacity = elements.Length; + int newCapacity = System.Math.Max(oldCapacity, minCapacity + (minCapacity >> 1)); + + Asn1Encodable[] copy = new Asn1Encodable[newCapacity]; + Array.Copy(elements, 0, copy, 0, elementCount); + + this.elements = copy; + this.copyOnWrite = false; + } + + internal static Asn1Encodable[] CloneElements(Asn1Encodable[] elements) + { + return elements.Length < 1 ? EmptyElements : (Asn1Encodable[])elements.Clone(); + } + } } diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs index a94ae5235..0c7461c98 100644 --- a/crypto/src/asn1/Asn1InputStream.cs +++ b/crypto/src/asn1/Asn1InputStream.cs @@ -98,13 +98,13 @@ namespace Org.BouncyCastle.Asn1 // // yes, people actually do this... // - return new BerOctetString(BuildDerEncodableVector(defIn)); + return new BerOctetString(ReadVector(defIn)); case Asn1Tags.Sequence: return CreateDerSequence(defIn); case Asn1Tags.Set: return CreateDerSet(defIn); case Asn1Tags.External: - return new DerExternal(BuildDerEncodableVector(defIn)); + return new DerExternal(ReadVector(defIn)); default: throw new IOException("unknown tag " + tagNo + " encountered"); } @@ -113,12 +113,15 @@ namespace Org.BouncyCastle.Asn1 return CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers); } - internal Asn1EncodableVector BuildEncodableVector() + internal virtual Asn1EncodableVector ReadVector(DefiniteLengthInputStream dIn) { - Asn1EncodableVector v = new Asn1EncodableVector(); + if (dIn.Remaining < 1) + return new Asn1EncodableVector(0); + Asn1InputStream subStream = new Asn1InputStream(dIn); + Asn1EncodableVector v = new Asn1EncodableVector(); Asn1Object o; - while ((o = ReadObject()) != null) + while ((o = subStream.ReadObject()) != null) { v.Add(o); } @@ -126,22 +129,16 @@ namespace Org.BouncyCastle.Asn1 return v; } - internal virtual Asn1EncodableVector BuildDerEncodableVector( - DefiniteLengthInputStream dIn) - { - return new Asn1InputStream(dIn).BuildEncodableVector(); - } - internal virtual DerSequence CreateDerSequence( DefiniteLengthInputStream dIn) { - return DerSequence.FromVector(BuildDerEncodableVector(dIn)); + return DerSequence.FromVector(ReadVector(dIn)); } internal virtual DerSet CreateDerSet( DefiniteLengthInputStream dIn) { - return DerSet.FromVector(BuildDerEncodableVector(dIn), false); + return DerSet.FromVector(ReadVector(dIn), false); } public Asn1Object ReadObject() diff --git a/crypto/src/asn1/Asn1Sequence.cs b/crypto/src/asn1/Asn1Sequence.cs index 849f5e308..854c81590 100644 --- a/crypto/src/asn1/Asn1Sequence.cs +++ b/crypto/src/asn1/Asn1Sequence.cs @@ -10,7 +10,8 @@ namespace Org.BouncyCastle.Asn1 public abstract class Asn1Sequence : Asn1Object, IEnumerable { - private readonly IList seq; + // NOTE: Only non-readonly to support LazyDerSequence + internal Asn1Encodable[] elements; /** * return an Asn1Sequence from the given object. @@ -106,21 +107,38 @@ namespace Org.BouncyCastle.Asn1 throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } - protected internal Asn1Sequence( - int capacity) + protected internal Asn1Sequence() { - seq = Platform.CreateArrayList(capacity); + this.elements = Asn1EncodableVector.EmptyElements; } - public virtual IEnumerator GetEnumerator() + protected internal Asn1Sequence(Asn1Encodable element) + { + if (null == element) + throw new ArgumentNullException("element"); + + this.elements = new Asn1Encodable[]{ element }; + } + + protected internal Asn1Sequence(params Asn1Encodable[] elements) { - return seq.GetEnumerator(); + if (Arrays.IsNullOrContainsNull(elements)) + throw new NullReferenceException("'elements' cannot be null, or contain null"); + + this.elements = Asn1EncodableVector.CloneElements(elements); } - [Obsolete("Use GetEnumerator() instead")] - public IEnumerator GetObjects() + protected internal Asn1Sequence(Asn1EncodableVector elementVector) { - return GetEnumerator(); + if (null == elementVector) + throw new ArgumentNullException("elementVector"); + + this.elements = elementVector.TakeElements(); + } + + public virtual IEnumerator GetEnumerator() + { + return elements.GetEnumerator(); } private class Asn1SequenceParserImpl @@ -176,93 +194,59 @@ namespace Org.BouncyCastle.Asn1 */ public virtual Asn1Encodable this[int index] { - get { return (Asn1Encodable) seq[index]; } + get { return elements[index]; } } - [Obsolete("Use 'object[index]' syntax instead")] - public Asn1Encodable GetObjectAt( - int index) - { - return this[index]; - } - - [Obsolete("Use 'Count' property instead")] - public int Size + public virtual int Count { - get { return Count; } + get { return elements.Length; } } - public virtual int Count + public virtual Asn1Encodable[] ToArray() { - get { return seq.Count; } + return Asn1EncodableVector.CloneElements(elements); } protected override int Asn1GetHashCode() { - int hc = Count; + //return Arrays.GetHashCode(elements); + int i = elements.Length; + int hc = i + 1; - foreach (object o in this) + while (--i >= 0) { - hc *= 17; - if (o == null) - { - hc ^= DerNull.Instance.GetHashCode(); - } - else - { - hc ^= o.GetHashCode(); - } + hc *= 257; + hc ^= elements[i].ToAsn1Object().CallAsn1GetHashCode(); } return hc; } - protected override bool Asn1Equals( - Asn1Object asn1Object) + protected override bool Asn1Equals(Asn1Object asn1Object) { - Asn1Sequence other = asn1Object as Asn1Sequence; - - if (other == null) + Asn1Sequence that = asn1Object as Asn1Sequence; + if (null == that) return false; - if (Count != other.Count) + int count = this.Count; + if (that.Count != count) return false; - IEnumerator s1 = GetEnumerator(); - IEnumerator s2 = other.GetEnumerator(); - - while (s1.MoveNext() && s2.MoveNext()) + for (int i = 0; i < count; ++i) { - Asn1Object o1 = GetCurrent(s1).ToAsn1Object(); - Asn1Object o2 = GetCurrent(s2).ToAsn1Object(); + Asn1Object o1 = this.elements[i].ToAsn1Object(); + Asn1Object o2 = that.elements[i].ToAsn1Object(); - if (!o1.Equals(o2)) + if (o1 != o2 && !o1.CallAsn1Equals(o2)) return false; } return true; } - private Asn1Encodable GetCurrent(IEnumerator e) - { - Asn1Encodable encObj = (Asn1Encodable)e.Current; - - // unfortunately null was allowed as a substitute for DER null - if (encObj == null) - return DerNull.Instance; - - return encObj; - } - - protected internal void AddObject( - Asn1Encodable obj) - { - seq.Add(obj); - } - public override string ToString() { - return CollectionUtilities.ToString(seq); + return CollectionUtilities.ToString(elements); } } } diff --git a/crypto/src/asn1/Asn1Set.cs b/crypto/src/asn1/Asn1Set.cs index 7fa072c0d..68ede2275 100644 --- a/crypto/src/asn1/Asn1Set.cs +++ b/crypto/src/asn1/Asn1Set.cs @@ -16,7 +16,8 @@ namespace Org.BouncyCastle.Asn1 abstract public class Asn1Set : Asn1Object, IEnumerable { - private readonly IList _set; + // NOTE: Only non-readonly to support LazyDerSet + internal Asn1Encodable[] elements; /** * return an ASN1Set from the given object. @@ -125,21 +126,38 @@ namespace Org.BouncyCastle.Asn1 throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } - protected internal Asn1Set( - int capacity) + protected internal Asn1Set() { - _set = Platform.CreateArrayList(capacity); + this.elements = Asn1EncodableVector.EmptyElements; } - public virtual IEnumerator GetEnumerator() + protected internal Asn1Set(Asn1Encodable element) + { + if (null == element) + throw new ArgumentNullException("element"); + + this.elements = new Asn1Encodable[]{ element }; + } + + protected internal Asn1Set(params Asn1Encodable[] elements) { - return _set.GetEnumerator(); + if (Arrays.IsNullOrContainsNull(elements)) + throw new NullReferenceException("'elements' cannot be null, or contain null"); + + this.elements = Asn1EncodableVector.CloneElements(elements); } - [Obsolete("Use GetEnumerator() instead")] - public IEnumerator GetObjects() + protected internal Asn1Set(Asn1EncodableVector elementVector) + { + if (null == elementVector) + throw new ArgumentNullException("elementVector"); + + this.elements = elementVector.TakeElements(); + } + + public virtual IEnumerator GetEnumerator() { - return GetEnumerator(); + return elements.GetEnumerator(); } /** @@ -150,35 +168,17 @@ namespace Org.BouncyCastle.Asn1 */ public virtual Asn1Encodable this[int index] { - get { return (Asn1Encodable) _set[index]; } - } - - [Obsolete("Use 'object[index]' syntax instead")] - public Asn1Encodable GetObjectAt( - int index) - { - return this[index]; - } - - [Obsolete("Use 'Count' property instead")] - public int Size - { - get { return Count; } + get { return elements[index]; } } public virtual int Count { - get { return _set.Count; } + get { return elements.Length; } } public virtual Asn1Encodable[] ToArray() { - Asn1Encodable[] values = new Asn1Encodable[this.Count]; - for (int i = 0; i < this.Count; ++i) - { - values[i] = this[i]; - } - return values; + return Asn1EncodableVector.CloneElements(elements); } private class Asn1SetParserImpl @@ -227,107 +227,67 @@ namespace Org.BouncyCastle.Asn1 protected override int Asn1GetHashCode() { - int hc = Count; + //return Arrays.GetHashCode(elements); + int i = elements.Length; + int hc = i + 1; - foreach (object o in this) + while (--i >= 0) { - hc *= 17; - if (o == null) - { - hc ^= DerNull.Instance.GetHashCode(); - } - else - { - hc ^= o.GetHashCode(); - } + hc *= 257; + hc ^= elements[i].ToAsn1Object().CallAsn1GetHashCode(); } return hc; } - protected override bool Asn1Equals( - Asn1Object asn1Object) + protected override bool Asn1Equals(Asn1Object asn1Object) { - Asn1Set other = asn1Object as Asn1Set; - - if (other == null) + Asn1Set that = asn1Object as Asn1Set; + if (null == that) return false; - if (Count != other.Count) - { + int count = this.Count; + if (that.Count != count) return false; - } - - IEnumerator s1 = GetEnumerator(); - IEnumerator s2 = other.GetEnumerator(); - while (s1.MoveNext() && s2.MoveNext()) + for (int i = 0; i < count; ++i) { - Asn1Object o1 = GetCurrent(s1).ToAsn1Object(); - Asn1Object o2 = GetCurrent(s2).ToAsn1Object(); + Asn1Object o1 = this.elements[i].ToAsn1Object(); + Asn1Object o2 = that.elements[i].ToAsn1Object(); - if (!o1.Equals(o2)) + if (o1 != o2 && !o1.CallAsn1Equals(o2)) return false; } return true; } - private Asn1Encodable GetCurrent(IEnumerator e) - { - Asn1Encodable encObj = (Asn1Encodable)e.Current; - - // unfortunately null was allowed as a substitute for DER null - if (encObj == null) - return DerNull.Instance; - - return encObj; - } - protected internal void Sort() { - if (_set.Count < 2) + if (elements.Length < 2) return; #if PORTABLE - var sorted = _set.Cast<Asn1Encodable>() - .Select(a => new { Item = a, Key = a.GetEncoded(Asn1Encodable.Der) }) - .OrderBy(t => t.Key, new DerComparer()) - .Select(t => t.Item) - .ToList(); - - for (int i = 0; i < _set.Count; ++i) - { - _set[i] = sorted[i]; - } + this.elements = elements + .Cast<Asn1Encodable>() + .Select(a => new { Item = a, Key = a.GetEncoded(Asn1Encodable.Der) }) + .OrderBy(t => t.Key, new DerComparer()) + .Select(t => t.Item) + .ToArray(); #else - Asn1Encodable[] items = new Asn1Encodable[_set.Count]; - byte[][] keys = new byte[_set.Count][]; - - for (int i = 0; i < _set.Count; ++i) - { - Asn1Encodable item = (Asn1Encodable)_set[i]; - items[i] = item; - keys[i] = item.GetEncoded(Asn1Encodable.Der); - } - - Array.Sort(keys, items, new DerComparer()); - - for (int i = 0; i < _set.Count; ++i) + int count = elements.Length; + byte[][] keys = new byte[count][]; + for (int i = 0; i < count; ++i) { - _set[i] = items[i]; + keys[i] = elements[i].GetEncoded(Asn1Encodable.Der); } + Array.Sort(keys, elements, new DerComparer()); #endif } - protected internal void AddObject(Asn1Encodable obj) - { - _set.Add(obj); - } - public override string ToString() { - return CollectionUtilities.ToString(_set); + return CollectionUtilities.ToString(elements); } #if PORTABLE diff --git a/crypto/src/asn1/Asn1TaggedObject.cs b/crypto/src/asn1/Asn1TaggedObject.cs index a6d4b2c28..14b1bc65f 100644 --- a/crypto/src/asn1/Asn1TaggedObject.cs +++ b/crypto/src/asn1/Asn1TaggedObject.cs @@ -33,7 +33,7 @@ namespace Org.BouncyCastle.Asn1 { if (explicitly) { - return (Asn1TaggedObject) obj.GetObject(); + return GetInstance(obj.GetObject()); } throw new ArgumentException("implicitly tagged tagged object"); diff --git a/crypto/src/asn1/BerSequence.cs b/crypto/src/asn1/BerSequence.cs index 70b43fc79..55c93a72e 100644 --- a/crypto/src/asn1/BerSequence.cs +++ b/crypto/src/asn1/BerSequence.cs @@ -5,47 +5,41 @@ namespace Org.BouncyCastle.Asn1 { public static new readonly BerSequence Empty = new BerSequence(); - public static new BerSequence FromVector( - Asn1EncodableVector v) + public static new BerSequence FromVector(Asn1EncodableVector elementVector) { - return v.Count < 1 ? Empty : new BerSequence(v); + return elementVector.Count < 1 ? Empty : new BerSequence(elementVector); } /** * create an empty sequence */ public BerSequence() + : base() { } /** * create a sequence containing one object */ - public BerSequence( - Asn1Encodable obj) - : base(obj) + public BerSequence(Asn1Encodable element) + : base(element) { } - public BerSequence( - params Asn1Encodable[] v) - : base(v) + public BerSequence(params Asn1Encodable[] elements) + : base(elements) { } /** * create a sequence containing a vector of objects. */ - public BerSequence( - Asn1EncodableVector v) - : base(v) + public BerSequence(Asn1EncodableVector elementVector) + : base(elementVector) { } - /* - */ - internal override void Encode( - DerOutputStream derOut) + internal override void Encode(DerOutputStream derOut) { if (derOut is Asn1OutputStream || derOut is BerOutputStream) { diff --git a/crypto/src/asn1/BerSet.cs b/crypto/src/asn1/BerSet.cs index a181e172d..6209e71a8 100644 --- a/crypto/src/asn1/BerSet.cs +++ b/crypto/src/asn1/BerSet.cs @@ -5,48 +5,46 @@ namespace Org.BouncyCastle.Asn1 { public static new readonly BerSet Empty = new BerSet(); - public static new BerSet FromVector( - Asn1EncodableVector v) + public static new BerSet FromVector(Asn1EncodableVector elementVector) { - return v.Count < 1 ? Empty : new BerSet(v); + return elementVector.Count < 1 ? Empty : new BerSet(elementVector); } - internal static new BerSet FromVector( - Asn1EncodableVector v, - bool needsSorting) + internal static new BerSet FromVector(Asn1EncodableVector elementVector, bool needsSorting) { - return v.Count < 1 ? Empty : new BerSet(v, needsSorting); + return elementVector.Count < 1 ? Empty : new BerSet(elementVector, needsSorting); } /** * create an empty sequence */ public BerSet() + : base() { } /** * create a set containing one object */ - public BerSet(Asn1Encodable obj) : base(obj) + public BerSet(Asn1Encodable element) + : base(element) { } /** * create a set containing a vector of objects. */ - public BerSet(Asn1EncodableVector v) : base(v, false) + public BerSet(Asn1EncodableVector elementVector) + : base(elementVector, false) { } - internal BerSet(Asn1EncodableVector v, bool needsSorting) : base(v, needsSorting) + internal BerSet(Asn1EncodableVector elementVector, bool needsSorting) + : base(elementVector, needsSorting) { } - /* - */ - internal override void Encode( - DerOutputStream derOut) + internal override void Encode(DerOutputStream derOut) { if (derOut is Asn1OutputStream || derOut is BerOutputStream) { diff --git a/crypto/src/asn1/DerEnumerated.cs b/crypto/src/asn1/DerEnumerated.cs index 6690feceb..8654a3bfd 100644 --- a/crypto/src/asn1/DerEnumerated.cs +++ b/crypto/src/asn1/DerEnumerated.cs @@ -9,6 +9,7 @@ namespace Org.BouncyCastle.Asn1 : Asn1Object { private readonly byte[] bytes; + private readonly int start; /** * return an integer from the passed in object @@ -49,32 +50,42 @@ namespace Org.BouncyCastle.Asn1 return FromOctetString(((Asn1OctetString)o).GetOctets()); } - public DerEnumerated( - int val) + public DerEnumerated(int val) { - bytes = BigInteger.ValueOf(val).ToByteArray(); + if (val < 0) + throw new ArgumentException("enumerated must be non-negative", "val"); + + this.bytes = BigInteger.ValueOf(val).ToByteArray(); + this.start = 0; } - public DerEnumerated( - BigInteger val) + public DerEnumerated(long val) { - bytes = val.ToByteArray(); + if (val < 0L) + throw new ArgumentException("enumerated must be non-negative", "val"); + + this.bytes = BigInteger.ValueOf(val).ToByteArray(); + this.start = 0; } - public DerEnumerated( - byte[] bytes) + public DerEnumerated(BigInteger val) { - if (bytes.Length > 1) - { - if ((bytes[0] == 0 && (bytes[1] & 0x80) == 0) - || (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0)) - { - if (!DerInteger.AllowUnsafe()) - throw new ArgumentException("malformed enumerated"); - } - } + if (val.SignValue < 0) + throw new ArgumentException("enumerated must be non-negative", "val"); + + this.bytes = val.ToByteArray(); + this.start = 0; + } + + public DerEnumerated(byte[] bytes) + { + if (DerInteger.IsMalformed(bytes)) + throw new ArgumentException("malformed enumerated", "bytes"); + if (0 != (bytes[0] & 0x80)) + throw new ArgumentException("enumerated must be non-negative", "bytes"); this.bytes = Arrays.Clone(bytes); + this.start = DerInteger.SignBytesToSkip(bytes); } public BigInteger Value @@ -82,17 +93,34 @@ namespace Org.BouncyCastle.Asn1 get { return new BigInteger(bytes); } } - internal override void Encode( - DerOutputStream derOut) + public bool HasValue(BigInteger x) + { + return null != x + // Fast check to avoid allocation + && DerInteger.IntValue(bytes, start, DerInteger.SignExtSigned) == x.IntValue + && Value.Equals(x); + } + + public int IntValueExact + { + get + { + int count = bytes.Length - start; + if (count > 4) + throw new ArithmeticException("ASN.1 Enumerated out of int range"); + + return DerInteger.IntValue(bytes, start, DerInteger.SignExtSigned); + } + } + + internal override void Encode(DerOutputStream derOut) { derOut.WriteEncoded(Asn1Tags.Enumerated, bytes); } - protected override bool Asn1Equals( - Asn1Object asn1Object) + protected override bool Asn1Equals(Asn1Object asn1Object) { DerEnumerated other = asn1Object as DerEnumerated; - if (other == null) return false; @@ -108,27 +136,21 @@ namespace Org.BouncyCastle.Asn1 internal static DerEnumerated FromOctetString(byte[] enc) { + if (enc.Length > 1) + return new DerEnumerated(enc); if (enc.Length == 0) - { throw new ArgumentException("ENUMERATED has zero length", "enc"); - } - if (enc.Length == 1) + int value = enc[0]; + if (value >= cache.Length) + return new DerEnumerated(enc); + + DerEnumerated possibleMatch = cache[value]; + if (possibleMatch == null) { - int value = enc[0]; - if (value < cache.Length) - { - DerEnumerated cached = cache[value]; - if (cached != null) - { - return cached; - } - - return cache[value] = new DerEnumerated(Arrays.Clone(enc)); - } + cache[value] = possibleMatch = new DerEnumerated(enc); } - - return new DerEnumerated(Arrays.Clone(enc)); + return possibleMatch; } } } diff --git a/crypto/src/asn1/DerInteger.cs b/crypto/src/asn1/DerInteger.cs index ae14d2a9f..3e19a07b6 100644 --- a/crypto/src/asn1/DerInteger.cs +++ b/crypto/src/asn1/DerInteger.cs @@ -16,7 +16,11 @@ namespace Org.BouncyCastle.Asn1 return allowUnsafeValue != null && Platform.EqualsIgnoreCase("true", allowUnsafeValue); } + internal const int SignExtSigned = -1; + internal const int SignExtUnsigned = 0xFF; + private readonly byte[] bytes; + private readonly int start; /** * return an integer from the passed in object @@ -60,42 +64,42 @@ namespace Org.BouncyCastle.Asn1 return new DerInteger(Asn1OctetString.GetInstance(o).GetOctets()); } - public DerInteger( - int value) + public DerInteger(int value) + { + this.bytes = BigInteger.ValueOf(value).ToByteArray(); + this.start = 0; + } + + public DerInteger(long value) { - bytes = BigInteger.ValueOf(value).ToByteArray(); + this.bytes = BigInteger.ValueOf(value).ToByteArray(); + this.start = 0; } - public DerInteger( - BigInteger value) + public DerInteger(BigInteger value) { if (value == null) throw new ArgumentNullException("value"); - bytes = value.ToByteArray(); + this.bytes = value.ToByteArray(); + this.start = 0; } - public DerInteger( - byte[] bytes) + public DerInteger(byte[] bytes) + : this(bytes, true) { - if (bytes.Length > 1) - { - if ((bytes[0] == 0 && (bytes[1] & 0x80) == 0) - || (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0)) - { - if (!AllowUnsafe()) - throw new ArgumentException("malformed integer"); - } - } - this.bytes = Arrays.Clone(bytes); } - public BigInteger Value + internal DerInteger(byte[] bytes, bool clone) { - get { return new BigInteger(bytes); } + if (IsMalformed(bytes)) + throw new ArgumentException("malformed integer", "bytes"); + + this.bytes = clone ? Arrays.Clone(bytes) : bytes; + this.start = SignBytesToSkip(bytes); } - /** + /** * in some cases positive values Get crammed into a space, * that's not quite big enough... */ @@ -104,8 +108,44 @@ namespace Org.BouncyCastle.Asn1 get { return new BigInteger(1, bytes); } } - internal override void Encode( - DerOutputStream derOut) + public BigInteger Value + { + get { return new BigInteger(bytes); } + } + + public bool HasValue(BigInteger x) + { + return null != x + // Fast check to avoid allocation + && IntValue(bytes, start, SignExtSigned) == x.IntValue + && Value.Equals(x); + } + + public int IntPositiveValueExact + { + get + { + int count = bytes.Length - start; + if (count > 4 || (count == 4 && 0 != (bytes[start] & 0x80))) + throw new ArithmeticException("ASN.1 Integer out of positive int range"); + + return IntValue(bytes, start, SignExtUnsigned); + } + } + + public int IntValueExact + { + get + { + int count = bytes.Length - start; + if (count > 4) + throw new ArithmeticException("ASN.1 Integer out of int range"); + + return IntValue(bytes, start, SignExtSigned); + } + } + + internal override void Encode(DerOutputStream derOut) { derOut.WriteEncoded(Asn1Tags.Integer, bytes); } @@ -115,20 +155,61 @@ namespace Org.BouncyCastle.Asn1 return Arrays.GetHashCode(bytes); } - protected override bool Asn1Equals( - Asn1Object asn1Object) + protected override bool Asn1Equals(Asn1Object asn1Object) { DerInteger other = asn1Object as DerInteger; - if (other == null) return false; - return Arrays.AreEqual(this.bytes, other.bytes); + return Arrays.AreEqual(this.bytes, other.bytes); } public override string ToString() { return Value.ToString(); } - } + + internal static int IntValue(byte[] bytes, int start, int signExt) + { + int length = bytes.Length; + int pos = System.Math.Max(start, length - 4); + + int val = (sbyte)bytes[pos] & signExt; + while (++pos < length) + { + val = (val << 8) | bytes[pos]; + } + return val; + } + + /** + * Apply the correct validation for an INTEGER primitive following the BER rules. + * + * @param bytes The raw encoding of the integer. + * @return true if the (in)put fails this validation. + */ + internal static bool IsMalformed(byte[] bytes) + { + switch (bytes.Length) + { + case 0: + return true; + case 1: + return false; + default: + return (sbyte)bytes[0] == ((sbyte)bytes[1] >> 7) && !AllowUnsafe(); + } + } + + internal static int SignBytesToSkip(byte[] bytes) + { + int pos = 0, last = bytes.Length - 1; + while (pos < last + && (sbyte)bytes[pos] == ((sbyte)bytes[pos + 1] >> 7)) + { + ++pos; + } + return pos; + } + } } diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs index 1c8032f45..fb38d5f05 100644 --- a/crypto/src/asn1/DerObjectIdentifier.cs +++ b/crypto/src/asn1/DerObjectIdentifier.cs @@ -210,36 +210,36 @@ namespace Org.BouncyCastle.Asn1 return identifier; } - private static bool IsValidBranchID( - string branchID, int start) + private static bool IsValidBranchID(string branchID, int start) { - bool periodAllowed = false; + int digitCount = 0; int pos = branchID.Length; while (--pos >= start) { char ch = branchID[pos]; - // TODO Leading zeroes? - if ('0' <= ch && ch <= '9') - { - periodAllowed = true; - continue; - } - if (ch == '.') { - if (!periodAllowed) + if (0 == digitCount || (digitCount > 1 && branchID[pos + 1] == '0')) return false; - periodAllowed = false; - continue; + digitCount = 0; + } + else if ('0' <= ch && ch <= '9') + { + ++digitCount; } + else + { + return false; + } + } + if (0 == digitCount || (digitCount > 1 && branchID[pos + 1] == '0')) return false; - } - return periodAllowed; + return true; } private static bool IsValidIdentifier(string identifier) diff --git a/crypto/src/asn1/DerSequence.cs b/crypto/src/asn1/DerSequence.cs index a76cf2882..823fa869b 100644 --- a/crypto/src/asn1/DerSequence.cs +++ b/crypto/src/asn1/DerSequence.cs @@ -11,51 +11,38 @@ namespace Org.BouncyCastle.Asn1 { public static readonly DerSequence Empty = new DerSequence(); - public static DerSequence FromVector( - Asn1EncodableVector v) + public static DerSequence FromVector(Asn1EncodableVector elementVector) { - return v.Count < 1 ? Empty : new DerSequence(v); + return elementVector.Count < 1 ? Empty : new DerSequence(elementVector); } /** * create an empty sequence */ public DerSequence() - : base(0) + : base() { } /** * create a sequence containing one object */ - public DerSequence( - Asn1Encodable obj) - : base(1) + public DerSequence(Asn1Encodable element) + : base(element) { - AddObject(obj); } - public DerSequence( - params Asn1Encodable[] v) - : base(v.Length) + public DerSequence(params Asn1Encodable[] elements) + : base(elements) { - foreach (Asn1Encodable ae in v) - { - AddObject(ae); - } } /** * create a sequence containing a vector of objects. */ - public DerSequence( - Asn1EncodableVector v) - : base(v.Count) + public DerSequence(Asn1EncodableVector elementVector) + : base(elementVector) { - foreach (Asn1Encodable ae in v) - { - AddObject(ae); - } } /* @@ -66,8 +53,7 @@ namespace Org.BouncyCastle.Asn1 * ASN.1 descriptions given. Rather than just outputing Sequence, * we also have to specify Constructed, and the objects length. */ - internal override void Encode( - DerOutputStream derOut) + internal override void Encode(DerOutputStream derOut) { // TODO Intermediate buffer could be avoided if we could calculate expected length MemoryStream bOut = new MemoryStream(); diff --git a/crypto/src/asn1/DerSet.cs b/crypto/src/asn1/DerSet.cs index 3df1a6766..d4c242778 100644 --- a/crypto/src/asn1/DerSet.cs +++ b/crypto/src/asn1/DerSet.cs @@ -13,68 +13,49 @@ namespace Org.BouncyCastle.Asn1 { public static readonly DerSet Empty = new DerSet(); - public static DerSet FromVector( - Asn1EncodableVector v) + public static DerSet FromVector(Asn1EncodableVector elementVector) { - return v.Count < 1 ? Empty : new DerSet(v); + return elementVector.Count < 1 ? Empty : new DerSet(elementVector); } - internal static DerSet FromVector( - Asn1EncodableVector v, - bool needsSorting) + internal static DerSet FromVector(Asn1EncodableVector elementVector, bool needsSorting) { - return v.Count < 1 ? Empty : new DerSet(v, needsSorting); + return elementVector.Count < 1 ? Empty : new DerSet(elementVector, needsSorting); } /** * create an empty set */ public DerSet() - : base(0) + : base() { } /** * @param obj - a single object that makes up the set. */ - public DerSet( - Asn1Encodable obj) - : base(1) + public DerSet(Asn1Encodable element) + : base(element) { - AddObject(obj); } - public DerSet( - params Asn1Encodable[] v) - : base(v.Length) + public DerSet(params Asn1Encodable[] elements) + : base(elements) { - foreach (Asn1Encodable o in v) - { - AddObject(o); - } - Sort(); } /** * @param v - a vector of objects making up the set. */ - public DerSet( - Asn1EncodableVector v) - : this(v, true) + public DerSet(Asn1EncodableVector elementVector) + : this(elementVector, true) { } - internal DerSet( - Asn1EncodableVector v, - bool needsSorting) - : base(v.Count) + internal DerSet(Asn1EncodableVector elementVector, bool needsSorting) + : base(elementVector) { - foreach (Asn1Encodable o in v) - { - AddObject(o); - } - if (needsSorting) { Sort(); @@ -89,8 +70,7 @@ namespace Org.BouncyCastle.Asn1 * ASN.1 descriptions given. Rather than just outputing Set, * we also have to specify Constructed, and the objects length. */ - internal override void Encode( - DerOutputStream derOut) + internal override void Encode(DerOutputStream derOut) { // TODO Intermediate buffer could be avoided if we could calculate expected length MemoryStream bOut = new MemoryStream(); diff --git a/crypto/src/asn1/LazyDERSequence.cs b/crypto/src/asn1/LazyDERSequence.cs index 7301bc158..8fa7a0792 100644 --- a/crypto/src/asn1/LazyDERSequence.cs +++ b/crypto/src/asn1/LazyDERSequence.cs @@ -19,18 +19,20 @@ namespace Org.BouncyCastle.Asn1 { lock (this) { - if (encoded != null) - { - Asn1InputStream e = new LazyAsn1InputStream(encoded); + if (null != encoded) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + Asn1InputStream e = new LazyAsn1InputStream(encoded); - Asn1Object o; - while ((o = e.ReadObject()) != null) - { - AddObject(o); - } + Asn1Object o; + while ((o = e.ReadObject()) != null) + { + v.Add(o); + } - encoded = null; - } + this.elements = v.TakeElements(); + this.encoded = null; + } } } diff --git a/crypto/src/asn1/LazyDERSet.cs b/crypto/src/asn1/LazyDERSet.cs index e6c9319dd..eac64cbbe 100644 --- a/crypto/src/asn1/LazyDERSet.cs +++ b/crypto/src/asn1/LazyDERSet.cs @@ -21,16 +21,18 @@ namespace Org.BouncyCastle.Asn1 { if (encoded != null) { - Asn1InputStream e = new LazyAsn1InputStream(encoded); + Asn1EncodableVector v = new Asn1EncodableVector(); + Asn1InputStream e = new LazyAsn1InputStream(encoded); Asn1Object o; while ((o = e.ReadObject()) != null) { - AddObject(o); + v.Add(o); } - encoded = null; - } + this.elements = v.TakeElements(); + this.encoded = null; + } } } diff --git a/crypto/src/asn1/anssi/ANSSINamedCurves.cs b/crypto/src/asn1/anssi/ANSSINamedCurves.cs index d0c90ebf1..ce941709f 100644 --- a/crypto/src/asn1/anssi/ANSSINamedCurves.cs +++ b/crypto/src/asn1/anssi/ANSSINamedCurves.cs @@ -4,6 +4,7 @@ using System.Collections; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Encoders; @@ -12,6 +13,13 @@ namespace Org.BouncyCastle.Asn1.Anssi { public class AnssiNamedCurves { + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.Decode(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + private static ECCurve ConfigureCurve(ECCurve curve) { return curve; @@ -42,9 +50,8 @@ namespace Org.BouncyCastle.Asn1.Anssi BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "B6B3D4C356C139EB31183D4749D423958C27D2DCAF98B70164C97A2DD98F5CFF" - + "6142E0F7C8B204911F9271F0F3ECEF8C2701C307E8E4C9E183115A1554062CFB")); + X9ECPoint G = ConfigureBasepoint(curve, + "04B6B3D4C356C139EB31183D4749D423958C27D2DCAF98B70164C97A2DD98F5CFF6142E0F7C8B204911F9271F0F3ECEF8C2701C307E8E4C9E183115A1554062CFB"); return new X9ECParameters(curve, G, n, h, S); } diff --git a/crypto/src/asn1/cms/EnvelopedData.cs b/crypto/src/asn1/cms/EnvelopedData.cs index 41dae548f..fbde00b28 100644 --- a/crypto/src/asn1/cms/EnvelopedData.cs +++ b/crypto/src/asn1/cms/EnvelopedData.cs @@ -154,7 +154,7 @@ namespace Org.BouncyCastle.Asn1.Cms { RecipientInfo ri = RecipientInfo.GetInstance(o); - if (ri.Version.Value.IntValue != 0) + if (ri.Version.IntValueExact != 0) { return 2; } diff --git a/crypto/src/asn1/cms/Evidence.cs b/crypto/src/asn1/cms/Evidence.cs index 8374aed55..b12f090a9 100644 --- a/crypto/src/asn1/cms/Evidence.cs +++ b/crypto/src/asn1/cms/Evidence.cs @@ -8,6 +8,7 @@ namespace Org.BouncyCastle.Asn1.Cms : Asn1Encodable, IAsn1Choice { private TimeStampTokenEvidence tstEvidence; + private Asn1Sequence otherEvidence; public Evidence(TimeStampTokenEvidence tstEvidence) { @@ -16,11 +17,23 @@ namespace Org.BouncyCastle.Asn1.Cms private Evidence(Asn1TaggedObject tagged) { - if (tagged.TagNo == 0) - { - this.tstEvidence = TimeStampTokenEvidence.GetInstance(tagged, false); - } - } + if (tagged.TagNo == 0) + { + this.tstEvidence = TimeStampTokenEvidence.GetInstance(tagged, false); + } + //else if (tagged.TagNo == 1) + //{ + // this.ersEvidence = EvidenceRecord.GetInstance(tagged, false); + //} + else if (tagged.TagNo == 2) + { + this.otherEvidence = Asn1Sequence.GetInstance(tagged, false); + } + else + { + throw new ArgumentException("unknown tag in Evidence", "tagged"); + } + } public static Evidence GetInstance(object obj) { @@ -33,17 +46,28 @@ namespace Org.BouncyCastle.Asn1.Cms throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } + public static Evidence GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(obj.GetObject()); // must be explicitly tagged + } + public virtual TimeStampTokenEvidence TstEvidence { get { return tstEvidence; } } + //public EvidenceRecord ErsEvidence + //{ + // get { return ersEvidence; } + //} + public override Asn1Object ToAsn1Object() { if (tstEvidence != null) return new DerTaggedObject(false, 0, tstEvidence); - - return null; + //if (ersEvidence != null) + // return new DerTaggedObject(false, 1, ersEvidence); + return new DerTaggedObject(false, 2, otherEvidence); } } } diff --git a/crypto/src/asn1/cms/SignedData.cs b/crypto/src/asn1/cms/SignedData.cs index 957b81cd8..dfc1e2829 100644 --- a/crypto/src/asn1/cms/SignedData.cs +++ b/crypto/src/asn1/cms/SignedData.cs @@ -150,7 +150,7 @@ namespace Org.BouncyCastle.Asn1.Cms { SignerInfo s = SignerInfo.GetInstance(obj); - if (s.Version.Value.IntValue == 3) + if (s.Version.IntValueExact == 3) { return true; } diff --git a/crypto/src/asn1/crmf/CertTemplate.cs b/crypto/src/asn1/crmf/CertTemplate.cs index 3de9f1d5a..f731ac12e 100644 --- a/crypto/src/asn1/crmf/CertTemplate.cs +++ b/crypto/src/asn1/crmf/CertTemplate.cs @@ -77,7 +77,7 @@ namespace Org.BouncyCastle.Asn1.Crmf public virtual int Version { - get { return version.Value.IntValue; } + get { return version.IntValueExact; } } public virtual DerInteger SerialNumber diff --git a/crypto/src/asn1/crmf/PopoPrivKey.cs b/crypto/src/asn1/crmf/PopoPrivKey.cs index 0cedc5127..2b38cb109 100644 --- a/crypto/src/asn1/crmf/PopoPrivKey.cs +++ b/crypto/src/asn1/crmf/PopoPrivKey.cs @@ -26,7 +26,7 @@ namespace Org.BouncyCastle.Asn1.Crmf this.obj = DerBitString.GetInstance(obj, false); break; case subsequentMessage: - this.obj = SubsequentMessage.ValueOf(DerInteger.GetInstance(obj, false).Value.IntValue); + this.obj = SubsequentMessage.ValueOf(DerInteger.GetInstance(obj, false).IntValueExact); break; case dhMAC: this.obj = DerBitString.GetInstance(obj, false); diff --git a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs index f4a3fce64..92c9312c7 100644 --- a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs +++ b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs @@ -5,6 +5,7 @@ using Org.BouncyCastle.Asn1.Rosstandart; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; @@ -15,6 +16,18 @@ namespace Org.BouncyCastle.Asn1.CryptoPro /// </summary> public sealed class ECGost3410NamedCurves { + private static ECPoint ConfigureBasepoint(ECCurve curve, BigInteger x, BigInteger y) + { + ECPoint G = curve.CreatePoint(x, y); + WNafUtilities.ConfigureBasepoint(G); + return G; + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + private ECGost3410NamedCurves() { } @@ -28,15 +41,15 @@ namespace Org.BouncyCastle.Asn1.CryptoPro BigInteger mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); BigInteger mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); - FpCurve curve = new FpCurve( + ECCurve curve = ConfigureCurve(new FpCurve( mod_p, // p new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a new BigInteger("166"), // b - mod_q, BigInteger.One); + mod_q, BigInteger.One)); ECDomainParameters ecParams = new ECDomainParameters( curve, - curve.CreatePoint( + ConfigureBasepoint(curve, new BigInteger("1"), // x new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")), // y mod_q, BigInteger.One); @@ -46,15 +59,15 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); - curve = new FpCurve( + curve = ConfigureCurve(new FpCurve( mod_p, // p new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), new BigInteger("166"), - mod_q, BigInteger.One); + mod_q, BigInteger.One)); ecParams = new ECDomainParameters( curve, - curve.CreatePoint( + ConfigureBasepoint(curve, new BigInteger("1"), // x new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")), // y mod_q, BigInteger.One); @@ -64,15 +77,15 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823193"); //p mod_q = new BigInteger("57896044618658097711785492504343953927102133160255826820068844496087732066703"); //q - curve = new FpCurve( + curve = ConfigureCurve(new FpCurve( mod_p, // p new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823190"), // a new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595"), // b - mod_q, BigInteger.One); + mod_q, BigInteger.One)); ecParams = new ECDomainParameters( curve, - curve.CreatePoint( + ConfigureBasepoint(curve, new BigInteger("1"), // x new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124")), // y mod_q, BigInteger.One); @@ -82,15 +95,15 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); - curve = new FpCurve( + curve = ConfigureCurve(new FpCurve( mod_p, // p new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), new BigInteger("32858"), - mod_q, BigInteger.One); + mod_q, BigInteger.One)); ecParams = new ECDomainParameters( curve, - curve.CreatePoint( + ConfigureBasepoint(curve, new BigInteger("0"), new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247")), mod_q, BigInteger.One); @@ -99,15 +112,16 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); //p mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); //q - curve = new FpCurve( + + curve = ConfigureCurve(new FpCurve( mod_p, // p new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), // a new BigInteger("32858"), // b - mod_q, BigInteger.One); + mod_q, BigInteger.One)); ecParams = new ECDomainParameters( curve, - curve.CreatePoint( + ConfigureBasepoint(curve, new BigInteger("0"), // x new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247")), // y mod_q, BigInteger.One); @@ -117,15 +131,16 @@ namespace Org.BouncyCastle.Asn1.CryptoPro //GOST34.10 2012 mod_p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", 16); //p mod_q = new BigInteger("400000000000000000000000000000000FD8CDDFC87B6635C115AF556C360C67", 16); //q - curve = new FpCurve( + + curve = ConfigureCurve(new FpCurve( mod_p, // p new BigInteger("C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335", 16), // a new BigInteger("295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513", 16), // b - mod_q, BigInteger.Four); + mod_q, BigInteger.Four)); ecParams = new ECDomainParameters( curve, - curve.CreatePoint( + ConfigureBasepoint(curve, new BigInteger("91E38443A5E82C0D880923425712B2BB658B9196932E02C78B2582FE742DAA28", 16), // x new BigInteger("32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C", 16)), // y mod_q, BigInteger.Four); @@ -134,15 +149,16 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7", 16); //p mod_q = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27E69532F48D89116FF22B8D4E0560609B4B38ABFAD2B85DCACDB1411F10B275", 16); //q - curve = new FpCurve( + + curve = ConfigureCurve(new FpCurve( mod_p, // p new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4", 16), // a new BigInteger("E8C2505DEDFC86DDC1BD0B2B6667F1DA34B82574761CB0E879BD081CFD0B6265EE3CB090F30D27614CB4574010DA90DD862EF9D4EBEE4761503190785A71C760", 16), // b - mod_q, BigInteger.One); + mod_q, BigInteger.One)); ecParams = new ECDomainParameters( curve, - curve.CreatePoint( + ConfigureBasepoint(curve, new BigInteger("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003"), // x new BigInteger("7503CFE87A836AE3A61B8816E25450E6CE5E1C93ACF1ABC1778064FDCBEFA921DF1626BE4FD036E93D75E6A50E3A41E98028FE5FC235F5B889A589CB5215F2A4", 16)), // y mod_q, BigInteger.One); @@ -151,15 +167,16 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p = new BigInteger("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006F", 16); //p mod_q = new BigInteger("800000000000000000000000000000000000000000000000000000000000000149A1EC142565A545ACFDB77BD9D40CFA8B996712101BEA0EC6346C54374F25BD", 16); //q - curve = new FpCurve( + + curve = ConfigureCurve(new FpCurve( mod_p, // p new BigInteger("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C", 16), // a new BigInteger("687D1B459DC841457E3E06CF6F5E2517B97C7D614AF138BCBF85DC806C4B289F3E965D2DB1416D217F8B276FAD1AB69C50F78BEE1FA3106EFB8CCBC7C5140116", 16), // b - mod_q, BigInteger.One); + mod_q, BigInteger.One)); ecParams = new ECDomainParameters( curve, - curve.CreatePoint( + ConfigureBasepoint(curve, new BigInteger("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"), // x new BigInteger("1A8F7EDA389B094C2C071E3647A8940F3C123B697578C213BE6DD9E6C8EC7335DCB228FD1EDF4A39152CBCAAF8C0398828041055F94CEEEC7E21340780FE41BD", 16)), // y mod_q, BigInteger.One); @@ -168,15 +185,16 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7", 16); //p mod_q = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC98CDBA46506AB004C33A9FF5147502CC8EDA9E7A769A12694623CEF47F023ED", 16); //q - curve = new FpCurve( + + curve = ConfigureCurve(new FpCurve( mod_p, // p new BigInteger("DC9203E514A721875485A529D2C722FB187BC8980EB866644DE41C68E143064546E861C0E2C9EDD92ADE71F46FCF50FF2AD97F951FDA9F2A2EB6546F39689BD3", 16), // a new BigInteger("B4C4EE28CEBC6C2C8AC12952CF37F16AC7EFB6A9F69F4B57FFDA2E4F0DE5ADE038CBC2FFF719D2C18DE0284B8BFEF3B52B8CC7A5F5BF0A3C8D2319A5312557E1", 16), // b - mod_q, BigInteger.Four); + mod_q, BigInteger.Four)); ecParams = new ECDomainParameters( curve, - curve.CreatePoint( + ConfigureBasepoint(curve, new BigInteger("E2E31EDFC23DE7BDEBE241CE593EF5DE2295B7A9CBAEF021D385F7074CEA043AA27272A7AE602BF2A7B9033DB9ED3610C6FB85487EAE97AAC5BC7928C1950148", 16), // x new BigInteger("F5CE40D95B5EB899ABBCCFF5911CB8577939804D6527378B8C108C3D2090FF9BE18E2D33E3021ED2EF32D85822423B6304F726AA854BAE07D0396E9A9ADDC40F", 16)), // y mod_q, BigInteger.Four); diff --git a/crypto/src/asn1/cryptopro/GOST3410ParamSetParameters.cs b/crypto/src/asn1/cryptopro/GOST3410ParamSetParameters.cs index b347f8dbd..ee6ed8c99 100644 --- a/crypto/src/asn1/cryptopro/GOST3410ParamSetParameters.cs +++ b/crypto/src/asn1/cryptopro/GOST3410ParamSetParameters.cs @@ -53,7 +53,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro if (seq.Count != 4) throw new ArgumentException("Wrong number of elements in sequence", "seq"); - this.keySize = DerInteger.GetInstance(seq[0]).Value.IntValue; + this.keySize = DerInteger.GetInstance(seq[0]).IntValueExact; this.p = DerInteger.GetInstance(seq[1]); this.q = DerInteger.GetInstance(seq[2]); this.a = DerInteger.GetInstance(seq[3]); diff --git a/crypto/src/asn1/gm/GMNamedCurves.cs b/crypto/src/asn1/gm/GMNamedCurves.cs index e2ec6d854..5b1072f8c 100644 --- a/crypto/src/asn1/gm/GMNamedCurves.cs +++ b/crypto/src/asn1/gm/GMNamedCurves.cs @@ -5,6 +5,7 @@ using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Encoders; @@ -17,6 +18,13 @@ namespace Org.BouncyCastle.Asn1.GM { } + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.Decode(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + private static ECCurve ConfigureCurve(ECCurve curve) { return curve; @@ -47,10 +55,8 @@ namespace Org.BouncyCastle.Asn1.GM BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7" - + "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0")); - + X9ECPoint G = ConfigureBasepoint(curve, + "0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"); return new X9ECParameters(curve, G, n, h, S); } } @@ -75,9 +81,8 @@ namespace Org.BouncyCastle.Asn1.GM BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "4AD5F7048DE709AD51236DE6" + "5E4D4B482C836DC6E4106640" - + "02BB3A02D4AAADACAE24817A" + "4CA3A1B014B5270432DB27D2")); + X9ECPoint G = ConfigureBasepoint(curve, + "044AD5F7048DE709AD51236DE65E4D4B482C836DC6E410664002BB3A02D4AAADACAE24817A4CA3A1B014B5270432DB27D2"); return new X9ECParameters(curve, G, n, h, S); } diff --git a/crypto/src/asn1/icao/CscaMasterList.cs b/crypto/src/asn1/icao/CscaMasterList.cs index 6890d8a2e..d03b3adb4 100644 --- a/crypto/src/asn1/icao/CscaMasterList.cs +++ b/crypto/src/asn1/icao/CscaMasterList.cs @@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Asn1.Icao public virtual int Version { - get { return version.Value.IntValue; } + get { return version.IntValueExact; } } public X509CertificateStructure[] GetCertStructs() diff --git a/crypto/src/asn1/icao/DataGroupHash.cs b/crypto/src/asn1/icao/DataGroupHash.cs index e0d7eee7b..bf83718f3 100644 --- a/crypto/src/asn1/icao/DataGroupHash.cs +++ b/crypto/src/asn1/icao/DataGroupHash.cs @@ -70,7 +70,7 @@ namespace Org.BouncyCastle.Asn1.Icao public int DataGroupNumber { - get { return dataGroupNumber.Value.IntValue; } + get { return dataGroupNumber.IntValueExact; } } public Asn1OctetString DataGroupHashValue diff --git a/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs b/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs index c4ebb2b72..b82c9373d 100644 --- a/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs +++ b/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs @@ -134,7 +134,7 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 switch ((Choice) declaration.TagNo) { case Choice.NotYoungerThan: - return DerInteger.GetInstance(declaration, false).Value.IntValue; + return DerInteger.GetInstance(declaration, false).IntValueExact; default: return -1; } diff --git a/crypto/src/asn1/misc/CAST5CBCParameters.cs b/crypto/src/asn1/misc/CAST5CBCParameters.cs index 51fd6607a..7bd9f1ec6 100644 --- a/crypto/src/asn1/misc/CAST5CBCParameters.cs +++ b/crypto/src/asn1/misc/CAST5CBCParameters.cs @@ -52,7 +52,7 @@ namespace Org.BouncyCastle.Asn1.Misc public int KeyLength { - get { return keyLength.Value.IntValue; } + get { return keyLength.IntValueExact; } } /** diff --git a/crypto/src/asn1/ocsp/OCSPResponseStatus.cs b/crypto/src/asn1/ocsp/OCSPResponseStatus.cs index 653317e33..cf52c73e4 100644 --- a/crypto/src/asn1/ocsp/OCSPResponseStatus.cs +++ b/crypto/src/asn1/ocsp/OCSPResponseStatus.cs @@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp } public OcspResponseStatus(DerEnumerated value) - : base(value.Value.IntValue) + : base(value.IntValueExact) { } } diff --git a/crypto/src/asn1/pkcs/CertBag.cs b/crypto/src/asn1/pkcs/CertBag.cs index b6f4c8a30..e561fb890 100644 --- a/crypto/src/asn1/pkcs/CertBag.cs +++ b/crypto/src/asn1/pkcs/CertBag.cs @@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Asn1.Pkcs // this.seq = seq; this.certID = DerObjectIdentifier.GetInstance(seq[0]); - this.certValue = DerTaggedObject.GetInstance(seq[1]).GetObject(); + this.certValue = Asn1TaggedObject.GetInstance(seq[1]).GetObject(); } public CertBag( diff --git a/crypto/src/asn1/pkcs/EncryptedData.cs b/crypto/src/asn1/pkcs/EncryptedData.cs index 7e95eb586..6a4c04f25 100644 --- a/crypto/src/asn1/pkcs/EncryptedData.cs +++ b/crypto/src/asn1/pkcs/EncryptedData.cs @@ -52,7 +52,7 @@ namespace Org.BouncyCastle.Asn1.Pkcs if (seq.Count != 2) throw new ArgumentException("Wrong number of elements in sequence", "seq"); - int version = ((DerInteger) seq[0]).Value.IntValue; + int version = ((DerInteger)seq[0]).IntValueExact; if (version != 0) { throw new ArgumentException("sequence not version 0"); diff --git a/crypto/src/asn1/pkcs/SignedData.cs b/crypto/src/asn1/pkcs/SignedData.cs index 3442e671c..ae335103c 100644 --- a/crypto/src/asn1/pkcs/SignedData.cs +++ b/crypto/src/asn1/pkcs/SignedData.cs @@ -66,9 +66,9 @@ namespace Org.BouncyCastle.Asn1.Pkcs // an interesting feature of SignedData is that there appear to be varying implementations... // for the moment we ignore anything which doesn't fit. // - if (o is DerTaggedObject) + if (o is Asn1TaggedObject) { - DerTaggedObject tagged = (DerTaggedObject) o; + Asn1TaggedObject tagged = (Asn1TaggedObject)o; switch (tagged.TagNo) { diff --git a/crypto/src/asn1/sec/SECNamedCurves.cs b/crypto/src/asn1/sec/SECNamedCurves.cs index b753ac5d1..44190d2b2 100644 --- a/crypto/src/asn1/sec/SECNamedCurves.cs +++ b/crypto/src/asn1/sec/SECNamedCurves.cs @@ -6,6 +6,7 @@ using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Encoders; @@ -18,6 +19,13 @@ namespace Org.BouncyCastle.Asn1.Sec { } + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.Decode(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + private static ECCurve ConfigureCurve(ECCurve curve) { return curve; @@ -54,9 +62,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "09487239995A5EE76B55F9C2F098" - + "A89CE5AF8724C0A23E0E0FF77500")); + + X9ECPoint G = ConfigureBasepoint(curve, + "0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500"); return new X9ECParameters(curve, G, n, h, S); } @@ -83,9 +91,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(4); ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "4BA30AB5E892B4E1649DD0928643" - + "ADCD46F5882E3747DEF36E956E97")); + + X9ECPoint G = ConfigureBasepoint(curve, + "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97"); return new X9ECParameters(curve, G, n, h, S); } @@ -112,9 +120,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "161FF7528B899B2D0C28607CA52C5B86" - + "CF5AC8395BAFEB13C02DA292DDED7A83")); + + X9ECPoint G = ConfigureBasepoint(curve, + "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83"); return new X9ECParameters(curve, G, n, h, S); } @@ -141,9 +149,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(4); ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "7B6AA5D85E572983E6FB32A7CDEBC140" - + "27B6916A894D3AEE7106FE805FC34B44")); + + X9ECPoint G = ConfigureBasepoint(curve, + "047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44"); return new X9ECParameters(curve, G, n, h, S); } @@ -172,20 +180,21 @@ namespace Org.BouncyCastle.Asn1.Sec GlvTypeBParameters glv = new GlvTypeBParameters( new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16), new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16), - new BigInteger[]{ - new BigInteger("9162fbe73984472a0a9e", 16), - new BigInteger("-96341f1138933bc2f505", 16) }, - new BigInteger[]{ - new BigInteger("127971af8721782ecffa3", 16), - new BigInteger("9162fbe73984472a0a9e", 16) }, - new BigInteger("9162fbe73984472a0a9d0590", 16), - new BigInteger("96341f1138933bc2f503fd44", 16), - 176); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("9162fbe73984472a0a9e", 16), + new BigInteger("-96341f1138933bc2f505", 16) }, + new BigInteger[]{ + new BigInteger("127971af8721782ecffa3", 16), + new BigInteger("9162fbe73984472a0a9e", 16) }, + new BigInteger("9162fbe73984472a0a9d0590", 16), + new BigInteger("96341f1138933bc2f503fd44", 16), + 176)); ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" - + "938CF935318FDCED6BC28286531733C3F03C4FEE")); + + X9ECPoint G = ConfigureBasepoint(curve, + "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE"); return new X9ECParameters(curve, G, n, h, S); } @@ -212,9 +221,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "4A96B5688EF573284664698968C38BB913CBFC82" - + "23A628553168947D59DCC912042351377AC5FB32")); + + X9ECPoint G = ConfigureBasepoint(curve, + "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32"); return new X9ECParameters(curve, G, n, h, S); } @@ -241,9 +250,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "52DCB034293A117E1F4FF11B30F7199D3144CE6D" - + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E")); + + X9ECPoint G = ConfigureBasepoint(curve, + "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"); return new X9ECParameters(curve, G, n, h, S); } @@ -272,20 +281,21 @@ namespace Org.BouncyCastle.Asn1.Sec GlvTypeBParameters glv = new GlvTypeBParameters( new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16), new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16), - new BigInteger[]{ - new BigInteger("71169be7330b3038edb025f1", 16), - new BigInteger("-b3fb3400dec5c4adceb8655c", 16) }, - new BigInteger[]{ - new BigInteger("12511cfe811d0f4e6bc688b4d", 16), - new BigInteger("71169be7330b3038edb025f1", 16) }, - new BigInteger("71169be7330b3038edb025f1d0f9", 16), - new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), - 208); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("71169be7330b3038edb025f1", 16), + new BigInteger("-b3fb3400dec5c4adceb8655c", 16) }, + new BigInteger[]{ + new BigInteger("12511cfe811d0f4e6bc688b4d", 16), + new BigInteger("71169be7330b3038edb025f1", 16) }, + new BigInteger("71169be7330b3038edb025f1d0f9", 16), + new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), + 208)); ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" - + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D")); + + X9ECPoint G = ConfigureBasepoint(curve, + "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"); return new X9ECParameters(curve, G, n, h, S); } @@ -312,9 +322,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" - + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")); + + X9ECPoint G = ConfigureBasepoint(curve, + "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811"); return new X9ECParameters(curve, G, n, h, S); } @@ -343,20 +353,21 @@ namespace Org.BouncyCastle.Asn1.Sec GlvTypeBParameters glv = new GlvTypeBParameters( new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16), new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16), - new BigInteger[]{ - new BigInteger("6b8cf07d4ca75c88957d9d670591", 16), - new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) }, - new BigInteger[]{ - new BigInteger("1243ae1b4d71613bc9f780a03690e", 16), - new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) }, - new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), - new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), - 240); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16), + new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) }, + new BigInteger[]{ + new BigInteger("1243ae1b4d71613bc9f780a03690e", 16), + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) }, + new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), + new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), + 240)); ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C" - + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5")); + + X9ECPoint G = ConfigureBasepoint(curve, + "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"); return new X9ECParameters(curve, G, n, h, S); } @@ -383,9 +394,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" - + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")); + + X9ECPoint G = ConfigureBasepoint(curve, + "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"); return new X9ECParameters(curve, G, n, h, S); } @@ -414,20 +425,21 @@ namespace Org.BouncyCastle.Asn1.Sec GlvTypeBParameters glv = new GlvTypeBParameters( new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16), new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16), - new BigInteger[]{ - new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16), - new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) }, - new BigInteger[]{ - new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16), - new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) }, - new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), - new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), - 272); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16), + new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) }, + new BigInteger[]{ + new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16), + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) }, + new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), + new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), + 272)); ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" - + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8")); + + X9ECPoint G = ConfigureBasepoint(curve, + "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); return new X9ECParameters(curve, G, n, h, S); } @@ -454,9 +466,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" - + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")); + + X9ECPoint G = ConfigureBasepoint(curve, + "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"); return new X9ECParameters(curve, G, n, h, S); } @@ -483,9 +495,10 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + X9ECPoint G = ConfigureBasepoint(curve, "04" + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7" - + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")); + + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"); return new X9ECParameters(curve, G, n, h, S); } @@ -512,9 +525,10 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.One; ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + X9ECPoint G = ConfigureBasepoint(curve, "04" + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" - + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650")); + + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"); return new X9ECParameters(curve, G, n, h, S); } @@ -542,9 +556,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "009D73616F35F4AB1407D73562C10F" - + "00A52830277958EE84D1315ED31886")); + + X9ECPoint G = ConfigureBasepoint(curve, + "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886"); return new X9ECParameters(curve, G, n, h, S); } @@ -572,9 +586,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "01A57A6A7B26CA5EF52FCDB8164797" - + "00B3ADC94ED1FE674C06E695BABA1D")); + + X9ECPoint G = ConfigureBasepoint(curve, + "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D"); return new X9ECParameters(curve, G, n, h, S); } @@ -604,9 +618,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "0081BAF91FDF9833C40F9C181343638399" - + "078C6E7EA38C001F73C8134B1B4EF9E150")); + + X9ECPoint G = ConfigureBasepoint(curve, + "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150"); return new X9ECParameters(curve, G, n, h, S); } @@ -636,9 +650,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "0356DCD8F2F95031AD652D23951BB366A8" - + "0648F06D867940A5366D9E265DE9EB240F")); + + X9ECPoint G = ConfigureBasepoint(curve, + "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F"); return new X9ECParameters(curve, G, n, h, S); } @@ -668,9 +682,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8" - + "0289070FB05D38FF58321F2E800536D538CCDAA3D9")); + + X9ECPoint G = ConfigureBasepoint(curve, + "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9"); return new X9ECParameters(curve, G, n, h, S); } @@ -700,9 +714,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "0369979697AB43897789566789567F787A7876A654" - + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883")); + + X9ECPoint G = ConfigureBasepoint(curve, + "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883"); return new X9ECParameters(curve, G, n, h, S); } @@ -732,9 +746,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "03F0EBA16286A2D57EA0991168D4994637E8343E36" - + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1")); + + X9ECPoint G = ConfigureBasepoint(curve, + "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"); return new X9ECParameters(curve, G, n, h, S); } @@ -762,9 +776,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1" - + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05")); + + X9ECPoint G = ConfigureBasepoint(curve, + "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"); return new X9ECParameters(curve, G, n, h, S); } @@ -792,9 +806,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F" - + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C")); + + X9ECPoint G = ConfigureBasepoint(curve, + "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"); return new X9ECParameters(curve, G, n, h, S); } @@ -822,9 +836,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(4); ECCurve curve = new F2mCurve(m, k, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126" - + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3")); + + X9ECPoint G = ConfigureBasepoint(curve, + "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"); return new X9ECParameters(curve, G, n, h, S); } @@ -852,9 +866,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B" - + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052")); + + X9ECPoint G = ConfigureBasepoint(curve, + "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"); return new X9ECParameters(curve, G, n, h, S); } @@ -882,9 +896,9 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(4); ECCurve curve = new F2mCurve(m, k, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC" - + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA")); + + X9ECPoint G = ConfigureBasepoint(curve, + "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"); return new X9ECParameters(curve, G, n, h, S); } @@ -914,9 +928,10 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(4); ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + X9ECPoint G = ConfigureBasepoint(curve, "04" + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836" - + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259")); + + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"); return new X9ECParameters(curve, G, n, h, S); } @@ -946,9 +961,10 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + X9ECPoint G = ConfigureBasepoint(curve, "04" + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053" - + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4")); + + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"); return new X9ECParameters(curve, G, n, h, S); } @@ -976,9 +992,10 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(4); ECCurve curve = new F2mCurve(m, k, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + X9ECPoint G = ConfigureBasepoint(curve, "04" + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746" - + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B")); + + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"); return new X9ECParameters(curve, G, n, h, S); } @@ -1006,9 +1023,10 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + X9ECPoint G = ConfigureBasepoint(curve, "04" + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7" - + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706")); + + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"); return new X9ECParameters(curve, G, n, h, S); } @@ -1038,9 +1056,10 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(4); ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + X9ECPoint G = ConfigureBasepoint(curve, "04" + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972" - + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3")); + + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"); return new X9ECParameters(curve, G, n, h, S); } @@ -1070,9 +1089,10 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger h = BigInteger.ValueOf(2); ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + X9ECPoint G = ConfigureBasepoint(curve, "04" + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19" - + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B")); + + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"); return new X9ECParameters(curve, G, n, h, S); } diff --git a/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs b/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs index 9a82db319..8393f3ea5 100644 --- a/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs +++ b/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs @@ -3,6 +3,7 @@ using System.Collections; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Encoders; @@ -15,6 +16,13 @@ namespace Org.BouncyCastle.Asn1.TeleTrust */ public class TeleTrusTNamedCurves { + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.Decode(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + private static ECCurve ConfigureCurve(ECCurve curve) { return curve; @@ -38,10 +46,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("1E589A8595423412134FAA2DBDEC95C8D8675E58", 16), // b n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321")), // G - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321"); + + return new X9ECParameters(curve, G, n, h); } } @@ -58,16 +66,16 @@ namespace Org.BouncyCastle.Asn1.TeleTrust BigInteger h = new BigInteger("01", 16); ECCurve curve = ConfigureCurve(new FpCurve( - // new BigInteger("24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B", 16), // Z + //new BigInteger("24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B", 16), // Z new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620C", 16), // a' new BigInteger("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", 16), // b' n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD")), // G - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD"); + + return new X9ECParameters(curve, G, n, h); } } @@ -89,10 +97,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", 16), // b n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F")), // G - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F"); + + return new X9ECParameters(curve, G, n, h); } } @@ -115,10 +123,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", 16), // b' n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9")), // G' - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9"); + + return new X9ECParameters(curve, G, n, h); } } @@ -140,10 +148,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", 16), // b n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD")), // G - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD"); + + return new X9ECParameters(curve, G, n, h); } } @@ -166,10 +174,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", 16), // b' n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C")), // G' - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C"); + + return new X9ECParameters(curve, G, n, h); } } @@ -191,10 +199,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", 16), // b n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997")), // G - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997"); + + return new X9ECParameters(curve, G, n, h); } } @@ -217,10 +225,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16), // b' n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE")), // G' - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE"); + + return new X9ECParameters(curve, G, n, h); } } @@ -242,10 +250,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", 16), // b n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1")), // G - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1"); + + return new X9ECParameters(curve, G, n, h); } } @@ -268,10 +276,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", 16), // b' n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3")), // G' - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3"); + + return new X9ECParameters(curve, G, n, h); } } @@ -293,10 +301,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", 16), // b n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315")), // G - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315"); + + return new X9ECParameters(curve, G, n, h); } } @@ -319,10 +327,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16), // b' n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928")), // G' - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928"); + + return new X9ECParameters(curve, G, n, h); } } @@ -344,10 +352,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", 16), // b n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892")), // G - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892"); + + return new X9ECParameters(curve, G, n, h); } } @@ -370,10 +378,10 @@ namespace Org.BouncyCastle.Asn1.TeleTrust new BigInteger("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16), // b' n, h)); - return new X9ECParameters( - curve, - new X9ECPoint(curve, Hex.Decode("04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332")), // G' - n, h); + X9ECPoint G = ConfigureBasepoint(curve, + "04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332"); + + return new X9ECParameters(curve, G, n, h); } } diff --git a/crypto/src/asn1/tsp/Accuracy.cs b/crypto/src/asn1/tsp/Accuracy.cs index c5a5ca119..31289db99 100644 --- a/crypto/src/asn1/tsp/Accuracy.cs +++ b/crypto/src/asn1/tsp/Accuracy.cs @@ -22,26 +22,22 @@ namespace Org.BouncyCastle.Asn1.Tsp DerInteger millis, DerInteger micros) { - //Verifications - if (millis != null - && (millis.Value.IntValue < MinMillis - || millis.Value.IntValue > MaxMillis)) - { - throw new ArgumentException( - "Invalid millis field : not in (1..999)"); - } - - if (micros != null - && (micros.Value.IntValue < MinMicros - || micros.Value.IntValue > MaxMicros)) - { - throw new ArgumentException( - "Invalid micros field : not in (1..999)"); - } + if (null != millis) + { + int millisValue = millis.IntValueExact; + if (millisValue < MinMillis || millisValue > MaxMillis) + throw new ArgumentException("Invalid millis field : not in (1..999)"); + } + if (null != micros) + { + int microsValue = micros.IntValueExact; + if (microsValue < MinMicros || microsValue > MaxMicros) + throw new ArgumentException("Invalid micros field : not in (1..999)"); + } - this.seconds = seconds; - this.millis = millis; - this.micros = micros; + this.seconds = seconds; + this.millis = millis; + this.micros = micros; } private Accuracy( @@ -54,33 +50,27 @@ namespace Org.BouncyCastle.Asn1.Tsp { seconds = (DerInteger) seq[i]; } - else if (seq[i] is DerTaggedObject) + else if (seq[i] is Asn1TaggedObject) { - DerTaggedObject extra = (DerTaggedObject) seq[i]; + Asn1TaggedObject extra = (Asn1TaggedObject)seq[i]; - switch (extra.TagNo) - { - case 0: - millis = DerInteger.GetInstance(extra, false); - if (millis.Value.IntValue < MinMillis - || millis.Value.IntValue > MaxMillis) - { - throw new ArgumentException( - "Invalid millis field : not in (1..999)."); - } - break; - case 1: - micros = DerInteger.GetInstance(extra, false); - if (micros.Value.IntValue < MinMicros - || micros.Value.IntValue > MaxMicros) - { - throw new ArgumentException( - "Invalid micros field : not in (1..999)."); - } - break; - default: - throw new ArgumentException("Invalig tag number"); - } + switch (extra.TagNo) + { + case 0: + millis = DerInteger.GetInstance(extra, false); + int millisValue = millis.IntValueExact; + if (millisValue < MinMillis || millisValue > MaxMillis) + throw new ArgumentException("Invalid millis field : not in (1..999)"); + break; + case 1: + micros = DerInteger.GetInstance(extra, false); + int microsValue = micros.IntValueExact; + if (microsValue < MinMicros || microsValue > MaxMicros) + throw new ArgumentException("Invalid micros field : not in (1..999)"); + break; + default: + throw new ArgumentException("Invalid tag number"); + } } } } diff --git a/crypto/src/asn1/util/Asn1Dump.cs b/crypto/src/asn1/util/Asn1Dump.cs index 6a21ee2af..019041789 100644 --- a/crypto/src/asn1/util/Asn1Dump.cs +++ b/crypto/src/asn1/util/Asn1Dump.cs @@ -63,7 +63,7 @@ namespace Org.BouncyCastle.Asn1.Utilities } } } - else if (obj is DerTaggedObject) + else if (obj is Asn1TaggedObject) { string tab = indent + Tab; buf.Append(indent); @@ -76,7 +76,7 @@ namespace Org.BouncyCastle.Asn1.Utilities buf.Append("Tagged ["); } - DerTaggedObject o = (DerTaggedObject)obj; + Asn1TaggedObject o = (Asn1TaggedObject)obj; buf.Append(((int)o.TagNo).ToString()); buf.Append(']'); diff --git a/crypto/src/asn1/x500/style/IetfUtilities.cs b/crypto/src/asn1/x500/style/IetfUtilities.cs index e3236aaec..2c0ab45bc 100644 --- a/crypto/src/asn1/x500/style/IetfUtilities.cs +++ b/crypto/src/asn1/x500/style/IetfUtilities.cs @@ -33,7 +33,7 @@ namespace Org.BouncyCastle.Asn1.X500.Style } catch (IOException e) { - throw new ArgumentException("Other value has no encoded form", "value", e); + throw new ArgumentException("Other value has no encoded form", e); } } @@ -85,7 +85,7 @@ namespace Org.BouncyCastle.Asn1.X500.Style while (endBuf >= 0 && vBuf[endBuf] == ' ') { - vBuf.Insert(endBuf, '\\'); + vBuf.Insert(endBuf, "\\"); endBuf--; } diff --git a/crypto/src/asn1/x509/CRLReason.cs b/crypto/src/asn1/x509/CRLReason.cs index e8eb53a59..050ceb3bd 100644 --- a/crypto/src/asn1/x509/CRLReason.cs +++ b/crypto/src/asn1/x509/CRLReason.cs @@ -45,15 +45,14 @@ namespace Org.BouncyCastle.Asn1.X509 { } - public CrlReason( - DerEnumerated reason) - : base(reason.Value.IntValue) + public CrlReason(DerEnumerated reason) + : base(reason.IntValueExact) { } public override string ToString() { - int reason = Value.IntValue; + int reason = IntValueExact; string str = (reason < 0 || reason > 10) ? "Invalid" : ReasonString[reason]; return "CrlReason: " + str; } diff --git a/crypto/src/asn1/x509/GeneralName.cs b/crypto/src/asn1/x509/GeneralName.cs index b8794ea8f..fe00323ee 100644 --- a/crypto/src/asn1/x509/GeneralName.cs +++ b/crypto/src/asn1/x509/GeneralName.cs @@ -170,24 +170,25 @@ namespace Org.BouncyCastle.Asn1.X509 switch (tag) { - case OtherName: - return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, false)); - case Rfc822Name: - return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false)); - case DnsName: - return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false)); - case X400Address: - throw new ArgumentException("unknown tag: " + tag); + case EdiPartyName: + case OtherName: + case X400Address: + return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, false)); + + case DnsName: + case Rfc822Name: + case UniformResourceIdentifier: + return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false)); + case DirectoryName: return new GeneralName(tag, X509Name.GetInstance(tagObj, true)); - case EdiPartyName: - return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, false)); - case UniformResourceIdentifier: - return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false)); case IPAddress: return new GeneralName(tag, Asn1OctetString.GetInstance(tagObj, false)); case RegisteredID: return new GeneralName(tag, DerObjectIdentifier.GetInstance(tagObj, false)); + + default: + throw new ArgumentException("unknown tag: " + tag); } } @@ -412,8 +413,10 @@ namespace Org.BouncyCastle.Asn1.X509 public override Asn1Object ToAsn1Object() { - // Explicitly tagged if DirectoryName - return new DerTaggedObject(tag == DirectoryName, tag, obj); + // directoryName is explicitly tagged as it is a CHOICE + bool isExplicit = (tag == DirectoryName); + + return new DerTaggedObject(isExplicit, tag, obj); } } } diff --git a/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs b/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs index 477329b7e..ae44a451f 100644 --- a/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs +++ b/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs @@ -66,6 +66,18 @@ namespace Org.BouncyCastle.Asn1.X509 get { return algID; } } + /** + * for when the public key is an encoded object - if the bitstring + * can't be decoded this routine raises an IOException. + * + * @exception IOException - if the bit string doesn't represent a Der + * encoded object. + */ + public Asn1Object ParsePublicKey() + { + return Asn1Object.FromByteArray(keyData.GetOctets()); + } + /** * for when the public key is an encoded object - if the bitstring * can't be decoded this routine raises an IOException. @@ -73,6 +85,7 @@ namespace Org.BouncyCastle.Asn1.X509 * @exception IOException - if the bit string doesn't represent a Der * encoded object. */ + [Obsolete("Use 'ParsePublicKey' instead")] public Asn1Object GetPublicKey() { return Asn1Object.FromByteArray(keyData.GetOctets()); diff --git a/crypto/src/asn1/x509/TBSCertList.cs b/crypto/src/asn1/x509/TBSCertList.cs index 5767a7f21..a427ba2ba 100644 --- a/crypto/src/asn1/x509/TBSCertList.cs +++ b/crypto/src/asn1/x509/TBSCertList.cs @@ -193,13 +193,13 @@ namespace Org.BouncyCastle.Asn1.X509 } if (seqPos < seq.Count - && !(seq[seqPos] is DerTaggedObject)) + && !(seq[seqPos] is Asn1TaggedObject)) { revokedCertificates = Asn1Sequence.GetInstance(seq[seqPos++]); } if (seqPos < seq.Count - && seq[seqPos] is DerTaggedObject) + && seq[seqPos] is Asn1TaggedObject) { crlExtensions = X509Extensions.GetInstance(seq[seqPos]); } @@ -207,7 +207,7 @@ namespace Org.BouncyCastle.Asn1.X509 public int Version { - get { return version.Value.IntValue + 1; } + get { return version.IntValueExact + 1; } } public DerInteger VersionNumber diff --git a/crypto/src/asn1/x509/TBSCertificateStructure.cs b/crypto/src/asn1/x509/TBSCertificateStructure.cs index e69e985f5..4e3c789e2 100644 --- a/crypto/src/asn1/x509/TBSCertificateStructure.cs +++ b/crypto/src/asn1/x509/TBSCertificateStructure.cs @@ -69,7 +69,7 @@ namespace Org.BouncyCastle.Asn1.X509 // // some certficates don't include a version number - we assume v1 // - if (seq[0] is DerTaggedObject) + if (seq[0] is Asn1TaggedObject) { version = DerInteger.GetInstance((Asn1TaggedObject)seq[0], true); } @@ -121,8 +121,7 @@ namespace Org.BouncyCastle.Asn1.X509 while (extras > 0) { - DerTaggedObject extra = (DerTaggedObject)seq[seqStart + 6 + extras]; - + Asn1TaggedObject extra = Asn1TaggedObject.GetInstance(seq[seqStart + 6 + extras]); switch (extra.TagNo) { case 1: @@ -154,7 +153,7 @@ namespace Org.BouncyCastle.Asn1.X509 public int Version { - get { return version.Value.IntValue + 1; } + get { return version.IntValueExact + 1; } } public DerInteger VersionNumber diff --git a/crypto/src/asn1/x509/qualified/Iso4217CurrencyCode.cs b/crypto/src/asn1/x509/qualified/Iso4217CurrencyCode.cs index 9ec88f5ed..a90a33ae2 100644 --- a/crypto/src/asn1/x509/qualified/Iso4217CurrencyCode.cs +++ b/crypto/src/asn1/x509/qualified/Iso4217CurrencyCode.cs @@ -35,7 +35,7 @@ namespace Org.BouncyCastle.Asn1.X509.Qualified if (obj is DerInteger) { DerInteger numericobj = DerInteger.GetInstance(obj); - int numeric = numericobj.Value.IntValue; + int numeric = numericobj.IntValueExact; return new Iso4217CurrencyCode(numeric); } @@ -74,7 +74,7 @@ namespace Org.BouncyCastle.Asn1.X509.Qualified public string Alphabetic { get { return ((DerPrintableString) obj).GetString(); } } - public int Numeric { get { return ((DerInteger)obj).Value.IntValue; } } + public int Numeric { get { return ((DerInteger)obj).IntValueExact; } } public override Asn1Object ToAsn1Object() { diff --git a/crypto/src/asn1/x509/qualified/TypeOfBiometricData.cs b/crypto/src/asn1/x509/qualified/TypeOfBiometricData.cs index 17b7841c3..a4e2e4555 100644 --- a/crypto/src/asn1/x509/qualified/TypeOfBiometricData.cs +++ b/crypto/src/asn1/x509/qualified/TypeOfBiometricData.cs @@ -35,7 +35,7 @@ namespace Org.BouncyCastle.Asn1.X509.Qualified if (obj is DerInteger) { DerInteger predefinedBiometricTypeObj = DerInteger.GetInstance(obj); - int predefinedBiometricType = predefinedBiometricTypeObj.Value.IntValue; + int predefinedBiometricType = predefinedBiometricTypeObj.IntValueExact; return new TypeOfBiometricData(predefinedBiometricType); } @@ -75,7 +75,7 @@ namespace Org.BouncyCastle.Asn1.X509.Qualified public int PredefinedBiometricType { - get { return ((DerInteger) obj).Value.IntValue; } + get { return ((DerInteger)obj).IntValueExact; } } public DerObjectIdentifier BiometricDataOid diff --git a/crypto/src/asn1/x9/X962NamedCurves.cs b/crypto/src/asn1/x9/X962NamedCurves.cs index 1609774f1..f8ba4144b 100644 --- a/crypto/src/asn1/x9/X962NamedCurves.cs +++ b/crypto/src/asn1/x9/X962NamedCurves.cs @@ -3,6 +3,7 @@ using System.Collections; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Encoders; @@ -18,6 +19,18 @@ namespace Org.BouncyCastle.Asn1.X9 { } + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.Decode(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + internal class Prime192v1Holder : X9ECParametersHolder { @@ -30,18 +43,16 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("ffffffffffffffffffffffff99def836146bc9b1b4d22831", 16); BigInteger h = BigInteger.One; - ECCurve cFp192v1 = new FpCurve( + ECCurve curve = ConfigureCurve(new FpCurve( new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16), new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16), - n, h); - - return new X9ECParameters( - cFp192v1, - new X9ECPoint(cFp192v1, - Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), - n, h, - Hex.Decode("3045AE6FC8422f64ED579528D38120EAE12196D5")); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012"); + + return new X9ECParameters(curve, G, n, h, Hex.Decode("3045AE6FC8422f64ED579528D38120EAE12196D5")); } } @@ -57,18 +68,16 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31", 16); BigInteger h = BigInteger.One; - ECCurve cFp192v2 = new FpCurve( + ECCurve curve = ConfigureCurve(new FpCurve( new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16), new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953", 16), - n, h); - - return new X9ECParameters( - cFp192v2, - new X9ECPoint(cFp192v2, - Hex.Decode("03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a")), - n, h, - Hex.Decode("31a92ee2029fd10d901b113e990710f0d21ac6b6")); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a"); + + return new X9ECParameters(curve, G, n, h, Hex.Decode("31a92ee2029fd10d901b113e990710f0d21ac6b6")); } } @@ -84,18 +93,16 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("ffffffffffffffffffffffff7a62d031c83f4294f640ec13", 16); BigInteger h = BigInteger.One; - ECCurve cFp192v3 = new FpCurve( + ECCurve curve = ConfigureCurve(new FpCurve( new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16), new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger("22123dc2395a05caa7423daeccc94760a7d462256bd56916", 16), - n, h); - - return new X9ECParameters( - cFp192v3, - new X9ECPoint(cFp192v3, - Hex.Decode("027d29778100c65a1da1783716588dce2b8b4aee8e228f1896")), - n, h, - Hex.Decode("c469684435deb378c4b65ca9591e2a5763059a2e")); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "027d29778100c65a1da1783716588dce2b8b4aee8e228f1896"); + + return new X9ECParameters(curve, G, n, h, Hex.Decode("c469684435deb378c4b65ca9591e2a5763059a2e")); } } @@ -111,18 +118,16 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b", 16); BigInteger h = BigInteger.One; - ECCurve cFp239v1 = new FpCurve( + ECCurve curve = ConfigureCurve(new FpCurve( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16), - n, h); - - return new X9ECParameters( - cFp239v1, - new X9ECPoint(cFp239v1, - Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), - n, h, - Hex.Decode("e43bb460f0b80cc0c0b075798e948060f8321b7d")); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf"); + + return new X9ECParameters(curve, G, n, h, Hex.Decode("e43bb460f0b80cc0c0b075798e948060f8321b7d")); } } @@ -138,18 +143,16 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063", 16); BigInteger h = BigInteger.One; - ECCurve cFp239v2 = new FpCurve( + ECCurve curve = ConfigureCurve(new FpCurve( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), new BigInteger("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c", 16), - n, h); - - return new X9ECParameters( - cFp239v2, - new X9ECPoint(cFp239v2, - Hex.Decode("0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7")), - n, h, - Hex.Decode("e8b4011604095303ca3b8099982be09fcb9ae616")); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7"); + + return new X9ECParameters(curve, G, n, h, Hex.Decode("e8b4011604095303ca3b8099982be09fcb9ae616")); } } @@ -165,18 +168,16 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551", 16); BigInteger h = BigInteger.One; - ECCurve cFp239v3 = new FpCurve( + ECCurve curve = ConfigureCurve(new FpCurve( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), new BigInteger("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e", 16), - n, h); - - return new X9ECParameters( - cFp239v3, - new X9ECPoint(cFp239v3, - Hex.Decode("036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a")), - n, h, - Hex.Decode("7d7374168ffe3471b60a857686a19475d3bfa2ff")); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a"); + + return new X9ECParameters(curve, G, n, h, Hex.Decode("7d7374168ffe3471b60a857686a19475d3bfa2ff")); } } @@ -192,18 +193,16 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16); BigInteger h = BigInteger.One; - ECCurve cFp256v1 = new FpCurve( + ECCurve curve = ConfigureCurve(new FpCurve( new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"), new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), - n, h); - - return new X9ECParameters( - cFp256v1, - new X9ECPoint(cFp256v1, - Hex.Decode("036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")), - n, h, - Hex.Decode("c49d360886e704936a6678e1139d26b7819f7e90")); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"); + + return new X9ECParameters(curve, G, n, h, Hex.Decode("c49d360886e704936a6678e1139d26b7819f7e90")); } } @@ -222,19 +221,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("0400000000000000000001E60FC8821CC74DAEAFC1", 16); BigInteger h = BigInteger.Two; - ECCurve c2m163v1 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 163, 1, 2, 8, new BigInteger("072546B5435234A422E0789675F432C89435DE5242", 16), new BigInteger("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", 16), - n, h); - - return new X9ECParameters( - c2m163v1, - new X9ECPoint(c2m163v1, - Hex.Decode("0307AF69989546103D79329FCC3D74880F33BBE803CB")), - n, h, - Hex.Decode("D2C0FB15760860DEF1EEF4D696E6768756151754")); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0307AF69989546103D79329FCC3D74880F33BBE803CB"); + + return new X9ECParameters(curve, G, n, h, Hex.Decode("D2C0FB15760860DEF1EEF4D696E6768756151754")); } } @@ -250,19 +247,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 16); BigInteger h = BigInteger.Two; - ECCurve c2m163v2 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 163, 1, 2, 8, new BigInteger("0108B39E77C4B108BED981ED0E890E117C511CF072", 16), new BigInteger("0667ACEB38AF4E488C407433FFAE4F1C811638DF20", 16), - n, h); - - return new X9ECParameters( - c2m163v2, - new X9ECPoint(c2m163v2, - Hex.Decode("030024266E4EB5106D0A964D92C4860E2671DB9B6CC5")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "030024266E4EB5106D0A964D92C4860E2671DB9B6CC5"); + + return new X9ECParameters(curve, G, n, h); } } @@ -278,18 +273,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 16); BigInteger h = BigInteger.Two; - ECCurve c2m163v3 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 163, 1, 2, 8, new BigInteger("07A526C63D3E25A256A007699F5447E32AE456B50E", 16), new BigInteger("03F7061798EB99E238FD6F1BF95B48FEEB4854252B", 16), - n, h); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB"); - return new X9ECParameters( - c2m163v3, - new X9ECPoint(c2m163v3, Hex.Decode("0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB")), - n, h, - null); + return new X9ECParameters(curve, G, n, h); } } @@ -305,19 +299,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("010092537397ECA4F6145799D62B0A19CE06FE26AD", 16); BigInteger h = BigInteger.ValueOf(0xFF6E); - ECCurve c2m176w1 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 176, 1, 2, 43, new BigInteger("00E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", 16), new BigInteger("005DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", 16), - n, h); - - return new X9ECParameters( - c2m176w1, - new X9ECPoint(c2m176w1, - Hex.Decode("038D16C2866798B600F9F08BB4A8E860F3298CE04A5798")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "038D16C2866798B600F9F08BB4A8E860F3298CE04A5798"); + + return new X9ECParameters(curve, G, n, h); } } @@ -333,19 +325,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("40000000000000000000000004A20E90C39067C893BBB9A5", 16); BigInteger h = BigInteger.Two; - ECCurve c2m191v1 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 191, 9, new BigInteger("2866537B676752636A68F56554E12640276B649EF7526267", 16), new BigInteger("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", 16), - n, h); - - return new X9ECParameters( - c2m191v1, - new X9ECPoint(c2m191v1, - Hex.Decode("0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D")), - n, h, - Hex.Decode("4E13CA542744D696E67687561517552F279A8C84")); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D"); + + return new X9ECParameters(curve, G, n, h, Hex.Decode("4E13CA542744D696E67687561517552F279A8C84")); } } @@ -361,19 +351,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("20000000000000000000000050508CB89F652824E06B8173", 16); BigInteger h = BigInteger.ValueOf(4); - ECCurve c2m191v2 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 191, 9, new BigInteger("401028774D7777C7B7666D1366EA432071274F89FF01E718", 16), new BigInteger("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", 16), - n, h); - - return new X9ECParameters( - c2m191v2, - new X9ECPoint(c2m191v2, - Hex.Decode("023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10"); + + return new X9ECParameters(curve, G, n, h); } } @@ -389,19 +377,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("155555555555555555555555610C0B196812BFB6288A3EA3", 16); BigInteger h = BigInteger.ValueOf(6); - ECCurve c2m191v3 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 191, 9, new BigInteger("6C01074756099122221056911C77D77E77A777E7E7E77FCB", 16), new BigInteger("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", 16), - n, h); - - return new X9ECParameters( - c2m191v3, - new X9ECPoint(c2m191v3, - Hex.Decode("03375D4CE24FDE434489DE8746E71786015009E66E38A926DD")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "03375D4CE24FDE434489DE8746E71786015009E66E38A926DD"); + + return new X9ECParameters(curve, G, n, h); } } @@ -417,19 +403,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 16); BigInteger h = BigInteger.ValueOf(0xFE48); - ECCurve c2m208w1 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 208, 1, 2, 83, new BigInteger("0", 16), new BigInteger("00C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", 16), - n, h); - - return new X9ECParameters( - c2m208w1, - new X9ECPoint(c2m208w1, - Hex.Decode("0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A"); + + return new X9ECParameters(curve, G, n, h); } } @@ -445,19 +429,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 16); BigInteger h = BigInteger.ValueOf(4); - ECCurve c2m239v1 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 239, 36, new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16), - n, h); - - return new X9ECParameters( - c2m239v1, - new X9ECPoint(c2m239v1, - Hex.Decode("0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D"); + + return new X9ECParameters(curve, G, n, h); } } @@ -473,19 +455,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 16); BigInteger h = BigInteger.ValueOf(6); - ECCurve c2m239v2 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 239, 36, new BigInteger("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", 16), new BigInteger("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", 16), - n, h); - - return new X9ECParameters( - c2m239v2, - new X9ECPoint(c2m239v2, - Hex.Decode("0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205"); + + return new X9ECParameters(curve, G, n, h); } } @@ -501,19 +481,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 16); BigInteger h = BigInteger.ValueOf(10); - ECCurve c2m239v3 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 239, 36, new BigInteger("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", 16), new BigInteger("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", 16), - n, h); - - return new X9ECParameters( - c2m239v3, - new X9ECPoint(c2m239v3, - Hex.Decode("0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92"); + + return new X9ECParameters(curve, G, n, h); } } @@ -529,19 +507,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", 16); BigInteger h = BigInteger.ValueOf(0xFF06); - ECCurve c2m272w1 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 272, 1, 3, 56, new BigInteger("0091A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", 16), new BigInteger("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", 16), - n, h); - - return new X9ECParameters( - c2m272w1, - new X9ECPoint(c2m272w1, - Hex.Decode("026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D"); + + return new X9ECParameters(curve, G, n, h); } } @@ -557,19 +533,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", 16); BigInteger h = BigInteger.ValueOf(0xFE2E); - ECCurve c2m304w1 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 304, 1, 2, 11, new BigInteger("00FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", 16), new BigInteger("00BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", 16), - n, h); - - return new X9ECParameters( - c2m304w1, - new X9ECPoint(c2m304w1, - Hex.Decode("02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614"); + + return new X9ECParameters(curve, G, n, h); } } @@ -585,19 +559,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", 16); BigInteger h = BigInteger.ValueOf(0x4C); - ECCurve c2m359v1 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 359, 68, new BigInteger("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", 16), new BigInteger("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", 16), - n, h); - - return new X9ECParameters( - c2m359v1, - new X9ECPoint(c2m359v1, - Hex.Decode("033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097"); + + return new X9ECParameters(curve, G, n, h); } } @@ -613,19 +585,17 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", 16); BigInteger h = BigInteger.ValueOf(0xFF70); - ECCurve c2m368w1 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 368, 1, 2, 85, new BigInteger("00E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", 16), new BigInteger("00FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", 16), - n, h); - - return new X9ECParameters( - c2m368w1, - new X9ECPoint(c2m368w1, - Hex.Decode("021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F"); + + return new X9ECParameters(curve, G, n, h); } } @@ -641,22 +611,21 @@ namespace Org.BouncyCastle.Asn1.X9 BigInteger n = new BigInteger("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", 16); BigInteger h = BigInteger.ValueOf(0x2760); - ECCurve c2m431r1 = new F2mCurve( + ECCurve curve = ConfigureCurve(new F2mCurve( 431, 120, new BigInteger("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", 16), new BigInteger("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", 16), - n, h); - - return new X9ECParameters( - c2m431r1, - new X9ECPoint(c2m431r1, - Hex.Decode("02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7")), - n, h, - null); + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7"); + + return new X9ECParameters(curve, G, n, h); } } + private static readonly IDictionary objIds = Platform.CreateHashtable(); private static readonly IDictionary curves = Platform.CreateHashtable(); private static readonly IDictionary names = Platform.CreateHashtable(); diff --git a/crypto/src/asn1/x9/X9Curve.cs b/crypto/src/asn1/x9/X9Curve.cs index eab94def8..0be9bf935 100644 --- a/crypto/src/asn1/x9/X9Curve.cs +++ b/crypto/src/asn1/x9/X9Curve.cs @@ -79,9 +79,8 @@ namespace Org.BouncyCastle.Asn1.X9 { // Characteristic two field DerSequence parameters = (DerSequence)fieldID.Parameters; - int m = ((DerInteger)parameters[0]).Value.IntValue; - DerObjectIdentifier representation - = (DerObjectIdentifier)parameters[1]; + int m = ((DerInteger)parameters[0]).IntValueExact; + DerObjectIdentifier representation = (DerObjectIdentifier)parameters[1]; int k1 = 0; int k2 = 0; @@ -89,15 +88,15 @@ namespace Org.BouncyCastle.Asn1.X9 if (representation.Equals(X9ObjectIdentifiers.TPBasis)) { // Trinomial basis representation - k1 = ((DerInteger)parameters[2]).Value.IntValue; + k1 = ((DerInteger)parameters[2]).IntValueExact; } else { // Pentanomial basis representation DerSequence pentanomial = (DerSequence) parameters[2]; - k1 = ((DerInteger) pentanomial[0]).Value.IntValue; - k2 = ((DerInteger) pentanomial[1]).Value.IntValue; - k3 = ((DerInteger) pentanomial[2]).Value.IntValue; + k1 = ((DerInteger)pentanomial[0]).IntValueExact; + k2 = ((DerInteger)pentanomial[1]).IntValueExact; + k3 = ((DerInteger)pentanomial[2]).IntValueExact; } BigInteger A = new BigInteger(1, Asn1OctetString.GetInstance(seq[0]).GetOctets()); BigInteger B = new BigInteger(1, Asn1OctetString.GetInstance(seq[1]).GetOctets()); diff --git a/crypto/src/cmp/ProtectedPkiMessage.cs b/crypto/src/cmp/ProtectedPkiMessage.cs index faddb0df1..770fe5443 100644 --- a/crypto/src/cmp/ProtectedPkiMessage.cs +++ b/crypto/src/cmp/ProtectedPkiMessage.cs @@ -120,11 +120,7 @@ namespace Org.BouncyCastle.Cmp streamCalculator.Stream.Write(enc, 0, enc.Length); streamCalculator.Stream.Flush(); -#if PORTABLE - streamCalculator.Stream.Dispose(); -#else - streamCalculator.Stream.Close(); -#endif + Platform.Dispose(streamCalculator.Stream); return streamCalculator.GetResult(); } diff --git a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs index 8ce0d48dc..5939e92df 100644 --- a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs +++ b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs @@ -90,6 +90,9 @@ namespace Org.BouncyCastle.Cmp public ProtectedPkiMessage Build(ISignatureFactory signatureFactory) { + if (null == body) + throw new InvalidOperationException("body must be set before building"); + IStreamCalculator calculator = signatureFactory.CreateCalculator(); if (!(signatureFactory.AlgorithmDetails is AlgorithmIdentifier)) @@ -105,6 +108,9 @@ namespace Org.BouncyCastle.Cmp public ProtectedPkiMessage Build(IMacFactory factory) { + if (null == body) + throw new InvalidOperationException("body must be set before building"); + IStreamCalculator calculator = factory.CreateCalculator(); FinalizeHeader((AlgorithmIdentifier)factory.AlgorithmDetails); PkiHeader header = hdrBuilBuilder.Build(); diff --git a/crypto/src/cms/CMSSignedData.cs b/crypto/src/cms/CMSSignedData.cs index 237c1528e..979be6535 100644 --- a/crypto/src/cms/CMSSignedData.cs +++ b/crypto/src/cms/CMSSignedData.cs @@ -147,7 +147,7 @@ namespace Org.BouncyCastle.Cms /// <summary>Return the version number for this object.</summary> public int Version { - get { return signedData.Version.Value.IntValue; } + get { return signedData.Version.IntValueExact; } } /** diff --git a/crypto/src/cms/CMSSignedDataParser.cs b/crypto/src/cms/CMSSignedDataParser.cs index fb51ab119..c25f0aad0 100644 --- a/crypto/src/cms/CMSSignedDataParser.cs +++ b/crypto/src/cms/CMSSignedDataParser.cs @@ -179,7 +179,7 @@ namespace Org.BouncyCastle.Cms */ public int Version { - get { return _signedData.Version.Value.IntValue; } + get { return _signedData.Version.IntValueExact; } } public ISet DigestOids diff --git a/crypto/src/cms/CMSSignedDataStreamGenerator.cs b/crypto/src/cms/CMSSignedDataStreamGenerator.cs index 29411e132..e32f95d42 100644 --- a/crypto/src/cms/CMSSignedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSSignedDataStreamGenerator.cs @@ -732,7 +732,7 @@ namespace Org.BouncyCastle.Cms { SignerInfo s = SignerInfo.GetInstance(si.ToSignerInfo()); - if (s.Version.Value.IntValue == 3) + if (s.Version.IntValueExact == 3) { return true; } diff --git a/crypto/src/cms/SignerInformation.cs b/crypto/src/cms/SignerInformation.cs index c262806a8..3643c6fe3 100644 --- a/crypto/src/cms/SignerInformation.cs +++ b/crypto/src/cms/SignerInformation.cs @@ -129,7 +129,7 @@ namespace Org.BouncyCastle.Cms */ public int Version { - get { return info.Version.Value.IntValue; } + get { return info.Version.IntValueExact; } } public AlgorithmIdentifier DigestAlgorithmID @@ -349,8 +349,8 @@ namespace Org.BouncyCastle.Cms throw new CmsException("RSASSA-PSS signature parameters specified unknown MGF"); IDigest pssDigest = DigestUtilities.GetDigest(pss.HashAlgorithm.Algorithm); - int saltLength = pss.SaltLength.Value.IntValue; - byte trailerField = (byte) pss.TrailerField.Value.IntValue; + int saltLength = pss.SaltLength.IntValueExact; + byte trailerField = (byte)pss.TrailerField.IntValueExact; // RFC 4055 3.1 // The value MUST be 1, which represents the trailer field with hexadecimal value 0xBC diff --git a/crypto/src/crmf/EncryptedValueBuilder.cs b/crypto/src/crmf/EncryptedValueBuilder.cs index 87ab0cd10..d95896959 100644 --- a/crypto/src/crmf/EncryptedValueBuilder.cs +++ b/crypto/src/crmf/EncryptedValueBuilder.cs @@ -121,11 +121,7 @@ namespace Org.BouncyCastle.Crmf try { eOut.Write(data, 0, data.Length); -#if PORTABLE - eOut.Dispose(); -#else - eOut.Close(); -#endif + Platform.Dispose(eOut); } catch (IOException e) { diff --git a/crypto/src/crmf/PKMacBuilder.cs b/crypto/src/crmf/PKMacBuilder.cs index b74eb6d18..156936eac 100644 --- a/crypto/src/crmf/PKMacBuilder.cs +++ b/crypto/src/crmf/PKMacBuilder.cs @@ -184,7 +184,7 @@ namespace Org.BouncyCastle.Crmf /// <returns>this</returns> public PKMacBuilder SetParameters(PbmParameter parameters) { - CheckIterationCountCeiling(parameters.IterationCount.Value.IntValue); + CheckIterationCountCeiling(parameters.IterationCount.IntValueExact); this.parameters = parameters; @@ -257,7 +257,7 @@ namespace Org.BouncyCastle.Crmf IDigest digest = provider.CreateDigest(parameters.Owf); - int iter = parameters.IterationCount.Value.IntValue; + int iter = parameters.IterationCount.IntValueExact; digest.BlockUpdate(K, 0, K.Length); diff --git a/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs b/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs index 154b606da..b7a3ae01a 100644 --- a/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs +++ b/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs @@ -5,6 +5,7 @@ using Org.BouncyCastle.Asn1.Crmf; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crmf { @@ -40,11 +41,7 @@ namespace Org.BouncyCastle.Crmf byte[] d = _pubKeyInfo.GetDerEncoded(); calc.Stream.Write(d, 0, d.Length); calc.Stream.Flush(); -#if PORTABLE - calc.Stream.Dispose(); -#else - calc.Stream.Close(); -#endif + Platform.Dispose(calc.Stream); this._publicKeyMAC = new PKMacValue( (AlgorithmIdentifier)fact.AlgorithmDetails, @@ -84,11 +81,7 @@ namespace Org.BouncyCastle.Crmf } calc.Stream.Flush(); -#if PORTABLE - calc.Stream.Dispose(); -#else - calc.Stream.Close(); -#endif + Platform.Dispose(calc.Stream); DefaultSignatureResult res = (DefaultSignatureResult)calc.GetResult(); return new PopoSigningKey(popo, (AlgorithmIdentifier)signer.AlgorithmDetails, new DerBitString(res.Collect())); } diff --git a/crypto/src/crypto/digests/Sha256Digest.cs b/crypto/src/crypto/digests/Sha256Digest.cs index 98e10a34d..63d5b8bee 100644 --- a/crypto/src/crypto/digests/Sha256Digest.cs +++ b/crypto/src/crypto/digests/Sha256Digest.cs @@ -230,63 +230,51 @@ namespace Org.BouncyCastle.Crypto.Digests Array.Clear(X, 0, 16); } - private static uint Sum1Ch( - uint x, - uint y, - uint z) + private static uint Sum1Ch(uint x, uint y, uint z) { // return Sum1(x) + Ch(x, y, z); return (((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))) - + ((x & y) ^ ((~x) & z)); - } + //+ ((x & y) ^ ((~x) & z)); + + (z ^ (x & (y ^ z))); + } - private static uint Sum0Maj( - uint x, - uint y, - uint z) + private static uint Sum0Maj(uint x, uint y, uint z) { // return Sum0(x) + Maj(x, y, z); return (((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))) - + ((x & y) ^ (x & z) ^ (y & z)); - } + //+ ((x & y) ^ (x & z) ^ (y & z)); + + ((x & y) | (z & (x ^ y))); + } // /* SHA-256 functions */ -// private static uint Ch( -// uint x, -// uint y, -// uint z) +// private static uint Ch(uint x, uint y, uint z) // { -// return ((x & y) ^ ((~x) & z)); +// return (x & y) ^ ((~x) & z); +// //return z ^ (x & (y ^ z)); // } // -// private static uint Maj( -// uint x, -// uint y, -// uint z) +// private static uint Maj(uint x, uint y, uint z) // { -// return ((x & y) ^ (x & z) ^ (y & z)); +// //return (x & y) ^ (x & z) ^ (y & z); +// return (x & y) | (z & (x ^ y)); // } // -// private static uint Sum0( -// uint x) +// private static uint Sum0(uint x) // { // return ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)); // } // -// private static uint Sum1( -// uint x) +// private static uint Sum1(uint x) // { // return ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)); // } - private static uint Theta0( - uint x) + private static uint Theta0(uint x) { return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3); } - private static uint Theta1( - uint x) + private static uint Theta1(uint x) { return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10); } diff --git a/crypto/src/crypto/ec/CustomNamedCurves.cs b/crypto/src/crypto/ec/CustomNamedCurves.cs index 4b7600e09..a9f60dd8c 100644 --- a/crypto/src/crypto/ec/CustomNamedCurves.cs +++ b/crypto/src/crypto/ec/CustomNamedCurves.cs @@ -11,6 +11,7 @@ using Org.BouncyCastle.Math.EC.Custom.Djb; using Org.BouncyCastle.Math.EC.Custom.GM; using Org.BouncyCastle.Math.EC.Custom.Sec; using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Encoders; @@ -23,9 +24,11 @@ namespace Org.BouncyCastle.Crypto.EC { } - private static BigInteger FromHex(string hex) + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) { - return new BigInteger(1, Hex.Decode(hex)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; } private static ECCurve ConfigureCurve(ECCurve curve) @@ -38,6 +41,11 @@ namespace Org.BouncyCastle.Crypto.EC return c.Configure().SetEndomorphism(new GlvTypeBEndomorphism(c, p)).Create(); } + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.Decode(hex)); + } + /* * curve25519 */ @@ -62,9 +70,8 @@ namespace Org.BouncyCastle.Crypto.EC * * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14) */ - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A" - + "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9")); + X9ECPoint G = ConfigureBasepoint(curve, + "042AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } @@ -84,9 +91,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("000E0D4D696E6768756151750CC03A4473D03679"); ECCurve curve = ConfigureCurve(new SecP128R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "161FF7528B899B2D0C28607CA52C5B86" - + "CF5AC8395BAFEB13C02DA292DDED7A83")); + X9ECPoint G = ConfigureBasepoint(curve, + "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -107,19 +113,19 @@ namespace Org.BouncyCastle.Crypto.EC GlvTypeBParameters glv = new GlvTypeBParameters( new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16), new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16), - new BigInteger[]{ - new BigInteger("9162fbe73984472a0a9e", 16), - new BigInteger("-96341f1138933bc2f505", 16) }, - new BigInteger[]{ - new BigInteger("127971af8721782ecffa3", 16), - new BigInteger("9162fbe73984472a0a9e", 16) }, - new BigInteger("9162fbe73984472a0a9d0590", 16), - new BigInteger("96341f1138933bc2f503fd44", 16), - 176); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("9162fbe73984472a0a9e", 16), + new BigInteger("-96341f1138933bc2f505", 16) }, + new BigInteger[]{ + new BigInteger("127971af8721782ecffa3", 16), + new BigInteger("9162fbe73984472a0a9e", 16) }, + new BigInteger("9162fbe73984472a0a9d0590", 16), + new BigInteger("96341f1138933bc2f503fd44", 16), + 176)); ECCurve curve = ConfigureCurveGlv(new SecP160K1Curve(), glv); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" - + "938CF935318FDCED6BC28286531733C3F03C4FEE")); + X9ECPoint G = ConfigureBasepoint(curve, + "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -138,9 +144,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("1053CDE42C14D696E67687561517533BF3F83345"); ECCurve curve = ConfigureCurve(new SecP160R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "4A96B5688EF573284664698968C38BB913CBFC82" - + "23A628553168947D59DCC912042351377AC5FB32")); + X9ECPoint G = ConfigureBasepoint(curve, + "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -159,9 +164,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("B99B99B099B323E02709A4D696E6768756151751"); ECCurve curve = ConfigureCurve(new SecP160R2Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "52DCB034293A117E1F4FF11B30F7199D3144CE6D" - + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E")); + X9ECPoint G = ConfigureBasepoint(curve, + "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -182,19 +186,19 @@ namespace Org.BouncyCastle.Crypto.EC GlvTypeBParameters glv = new GlvTypeBParameters( new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16), new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16), - new BigInteger[]{ - new BigInteger("71169be7330b3038edb025f1", 16), - new BigInteger("-b3fb3400dec5c4adceb8655c", 16) }, - new BigInteger[]{ - new BigInteger("12511cfe811d0f4e6bc688b4d", 16), - new BigInteger("71169be7330b3038edb025f1", 16) }, - new BigInteger("71169be7330b3038edb025f1d0f9", 16), - new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), - 208); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("71169be7330b3038edb025f1", 16), + new BigInteger("-b3fb3400dec5c4adceb8655c", 16) }, + new BigInteger[]{ + new BigInteger("12511cfe811d0f4e6bc688b4d", 16), + new BigInteger("71169be7330b3038edb025f1", 16) }, + new BigInteger("71169be7330b3038edb025f1d0f9", 16), + new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), + 208)); ECCurve curve = ConfigureCurveGlv(new SecP192K1Curve(), glv); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" - + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D")); + X9ECPoint G = ConfigureBasepoint(curve, + "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } } @@ -213,9 +217,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("3045AE6FC8422F64ED579528D38120EAE12196D5"); ECCurve curve = ConfigureCurve(new SecP192R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" - + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")); + X9ECPoint G = ConfigureBasepoint(curve, + "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } } @@ -236,19 +239,19 @@ namespace Org.BouncyCastle.Crypto.EC GlvTypeBParameters glv = new GlvTypeBParameters( new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16), new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16), - new BigInteger[]{ - new BigInteger("6b8cf07d4ca75c88957d9d670591", 16), - new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) }, - new BigInteger[]{ - new BigInteger("1243ae1b4d71613bc9f780a03690e", 16), - new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) }, - new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), - new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), - 240); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16), + new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) }, + new BigInteger[]{ + new BigInteger("1243ae1b4d71613bc9f780a03690e", 16), + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) }, + new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), + new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), + 240)); ECCurve curve = ConfigureCurveGlv(new SecP224K1Curve(), glv); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C" - + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5")); + X9ECPoint G = ConfigureBasepoint(curve, + "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } } @@ -267,9 +270,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); ECCurve curve = ConfigureCurve(new SecP224R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" - + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")); + X9ECPoint G = ConfigureBasepoint(curve, + "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } } @@ -290,19 +292,19 @@ namespace Org.BouncyCastle.Crypto.EC GlvTypeBParameters glv = new GlvTypeBParameters( new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16), new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16), - new BigInteger[]{ - new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16), - new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) }, - new BigInteger[]{ - new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16), - new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) }, - new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), - new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), - 272); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16), + new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) }, + new BigInteger[]{ + new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16), + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) }, + new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), + new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), + 272)); ECCurve curve = ConfigureCurveGlv(new SecP256K1Curve(), glv); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" - + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8")); + X9ECPoint G = ConfigureBasepoint(curve, + "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } } @@ -321,9 +323,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("C49D360886E704936A6678E1139D26B7819F7E90"); ECCurve curve = ConfigureCurve(new SecP256R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" - + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")); + X9ECPoint G = ConfigureBasepoint(curve, + "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } } @@ -342,9 +343,9 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("A335926AA319A27A1D00896A6773A4827ACDAC73"); ECCurve curve = ConfigureCurve(new SecP384R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + X9ECPoint G = ConfigureBasepoint(curve, "04" + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7" - + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")); + + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } } @@ -363,9 +364,9 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("D09E8800291CB85396CC6717393284AAA0DA64BA"); ECCurve curve = ConfigureCurve(new SecP521R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + X9ECPoint G = ConfigureBasepoint(curve, "04" + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" - + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650")); + + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } } @@ -384,9 +385,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("10E723AB14D696E6768756151756FEBF8FCB49A9"); ECCurve curve = ConfigureCurve(new SecT113R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "009D73616F35F4AB1407D73562C10F" - + "00A52830277958EE84D1315ED31886")); + X9ECPoint G = ConfigureBasepoint(curve, + "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -405,9 +405,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("10C0FB15760860DEF1EEF4D696E676875615175D"); ECCurve curve = ConfigureCurve(new SecT113R2Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "01A57A6A7B26CA5EF52FCDB8164797" - + "00B3ADC94ED1FE674C06E695BABA1D")); + X9ECPoint G = ConfigureBasepoint(curve, + "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -426,9 +425,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("4D696E676875615175985BD3ADBADA21B43A97E2"); ECCurve curve = ConfigureCurve(new SecT131R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "0081BAF91FDF9833C40F9C181343638399" - + "078C6E7EA38C001F73C8134B1B4EF9E150")); + X9ECPoint G = ConfigureBasepoint(curve, + "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -447,9 +445,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("985BD3ADBAD4D696E676875615175A21B43A97E3"); ECCurve curve = ConfigureCurve(new SecT131R2Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "0356DCD8F2F95031AD652D23951BB366A8" - + "0648F06D867940A5366D9E265DE9EB240F")); + X9ECPoint G = ConfigureBasepoint(curve, + "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -468,9 +465,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = null; ECCurve curve = ConfigureCurve(new SecT163K1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8" - + "0289070FB05D38FF58321F2E800536D538CCDAA3D9")); + X9ECPoint G = ConfigureBasepoint(curve, + "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -489,9 +485,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("24B7B137C8A14D696E6768756151756FD0DA2E5C"); ECCurve curve = ConfigureCurve(new SecT163R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "0369979697AB43897789566789567F787A7876A654" - + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883")); + X9ECPoint G = ConfigureBasepoint(curve, + "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -510,9 +505,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("85E25BFE5C86226CDB12016F7553F9D0E693A268"); ECCurve curve = ConfigureCurve(new SecT163R2Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "03F0EBA16286A2D57EA0991168D4994637E8343E36" - + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1")); + X9ECPoint G = ConfigureBasepoint(curve, + "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -531,9 +525,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("103FAEC74D696E676875615175777FC5B191EF30"); ECCurve curve = ConfigureCurve(new SecT193R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1" - + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05")); + X9ECPoint G = ConfigureBasepoint(curve, + "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -552,9 +545,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("10B7B4D696E676875615175137C8A16FD0DA2211"); ECCurve curve = ConfigureCurve(new SecT193R2Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F" - + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C")); + X9ECPoint G = ConfigureBasepoint(curve, + "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -573,9 +565,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = null; ECCurve curve = ConfigureCurve(new SecT233K1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126" - + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3")); + X9ECPoint G = ConfigureBasepoint(curve, + "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -594,9 +585,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3"); ECCurve curve = ConfigureCurve(new SecT233R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B" - + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052")); + X9ECPoint G = ConfigureBasepoint(curve, + "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -615,9 +605,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = null; ECCurve curve = ConfigureCurve(new SecT239K1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC" - + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA")); + X9ECPoint G = ConfigureBasepoint(curve, + "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -636,9 +625,9 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = null; ECCurve curve = ConfigureCurve(new SecT283K1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + X9ECPoint G = ConfigureBasepoint(curve, "04" + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836" - + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259")); + + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -657,9 +646,9 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE"); ECCurve curve = ConfigureCurve(new SecT283R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + X9ECPoint G = ConfigureBasepoint(curve, "04" + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053" - + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4")); + + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -678,9 +667,9 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = null; ECCurve curve = ConfigureCurve(new SecT409K1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + X9ECPoint G = ConfigureBasepoint(curve, "04" + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746" - + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B")); + + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -699,9 +688,9 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("4099B5A457F9D69F79213D094C4BCD4D4262210B"); ECCurve curve = ConfigureCurve(new SecT409R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + X9ECPoint G = ConfigureBasepoint(curve, "04" + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7" - + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706")); + + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -720,9 +709,9 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = null; ECCurve curve = ConfigureCurve(new SecT571K1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + X9ECPoint G = ConfigureBasepoint(curve, "04" + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972" - + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3")); + + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -741,9 +730,9 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = Hex.Decode("2AA058F73A0E33AB486B0F610410C53A7F132310"); ECCurve curve = ConfigureCurve(new SecT571R1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + X9ECPoint G = ConfigureBasepoint(curve, "04" + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19" - + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B")); + + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } }; @@ -762,9 +751,8 @@ namespace Org.BouncyCastle.Crypto.EC { byte[] S = null; ECCurve curve = ConfigureCurve(new SM2P256V1Curve()); - X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" - + "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7" - + "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0")); + X9ECPoint G = ConfigureBasepoint(curve, + "0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"); return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); } } diff --git a/crypto/src/crypto/engines/RSABlindedEngine.cs b/crypto/src/crypto/engines/RSABlindedEngine.cs index 7b928c5fb..98108f9b4 100644 --- a/crypto/src/crypto/engines/RSABlindedEngine.cs +++ b/crypto/src/crypto/engines/RSABlindedEngine.cs @@ -49,13 +49,29 @@ namespace Org.BouncyCastle.Crypto.Engines { ParametersWithRandom rParam = (ParametersWithRandom)param; - key = (RsaKeyParameters)rParam.Parameters; - random = rParam.Random; + this.key = (RsaKeyParameters)rParam.Parameters; + + if (key is RsaPrivateCrtKeyParameters) + { + this.random = rParam.Random; + } + else + { + this.random = null; + } } else { - key = (RsaKeyParameters)param; - random = new SecureRandom(); + this.key = (RsaKeyParameters)param; + + if (key is RsaPrivateCrtKeyParameters) + { + this.random = new SecureRandom(); + } + else + { + this.random = null; + } } } diff --git a/crypto/src/crypto/generators/SCrypt.cs b/crypto/src/crypto/generators/SCrypt.cs index 51dc50b81..9c204e786 100644 --- a/crypto/src/crypto/generators/SCrypt.cs +++ b/crypto/src/crypto/generators/SCrypt.cs @@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Crypto.Generators uint mask = (uint)N - 1; for (int i = 0; i < N; ++i) { - uint j = X[BCount - 16] & mask; + int j = (int)(X[BCount - 16] & mask); Array.Copy(V, j * BCount, blockY, 0, BCount); Xor(blockY, X, 0, blockY); BlockMix(blockY, blockX1, blockX2, X, r); diff --git a/crypto/src/crypto/parameters/MqvPrivateParameters.cs b/crypto/src/crypto/parameters/MqvPrivateParameters.cs index 9159cac12..37145715f 100644 --- a/crypto/src/crypto/parameters/MqvPrivateParameters.cs +++ b/crypto/src/crypto/parameters/MqvPrivateParameters.cs @@ -1,5 +1,8 @@ using System; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; + namespace Org.BouncyCastle.Crypto.Parameters { public class MqvPrivateParameters @@ -32,9 +35,9 @@ namespace Org.BouncyCastle.Crypto.Parameters if (ephemeralPublicKey == null) { - ephemeralPublicKey = new ECPublicKeyParameters( - parameters.G.Multiply(ephemeralPrivateKey.D), - parameters); + ECPoint q = new FixedPointCombMultiplier().Multiply(parameters.G, ephemeralPrivateKey.D); + + ephemeralPublicKey = new ECPublicKeyParameters(q, parameters); } else if (!parameters.Equals(ephemeralPublicKey.Parameters)) { diff --git a/crypto/src/crypto/parameters/SM2KeyExchangePrivateParameters.cs b/crypto/src/crypto/parameters/SM2KeyExchangePrivateParameters.cs index 8afb61544..666566426 100644 --- a/crypto/src/crypto/parameters/SM2KeyExchangePrivateParameters.cs +++ b/crypto/src/crypto/parameters/SM2KeyExchangePrivateParameters.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; namespace Org.BouncyCastle.Crypto.Parameters { @@ -29,11 +30,13 @@ namespace Org.BouncyCastle.Crypto.Parameters if (!parameters.Equals(ephemeralPrivateKey.Parameters)) throw new ArgumentException("Static and ephemeral private keys have different domain parameters"); + ECMultiplier m = new FixedPointCombMultiplier(); + this.mInitiator = initiator; this.mStaticPrivateKey = staticPrivateKey; - this.mStaticPublicPoint = parameters.G.Multiply(staticPrivateKey.D).Normalize(); + this.mStaticPublicPoint = m.Multiply(parameters.G, staticPrivateKey.D).Normalize(); this.mEphemeralPrivateKey = ephemeralPrivateKey; - this.mEphemeralPublicPoint = parameters.G.Multiply(ephemeralPrivateKey.D).Normalize(); + this.mEphemeralPublicPoint = m.Multiply(parameters.G, ephemeralPrivateKey.D).Normalize(); } public virtual bool IsInitiator diff --git a/crypto/src/crypto/signers/ECGOST3410Signer.cs b/crypto/src/crypto/signers/ECGOST3410Signer.cs index f08d16551..ac6b080a5 100644 --- a/crypto/src/crypto/signers/ECGOST3410Signer.cs +++ b/crypto/src/crypto/signers/ECGOST3410Signer.cs @@ -6,6 +6,7 @@ using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Signers { @@ -78,12 +79,7 @@ namespace Org.BouncyCastle.Crypto.Signers throw new InvalidOperationException("not initialized for signing"); } - byte[] mRev = new byte[message.Length]; // conversion is little-endian - for (int i = 0; i != mRev.Length; i++) - { - mRev[i] = message[mRev.Length - 1 - i]; - } - + byte[] mRev = Arrays.Reverse(message); // conversion is little-endian BigInteger e = new BigInteger(1, mRev); ECDomainParameters ec = key.Parameters; @@ -133,12 +129,7 @@ namespace Org.BouncyCastle.Crypto.Signers throw new InvalidOperationException("not initialized for verification"); } - byte[] mRev = new byte[message.Length]; // conversion is little-endian - for (int i = 0; i != mRev.Length; i++) - { - mRev[i] = message[mRev.Length - 1 - i]; - } - + byte[] mRev = Arrays.Reverse(message); // conversion is little-endian BigInteger e = new BigInteger(1, mRev); BigInteger n = key.Parameters.N; diff --git a/crypto/src/crypto/signers/GOST3410Signer.cs b/crypto/src/crypto/signers/GOST3410Signer.cs index c5f3bd5ef..bcc1125b1 100644 --- a/crypto/src/crypto/signers/GOST3410Signer.cs +++ b/crypto/src/crypto/signers/GOST3410Signer.cs @@ -3,6 +3,7 @@ using System; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Signers { @@ -67,12 +68,7 @@ namespace Org.BouncyCastle.Crypto.Signers public virtual BigInteger[] GenerateSignature( byte[] message) { - byte[] mRev = new byte[message.Length]; // conversion is little-endian - for (int i = 0; i != mRev.Length; i++) - { - mRev[i] = message[mRev.Length - 1 - i]; - } - + byte[] mRev = Arrays.Reverse(message); // conversion is little-endian BigInteger m = new BigInteger(1, mRev); Gost3410Parameters parameters = key.Parameters; BigInteger k; @@ -102,13 +98,8 @@ namespace Org.BouncyCastle.Crypto.Signers BigInteger r, BigInteger s) { - byte[] mRev = new byte[message.Length]; // conversion is little-endian - for (int i = 0; i != mRev.Length; i++) - { - mRev[i] = message[mRev.Length - 1 - i]; - } - - BigInteger m = new BigInteger(1, mRev); + byte[] mRev = Arrays.Reverse(message); // conversion is little-endian + BigInteger m = new BigInteger(1, mRev); Gost3410Parameters parameters = key.Parameters; if (r.SignValue < 0 || parameters.Q.CompareTo(r) <= 0) diff --git a/crypto/src/math/BigInteger.cs b/crypto/src/math/BigInteger.cs index 997f0bbea..3badb6d2c 100644 --- a/crypto/src/math/BigInteger.cs +++ b/crypto/src/math/BigInteger.cs @@ -249,7 +249,7 @@ namespace Org.BouncyCastle.Math return (nBits + BitsPerByte - 1) / BitsPerByte; } - internal static BigInteger Arbitrary(int sizeInBits) + public static BigInteger Arbitrary(int sizeInBits) { return new BigInteger(sizeInBits, RandomSource); } @@ -1332,6 +1332,17 @@ namespace Org.BouncyCastle.Math } } + public int IntValueExact + { + get + { + if (BitLength > 31) + throw new ArithmeticException("BigInteger out of int range"); + + return IntValue; + } + } + /** * return whether or not a BigInteger is probably prime with a * probability of 1 - (1/2)**certainty. @@ -1588,6 +1599,17 @@ namespace Org.BouncyCastle.Math } } + public long LongValueExact + { + get + { + if (BitLength > 63) + throw new ArithmeticException("BigInteger out of long range"); + + return LongValue; + } + } + public BigInteger Max( BigInteger value) { diff --git a/crypto/src/math/ec/AbstractECLookupTable.cs b/crypto/src/math/ec/AbstractECLookupTable.cs new file mode 100644 index 000000000..fbd272d0c --- /dev/null +++ b/crypto/src/math/ec/AbstractECLookupTable.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public abstract class AbstractECLookupTable + : ECLookupTable + { + public abstract ECPoint Lookup(int index); + public abstract int Size { get; } + + public virtual ECPoint LookupVar(int index) + { + return Lookup(index); + } + } +} diff --git a/crypto/src/math/ec/ECAlgorithms.cs b/crypto/src/math/ec/ECAlgorithms.cs index b05c0201a..4976b73b0 100644 --- a/crypto/src/math/ec/ECAlgorithms.cs +++ b/crypto/src/math/ec/ECAlgorithms.cs @@ -3,6 +3,7 @@ using System; using Org.BouncyCastle.Math.EC.Endo; using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Math.Field; +using Org.BouncyCastle.Math.Raw; namespace Org.BouncyCastle.Math.EC { @@ -265,46 +266,63 @@ namespace Org.BouncyCastle.Math.EC { bool negK = k.SignValue < 0, negL = l.SignValue < 0; - k = k.Abs(); - l = l.Abs(); + BigInteger kAbs = k.Abs(), lAbs = l.Abs(); + + int minWidthP = WNafUtilities.GetWindowSize(kAbs.BitLength, 8); + int minWidthQ = WNafUtilities.GetWindowSize(lAbs.BitLength, 8); - int widthP = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(k.BitLength))); - int widthQ = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(l.BitLength))); + WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidthP, true); + WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, minWidthQ, true); + + // When P, Q are 'promoted' (i.e. reused several times), switch to fixed-point algorithm + { + ECCurve c = P.Curve; + int combSize = FixedPointUtilities.GetCombSize(c); + if (!negK && !negL + && k.BitLength <= combSize && l.BitLength <= combSize + && infoP.IsPromoted && infoQ.IsPromoted) + { + return ImplShamirsTrickFixedPoint(P, k, Q, l); + } + } - WNafPreCompInfo infoP = WNafUtilities.Precompute(P, widthP, true); - WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, widthQ, true); + int widthP = System.Math.Min(8, infoP.Width); + int widthQ = System.Math.Min(8, infoQ.Width); ECPoint[] preCompP = negK ? infoP.PreCompNeg : infoP.PreComp; ECPoint[] preCompQ = negL ? infoQ.PreCompNeg : infoQ.PreComp; ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg; ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg; - byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, k); - byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, l); + byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, kAbs); + byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, lAbs); return ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ); } - internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, ECPointMap pointMapQ, BigInteger l) + internal static ECPoint ImplShamirsTrickWNaf(ECEndomorphism endomorphism, ECPoint P, BigInteger k, BigInteger l) { bool negK = k.SignValue < 0, negL = l.SignValue < 0; k = k.Abs(); l = l.Abs(); - int width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(System.Math.Max(k.BitLength, l.BitLength)))); + int minWidth = WNafUtilities.GetWindowSize(System.Math.Max(k.BitLength, l.BitLength), 8); + + WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidth, true); + ECPoint Q = EndoUtilities.MapPoint(endomorphism, P); + WNafPreCompInfo infoQ = WNafUtilities.PrecomputeWithPointMap(Q, endomorphism.PointMap, infoP, true); - ECPoint Q = WNafUtilities.MapPointWithPrecomp(P, width, true, pointMapQ); - WNafPreCompInfo infoP = WNafUtilities.GetWNafPreCompInfo(P); - WNafPreCompInfo infoQ = WNafUtilities.GetWNafPreCompInfo(Q); + int widthP = System.Math.Min(8, infoP.Width); + int widthQ = System.Math.Min(8, infoQ.Width); ECPoint[] preCompP = negK ? infoP.PreCompNeg : infoP.PreComp; ECPoint[] preCompQ = negL ? infoQ.PreCompNeg : infoQ.PreComp; ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg; ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg; - byte[] wnafP = WNafUtilities.GenerateWindowNaf(width, k); - byte[] wnafQ = WNafUtilities.GenerateWindowNaf(width, l); + byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, k); + byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, l); return ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ); } @@ -373,8 +391,12 @@ namespace Org.BouncyCastle.Math.EC { BigInteger ki = ks[i]; negs[i] = ki.SignValue < 0; ki = ki.Abs(); - int width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(ki.BitLength))); - infos[i] = WNafUtilities.Precompute(ps[i], width, true); + int minWidth = WNafUtilities.GetWindowSize(ki.BitLength, 8); + WNafPreCompInfo info = WNafUtilities.Precompute(ps[i], minWidth, true); + + int width = System.Math.Min(8, info.Width); + + infos[i] = info; wnafs[i] = WNafUtilities.GenerateWindowNaf(width, ki); } @@ -395,24 +417,24 @@ namespace Org.BouncyCastle.Math.EC abs[j++] = ab[1]; } - ECPointMap pointMap = glvEndomorphism.PointMap; if (glvEndomorphism.HasEfficientPointMap) { - return ECAlgorithms.ImplSumOfMultiplies(ps, pointMap, abs); + return ImplSumOfMultiplies(glvEndomorphism, ps, abs); } ECPoint[] pqs = new ECPoint[len << 1]; for (int i = 0, j = 0; i < len; ++i) { - ECPoint p = ps[i], q = pointMap.Map(p); + ECPoint p = ps[i]; + ECPoint q = EndoUtilities.MapPoint(glvEndomorphism, p); pqs[j++] = p; pqs[j++] = q; } - return ECAlgorithms.ImplSumOfMultiplies(pqs, abs); + return ImplSumOfMultiplies(pqs, abs); } - internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, ECPointMap pointMap, BigInteger[] ks) + internal static ECPoint ImplSumOfMultiplies(ECEndomorphism endomorphism, ECPoint[] ps, BigInteger[] ks) { int halfCount = ps.Length, fullCount = halfCount << 1; @@ -420,6 +442,8 @@ namespace Org.BouncyCastle.Math.EC WNafPreCompInfo[] infos = new WNafPreCompInfo[fullCount]; byte[][] wnafs = new byte[fullCount][]; + ECPointMap pointMap = endomorphism.PointMap; + for (int i = 0; i < halfCount; ++i) { int j0 = i << 1, j1 = j0 + 1; @@ -427,13 +451,20 @@ namespace Org.BouncyCastle.Math.EC BigInteger kj0 = ks[j0]; negs[j0] = kj0.SignValue < 0; kj0 = kj0.Abs(); BigInteger kj1 = ks[j1]; negs[j1] = kj1.SignValue < 0; kj1 = kj1.Abs(); - int width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(System.Math.Max(kj0.BitLength, kj1.BitLength)))); + int minWidth = WNafUtilities.GetWindowSize(System.Math.Max(kj0.BitLength, kj1.BitLength), 8); + + ECPoint P = ps[i]; + WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidth, true); + ECPoint Q = EndoUtilities.MapPoint(endomorphism, P); + WNafPreCompInfo infoQ = WNafUtilities.PrecomputeWithPointMap(Q, pointMap, infoP, true); + + int widthP = System.Math.Min(8, infoP.Width); + int widthQ = System.Math.Min(8, infoQ.Width); - ECPoint P = ps[i], Q = WNafUtilities.MapPointWithPrecomp(P, width, true, pointMap); - infos[j0] = WNafUtilities.GetWNafPreCompInfo(P); - infos[j1] = WNafUtilities.GetWNafPreCompInfo(Q); - wnafs[j0] = WNafUtilities.GenerateWindowNaf(width, kj0); - wnafs[j1] = WNafUtilities.GenerateWindowNaf(width, kj1); + infos[j0] = infoP; + infos[j1] = infoQ; + wnafs[j0] = WNafUtilities.GenerateWindowNaf(widthP, kj0); + wnafs[j1] = WNafUtilities.GenerateWindowNaf(widthQ, kj1); } return ImplSumOfMultiplies(negs, infos, wnafs); @@ -492,5 +523,78 @@ namespace Org.BouncyCastle.Math.EC return R; } + + private static ECPoint ImplShamirsTrickFixedPoint(ECPoint p, BigInteger k, ECPoint q, BigInteger l) + { + ECCurve c = p.Curve; + int combSize = FixedPointUtilities.GetCombSize(c); + + if (k.BitLength > combSize || l.BitLength > combSize) + { + /* + * TODO The comb works best when the scalars are less than the (possibly unknown) order. + * Still, if we want to handle larger scalars, we could allow customization of the comb + * size, or alternatively we could deal with the 'extra' bits either by running the comb + * multiple times as necessary, or by using an alternative multiplier as prelude. + */ + throw new InvalidOperationException("fixed-point comb doesn't support scalars larger than the curve order"); + } + + FixedPointPreCompInfo infoP = FixedPointUtilities.Precompute(p); + FixedPointPreCompInfo infoQ = FixedPointUtilities.Precompute(q); + + ECLookupTable lookupTableP = infoP.LookupTable; + ECLookupTable lookupTableQ = infoQ.LookupTable; + + int widthP = infoP.Width; + int widthQ = infoQ.Width; + + // TODO This shouldn't normally happen, but a better "solution" is desirable anyway + if (widthP != widthQ) + { + FixedPointCombMultiplier m = new FixedPointCombMultiplier(); + ECPoint r1 = m.Multiply(p, k); + ECPoint r2 = m.Multiply(q, l); + return r1.Add(r2); + } + + int width = widthP; + + int d = (combSize + width - 1) / width; + + ECPoint R = c.Infinity; + + int fullComb = d * width; + uint[] K = Nat.FromBigInteger(fullComb, k); + uint[] L = Nat.FromBigInteger(fullComb, l); + + int top = fullComb - 1; + for (int i = 0; i < d; ++i) + { + uint secretIndexK = 0, secretIndexL = 0; + + for (int j = top - i; j >= 0; j -= d) + { + uint secretBitK = K[j >> 5] >> (j & 0x1F); + secretIndexK ^= secretBitK >> 1; + secretIndexK <<= 1; + secretIndexK ^= secretBitK; + + uint secretBitL = L[j >> 5] >> (j & 0x1F); + secretIndexL ^= secretBitL >> 1; + secretIndexL <<= 1; + secretIndexL ^= secretBitL; + } + + ECPoint addP = lookupTableP.LookupVar((int)secretIndexK); + ECPoint addQ = lookupTableQ.LookupVar((int)secretIndexL); + + ECPoint T = addP.Add(addQ); + + R = R.TwicePlus(T); + } + + return R.Add(infoP.Offset).Add(infoQ.Offset); + } } } diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs index 993b69149..60fbc887a 100644 --- a/crypto/src/math/ec/ECCurve.cs +++ b/crypto/src/math/ec/ECCurve.cs @@ -521,7 +521,7 @@ namespace Org.BouncyCastle.Math.EC } private class DefaultLookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly ECCurve m_outer; private readonly byte[] m_table; @@ -534,12 +534,12 @@ namespace Org.BouncyCastle.Math.EC this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { int FE_BYTES = (m_outer.FieldSize + 7) / 8; byte[] x = new byte[FE_BYTES], y = new byte[FE_BYTES]; @@ -558,6 +558,26 @@ namespace Org.BouncyCastle.Math.EC pos += (FE_BYTES * 2); } + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + int FE_BYTES = (m_outer.FieldSize + 7) / 8; + byte[] x = new byte[FE_BYTES], y = new byte[FE_BYTES]; + int pos = index * FE_BYTES * 2; + + for (int j = 0; j < FE_BYTES; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + FE_BYTES + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(byte[] x, byte[] y) + { ECFieldElement X = m_outer.FromBigInteger(new BigInteger(1, x)); ECFieldElement Y = m_outer.FromBigInteger(new BigInteger(1, y)); return m_outer.CreateRawPoint(X, Y, false); @@ -862,12 +882,29 @@ namespace Org.BouncyCastle.Math.EC */ internal ECFieldElement SolveQuadraticEquation(ECFieldElement beta) { + AbstractF2mFieldElement betaF2m = (AbstractF2mFieldElement)beta; + + bool fastTrace = betaF2m.HasFastTrace; + if (fastTrace && 0 != betaF2m.Trace()) + return null; + + int m = FieldSize; + + // For odd m, use the half-trace + if (0 != (m & 1)) + { + ECFieldElement r = betaF2m.HalfTrace(); + if (fastTrace || r.Square().Add(r).Add(beta).IsZero) + return r; + + return null; + } + if (beta.IsZero) return beta; ECFieldElement gamma, z, zeroElement = FromBigInteger(BigInteger.Zero); - int m = FieldSize; do { ECFieldElement t = FromBigInteger(BigInteger.Arbitrary(m)); @@ -1234,7 +1271,7 @@ namespace Org.BouncyCastle.Math.EC } private class DefaultF2mLookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly F2mCurve m_outer; private readonly long[] m_table; @@ -1247,16 +1284,13 @@ namespace Org.BouncyCastle.Math.EC this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { - int m = m_outer.m; - int[] ks = m_outer.IsTrinomial() ? new int[]{ m_outer.k1 } : new int[]{ m_outer.k1, m_outer.k2, m_outer.k3 }; - int FE_LONGS = (m_outer.m + 63) / 64; long[] x = new long[FE_LONGS], y = new long[FE_LONGS]; int pos = 0; @@ -1274,6 +1308,29 @@ namespace Org.BouncyCastle.Math.EC pos += (FE_LONGS * 2); } + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + int FE_LONGS = (m_outer.m + 63) / 64; + long[] x = new long[FE_LONGS], y = new long[FE_LONGS]; + int pos = index * FE_LONGS * 2; + + for (int j = 0; j < FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(long[] x, long[] y) + { + int m = m_outer.m; + int[] ks = m_outer.IsTrinomial() ? new int[] { m_outer.k1 } : new int[] { m_outer.k1, m_outer.k2, m_outer.k3 }; + ECFieldElement X = new F2mFieldElement(m, ks, new LongArray(x)); ECFieldElement Y = new F2mFieldElement(m, ks, new LongArray(y)); return m_outer.CreateRawPoint(X, Y, false); diff --git a/crypto/src/math/ec/ECFieldElement.cs b/crypto/src/math/ec/ECFieldElement.cs index 350e8c6d4..ef10dbf90 100644 --- a/crypto/src/math/ec/ECFieldElement.cs +++ b/crypto/src/math/ec/ECFieldElement.cs @@ -550,32 +550,63 @@ namespace Org.BouncyCastle.Math.EC if ((m & 1) == 0) throw new InvalidOperationException("Half-trace only defined for odd m"); - ECFieldElement fe = this; - ECFieldElement ht = fe; - for (int i = 2; i < m; i += 2) + //ECFieldElement ht = this; + //for (int i = 1; i < m; i += 2) + //{ + // ht = ht.SquarePow(2).Add(this); + //} + + int n = (m + 1) >> 1; + int k = 31 - Integers.NumberOfLeadingZeros(n); + int nk = 1; + + ECFieldElement ht = this; + while (k > 0) { - fe = fe.SquarePow(2); - ht = ht.Add(fe); + ht = ht.SquarePow(nk << 1).Add(ht); + nk = n >> --k; + if (0 != (nk & 1)) + { + ht = ht.SquarePow(2).Add(this); + } } return ht; } + public virtual bool HasFastTrace + { + get { return false; } + } + public virtual int Trace() { int m = FieldSize; - ECFieldElement fe = this; - ECFieldElement tr = fe; - for (int i = 1; i < m; ++i) + + //ECFieldElement tr = this; + //for (int i = 1; i < m; ++i) + //{ + // tr = tr.Square().Add(this); + //} + + int k = 31 - Integers.NumberOfLeadingZeros(m); + int mk = 1; + + ECFieldElement tr = this; + while (k > 0) { - fe = fe.Square(); - tr = tr.Add(fe); + tr = tr.SquarePow(mk).Add(tr); + mk = m >> --k; + if (0 != (mk & 1)) + { + tr = tr.Square().Add(this); + } } + if (tr.IsZero) return 0; if (tr.IsOne) return 1; - throw new InvalidOperationException("Internal error in trace calculation"); } } diff --git a/crypto/src/math/ec/ECLookupTable.cs b/crypto/src/math/ec/ECLookupTable.cs index 35995d426..c14087d3b 100644 --- a/crypto/src/math/ec/ECLookupTable.cs +++ b/crypto/src/math/ec/ECLookupTable.cs @@ -6,5 +6,6 @@ namespace Org.BouncyCastle.Math.EC { int Size { get; } ECPoint Lookup(int index); + ECPoint LookupVar(int index); } } diff --git a/crypto/src/math/ec/ECPoint.cs b/crypto/src/math/ec/ECPoint.cs index 2acc9f5c0..6a7c3ecf0 100644 --- a/crypto/src/math/ec/ECPoint.cs +++ b/crypto/src/math/ec/ECPoint.cs @@ -306,6 +306,13 @@ namespace Org.BouncyCastle.Math.EC : Curve.CreateRawPoint(RawXCoord.Multiply(scale), RawYCoord, RawZCoords, IsCompressed); } + public virtual ECPoint ScaleXNegateY(ECFieldElement scale) + { + return IsInfinity + ? this + : Curve.CreateRawPoint(RawXCoord.Multiply(scale), RawYCoord.Negate(), RawZCoords, IsCompressed); + } + public virtual ECPoint ScaleY(ECFieldElement scale) { return IsInfinity @@ -313,6 +320,13 @@ namespace Org.BouncyCastle.Math.EC : Curve.CreateRawPoint(RawXCoord, RawYCoord.Multiply(scale), RawZCoords, IsCompressed); } + public virtual ECPoint ScaleYNegateX(ECFieldElement scale) + { + return IsInfinity + ? this + : Curve.CreateRawPoint(RawXCoord.Negate(), RawYCoord.Multiply(scale), RawZCoords, IsCompressed); + } + public override bool Equals(object obj) { return Equals(obj as ECPoint); @@ -1421,34 +1435,44 @@ namespace Org.BouncyCastle.Math.EC if (BigInteger.Two.Equals(cofactor)) { /* - * Check that the trace of (X + A) is 0, then there exists a solution to L^2 + L = X + A, - * and so a halving is possible, so this point is the double of another. + * Check that 0 == Tr(X + A); then there exists a solution to L^2 + L = X + A, and + * so a halving is possible, so this point is the double of another. + * + * Note: Tr(A) == 1 for cofactor 2 curves. */ ECPoint N = this.Normalize(); ECFieldElement X = N.AffineXCoord; - ECFieldElement rhs = X.Add(curve.A); - return ((AbstractF2mFieldElement)rhs).Trace() == 0; + return 0 != ((AbstractF2mFieldElement)X).Trace(); } if (BigInteger.ValueOf(4).Equals(cofactor)) { /* * Solve L^2 + L = X + A to find the half of this point, if it exists (fail if not). - * Generate both possibilities for the square of the half-point's x-coordinate (w), - * and check if Tr(w + A) == 0 for at least one; then a second halving is possible - * (see comments for cofactor 2 above), so this point is four times another. * - * Note: Tr(x^2) == Tr(x). + * Note: Tr(A) == 0 for cofactor 4 curves. */ ECPoint N = this.Normalize(); ECFieldElement X = N.AffineXCoord; - ECFieldElement lambda = ((AbstractF2mCurve)curve).SolveQuadraticEquation(X.Add(curve.A)); - if (lambda == null) + ECFieldElement L = ((AbstractF2mCurve)curve).SolveQuadraticEquation(X.Add(curve.A)); + if (null == L) return false; - ECFieldElement w = X.Multiply(lambda).Add(N.AffineYCoord); - ECFieldElement t = w.Add(curve.A); - return ((AbstractF2mFieldElement)t).Trace() == 0 - || ((AbstractF2mFieldElement)(t.Add(X))).Trace() == 0; + /* + * A solution exists, therefore 0 == Tr(X + A) == Tr(X). + */ + ECFieldElement Y = N.AffineYCoord; + ECFieldElement T = X.Multiply(L).Add(Y); + + /* + * Either T or (T + X) is the square of a half-point's x coordinate (hx). In either + * case, the half-point can be halved again when 0 == Tr(hx + A). + * + * Note: Tr(hx + A) == Tr(hx) == Tr(hx^2) == Tr(T) == Tr(T + X) + * + * Check that 0 == Tr(T); then there exists a solution to L^2 + L = hx + A, and so a + * second halving is possible and this point is four times some other. + */ + return 0 == ((AbstractF2mFieldElement)T).Trace(); } return base.SatisfiesOrder(); @@ -1490,6 +1514,11 @@ namespace Org.BouncyCastle.Math.EC } } + public override ECPoint ScaleXNegateY(ECFieldElement scale) + { + return ScaleX(scale); + } + public override ECPoint ScaleY(ECFieldElement scale) { if (this.IsInfinity) @@ -1514,6 +1543,11 @@ namespace Org.BouncyCastle.Math.EC } } + public override ECPoint ScaleYNegateX(ECFieldElement scale) + { + return ScaleY(scale); + } + public override ECPoint Subtract(ECPoint b) { if (b.IsInfinity) diff --git a/crypto/src/math/ec/ScaleXNegateYPointMap.cs b/crypto/src/math/ec/ScaleXNegateYPointMap.cs new file mode 100644 index 000000000..b0466a633 --- /dev/null +++ b/crypto/src/math/ec/ScaleXNegateYPointMap.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public class ScaleXNegateYPointMap + : ECPointMap + { + protected readonly ECFieldElement scale; + + public ScaleXNegateYPointMap(ECFieldElement scale) + { + this.scale = scale; + } + + public virtual ECPoint Map(ECPoint p) + { + return p.ScaleXNegateY(scale); + } + } +} diff --git a/crypto/src/math/ec/ScaleYNegateXPointMap.cs b/crypto/src/math/ec/ScaleYNegateXPointMap.cs new file mode 100644 index 000000000..6a7fed12e --- /dev/null +++ b/crypto/src/math/ec/ScaleYNegateXPointMap.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public class ScaleYNegateXPointMap + : ECPointMap + { + protected readonly ECFieldElement scale; + + public ScaleYNegateXPointMap(ECFieldElement scale) + { + this.scale = scale; + } + + public virtual ECPoint Map(ECPoint p) + { + return p.ScaleYNegateX(scale); + } + } +} diff --git a/crypto/src/math/ec/SimpleLookupTable.cs b/crypto/src/math/ec/SimpleLookupTable.cs index f1e32f215..ed300baaa 100644 --- a/crypto/src/math/ec/SimpleLookupTable.cs +++ b/crypto/src/math/ec/SimpleLookupTable.cs @@ -3,7 +3,7 @@ namespace Org.BouncyCastle.Math.EC { public class SimpleLookupTable - : ECLookupTable + : AbstractECLookupTable { private static ECPoint[] Copy(ECPoint[] points, int off, int len) { @@ -22,12 +22,17 @@ namespace Org.BouncyCastle.Math.EC this.points = Copy(points, off, len); } - public virtual int Size + public override int Size { get { return points.Length; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) + { + throw new NotSupportedException("Constant-time lookup not supported"); + } + + public override ECPoint LookupVar(int index) { return points[index]; } diff --git a/crypto/src/math/ec/custom/djb/Curve25519.cs b/crypto/src/math/ec/custom/djb/Curve25519.cs index c0f911a9c..190edf6ec 100644 --- a/crypto/src/math/ec/custom/djb/Curve25519.cs +++ b/crypto/src/math/ec/custom/djb/Curve25519.cs @@ -8,11 +8,15 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb internal class Curve25519 : AbstractFpCurve { - public static readonly BigInteger q = Nat256.ToBigInteger(Curve25519Field.P); + public static readonly BigInteger q = Curve25519FieldElement.Q; - private const int Curve25519_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; - private const int CURVE25519_FE_INTS = 8; + private static readonly BigInteger C_a = new BigInteger(1, Hex.Decode("2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144")); + private static readonly BigInteger C_b = new BigInteger(1, Hex.Decode("7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864")); + private const int CURVE25519_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; + private const int CURVE25519_FE_INTS = 8; + private static readonly ECFieldElement[] CURVE25519_AFFINE_ZS = new ECFieldElement[] { + new Curve25519FieldElement(BigInteger.One), new Curve25519FieldElement(C_a) }; protected readonly Curve25519Point m_infinity; public Curve25519() @@ -20,13 +24,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb { this.m_infinity = new Curve25519Point(this, null, null); - this.m_a = FromBigInteger(new BigInteger(1, - Hex.Decode("2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144"))); - this.m_b = FromBigInteger(new BigInteger(1, - Hex.Decode("7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864"))); + this.m_a = FromBigInteger(C_a); + this.m_b = FromBigInteger(C_b); this.m_order = new BigInteger(1, Hex.Decode("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED")); this.m_cofactor = BigInteger.ValueOf(8); - this.m_coord = Curve25519_DEFAULT_COORDS; + this.m_coord = CURVE25519_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -92,7 +94,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb } private class Curve25519LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly Curve25519 m_outer; private readonly uint[] m_table; @@ -105,12 +107,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat256.Create(), y = Nat256.Create(); int pos = 0; @@ -128,7 +130,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb pos += (CURVE25519_FE_INTS * 2); } - return m_outer.CreateRawPoint(new Curve25519FieldElement(x), new Curve25519FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = index * CURVE25519_FE_INTS * 2; + + for (int j = 0; j < CURVE25519_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + CURVE25519_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new Curve25519FieldElement(x), new Curve25519FieldElement(y), CURVE25519_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs b/crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs index 37256a550..5d82df547 100644 --- a/crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs +++ b/crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb internal class Curve25519FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = Curve25519.q; + public static readonly BigInteger Q = Nat256.ToBigInteger(Curve25519Field.P); // Calculated as ECConstants.TWO.modPow(Q.shiftRight(2), Q) private static readonly uint[] PRECOMP_POW2 = new uint[]{ 0x4a0ea0b0, 0xc4ee1b27, 0xad2fe478, 0x2f431806, diff --git a/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs b/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs index 2c5d8f3a3..4978a2beb 100644 --- a/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs +++ b/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.GM internal class SM2P256V1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF")); + public static readonly BigInteger q = SM2P256V1FieldElement.Q; private const int SM2P256V1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SM2P256V1_FE_INTS = 8; + private static readonly ECFieldElement[] SM2P256V1_AFFINE_ZS = new ECFieldElement[] { new SM2P256V1FieldElement(BigInteger.One) }; protected readonly SM2P256V1Point m_infinity; @@ -93,7 +93,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.GM } private class SM2P256V1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SM2P256V1Curve m_outer; private readonly uint[] m_table; @@ -106,12 +106,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.GM this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat256.Create(), y = Nat256.Create(); int pos = 0; @@ -129,7 +129,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.GM pos += (SM2P256V1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SM2P256V1FieldElement(x), new SM2P256V1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = index * SM2P256V1_FE_INTS * 2; + + for (int j = 0; j < SM2P256V1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SM2P256V1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SM2P256V1FieldElement(x), new SM2P256V1FieldElement(y), SM2P256V1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/gm/SM2P256V1FieldElement.cs b/crypto/src/math/ec/custom/gm/SM2P256V1FieldElement.cs index 087a040f2..a1f675f90 100644 --- a/crypto/src/math/ec/custom/gm/SM2P256V1FieldElement.cs +++ b/crypto/src/math/ec/custom/gm/SM2P256V1FieldElement.cs @@ -2,13 +2,15 @@ using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.GM { internal class SM2P256V1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SM2P256V1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs index cc50f50d2..58bff2390 100644 --- a/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP128R1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF")); + public static readonly BigInteger q = SecP128R1FieldElement.Q; private const int SECP128R1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP128R1_FE_INTS = 4; + private static readonly ECFieldElement[] SECP128R1_AFFINE_ZS = new ECFieldElement[] { new SecP128R1FieldElement(BigInteger.One) }; protected readonly SecP128R1Point m_infinity; @@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP128R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP128R1Curve m_outer; private readonly uint[] m_table; @@ -107,12 +107,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat128.Create(), y = Nat128.Create(); int pos = 0; @@ -130,7 +130,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP128R1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP128R1FieldElement(x), new SecP128R1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat128.Create(), y = Nat128.Create(); + int pos = index * SECP128R1_FE_INTS * 2; + + for (int j = 0; j < SECP128R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP128R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP128R1FieldElement(x), new SecP128R1FieldElement(y), SECP128R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP128R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP128R1FieldElement.cs index 5912a87e8..04f432ced 100644 --- a/crypto/src/math/ec/custom/sec/SecP128R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP128R1FieldElement.cs @@ -2,13 +2,15 @@ using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP128R1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP128R1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs index 234c86b87..1b5bbfe96 100644 --- a/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs @@ -8,10 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP160K1Curve : AbstractFpCurve { - public static readonly BigInteger q = SecP160R2Curve.q; + public static readonly BigInteger q = SecP160R2FieldElement.Q; private const int SECP160K1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP160K1_FE_INTS = 5; + private static readonly ECFieldElement[] SECP160K1_AFFINE_ZS = new ECFieldElement[] { new SecP160R2FieldElement(BigInteger.One) }; protected readonly SecP160K1Point m_infinity; @@ -90,7 +91,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP160K1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP160K1Curve m_outer; private readonly uint[] m_table; @@ -103,12 +104,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat256.Create(), y = Nat256.Create(); int pos = 0; @@ -126,7 +127,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP160K1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP160R2FieldElement(x), new SecP160R2FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = index * SECP160K1_FE_INTS * 2; + + for (int j = 0; j < SECP160K1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP160K1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP160R2FieldElement(x), new SecP160R2FieldElement(y), SECP160K1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs index 958eb2765..42f2f467b 100644 --- a/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP160R1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")); + public static readonly BigInteger q = SecP160R1FieldElement.Q; private const int SECP160R1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP160R1_FE_INTS = 5; + private static readonly ECFieldElement[] SECP160R1_AFFINE_ZS = new ECFieldElement[] { new SecP160R1FieldElement(BigInteger.One) }; protected readonly SecP160R1Point m_infinity; @@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP160R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP160R1Curve m_outer; private readonly uint[] m_table; @@ -107,12 +107,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat160.Create(), y = Nat160.Create(); int pos = 0; @@ -130,7 +130,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP160R1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP160R1FieldElement(x), new SecP160R1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat160.Create(), y = Nat160.Create(); + int pos = index * SECP160R1_FE_INTS * 2; + + for (int j = 0; j < SECP160R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP160R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP160R1FieldElement(x), new SecP160R1FieldElement(y), SECP160R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP160R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP160R1FieldElement.cs index 3ab11bdae..5365d7cd0 100644 --- a/crypto/src/math/ec/custom/sec/SecP160R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP160R1FieldElement.cs @@ -2,13 +2,15 @@ using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP160R1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP160R1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs b/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs index 252312e62..17f73d7ce 100644 --- a/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP160R2Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73")); + public static readonly BigInteger q = SecP160R2FieldElement.Q; private const int SECP160R2_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP160R2_FE_INTS = 5; + private static readonly ECFieldElement[] SECP160R2_AFFINE_ZS = new ECFieldElement[] { new SecP160R2FieldElement(BigInteger.One) }; protected readonly SecP160R2Point m_infinity; @@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP160R2LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP160R2Curve m_outer; private readonly uint[] m_table; @@ -107,12 +107,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat160.Create(), y = Nat160.Create(); int pos = 0; @@ -130,7 +130,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP160R2_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP160R2FieldElement(x), new SecP160R2FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat160.Create(), y = Nat160.Create(); + int pos = index * SECP160R2_FE_INTS * 2; + + for (int j = 0; j < SECP160R2_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP160R2_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP160R2FieldElement(x), new SecP160R2FieldElement(y), SECP160R2_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP160R2FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP160R2FieldElement.cs index 9d8131857..95d3c0b31 100644 --- a/crypto/src/math/ec/custom/sec/SecP160R2FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP160R2FieldElement.cs @@ -2,13 +2,15 @@ using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP160R2FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP160R2Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs index 518e0a131..6647ebab9 100644 --- a/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP192K1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37")); + public static readonly BigInteger q = SecP192K1FieldElement.Q; private const int SECP192K1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP192K1_FE_INTS = 6; + private static readonly ECFieldElement[] SECP192K1_AFFINE_ZS = new ECFieldElement[] { new SecP192K1FieldElement(BigInteger.One) }; protected readonly SecP192K1Point m_infinity; @@ -91,7 +91,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP192K1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP192K1Curve m_outer; private readonly uint[] m_table; @@ -104,12 +104,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat192.Create(), y = Nat192.Create(); int pos = 0; @@ -127,7 +127,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP192K1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP192K1FieldElement(x), new SecP192K1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat192.Create(), y = Nat192.Create(); + int pos = index * SECP192K1_FE_INTS * 2; + + for (int j = 0; j < SECP192K1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP192K1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP192K1FieldElement(x), new SecP192K1FieldElement(y), SECP192K1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP192K1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP192K1FieldElement.cs index 54b72573c..d3de532d9 100644 --- a/crypto/src/math/ec/custom/sec/SecP192K1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP192K1FieldElement.cs @@ -3,13 +3,15 @@ using System.Diagnostics; using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP192K1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP192K1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs index 91d31932a..a65afd0b0 100644 --- a/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP192R1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")); + public static readonly BigInteger q = SecP192R1FieldElement.Q; private const int SECP192R1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP192R1_FE_INTS = 6; + private static readonly ECFieldElement[] SECP192R1_AFFINE_ZS = new ECFieldElement[] { new SecP192R1FieldElement(BigInteger.One) }; protected readonly SecP192R1Point m_infinity; @@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP192R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP192R1Curve m_outer; private readonly uint[] m_table; @@ -107,12 +107,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat192.Create(), y = Nat192.Create(); int pos = 0; @@ -130,7 +130,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP192R1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP192R1FieldElement(x), new SecP192R1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat192.Create(), y = Nat192.Create(); + int pos = index * SECP192R1_FE_INTS * 2; + + for (int j = 0; j < SECP192R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP192R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP192R1FieldElement(x), new SecP192R1FieldElement(y), SECP192R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP192R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP192R1FieldElement.cs index f3e12b542..65a1aadb3 100644 --- a/crypto/src/math/ec/custom/sec/SecP192R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP192R1FieldElement.cs @@ -2,13 +2,15 @@ using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP192R1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP192R1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs index a9c55090f..ce56fbf52 100644 --- a/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP224K1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D")); + public static readonly BigInteger q = SecP224K1FieldElement.Q; private const int SECP224K1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP224K1_FE_INTS = 7; + private static readonly ECFieldElement[] SECP224K1_AFFINE_ZS = new ECFieldElement[] { new SecP224K1FieldElement(BigInteger.One) }; protected readonly SecP224K1Point m_infinity; @@ -91,7 +91,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP224K1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP224K1Curve m_outer; private readonly uint[] m_table; @@ -104,12 +104,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat224.Create(), y = Nat224.Create(); int pos = 0; @@ -127,7 +127,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP224K1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat224.Create(), y = Nat224.Create(); + int pos = index * SECP224K1_FE_INTS * 2; + + for (int j = 0; j < SECP224K1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP224K1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), SECP224K1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP224K1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP224K1FieldElement.cs index ef53a88d6..0614b7def 100644 --- a/crypto/src/math/ec/custom/sec/SecP224K1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP224K1FieldElement.cs @@ -3,13 +3,15 @@ using System.Diagnostics; using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP224K1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP224K1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D")); // Calculated as BigInteger.Two.ModPow(Q.ShiftRight(2), Q) private static readonly uint[] PRECOMP_POW2 = new uint[]{ 0x33bfd202, 0xdcfad133, 0x2287624a, 0xc3811ba8, diff --git a/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs index ec34390aa..a37fc282f 100644 --- a/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP224R1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")); + public static readonly BigInteger q = SecP224R1FieldElement.Q; private const int SECP224R1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP224R1_FE_INTS = 7; + private static readonly ECFieldElement[] SECP224R1_AFFINE_ZS = new ECFieldElement[] { new SecP224R1FieldElement(BigInteger.One) }; protected readonly SecP224R1Point m_infinity; @@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP224R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP224R1Curve m_outer; private readonly uint[] m_table; @@ -107,12 +107,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat224.Create(), y = Nat224.Create(); int pos = 0; @@ -130,7 +130,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP224R1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP224R1FieldElement(x), new SecP224R1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat224.Create(), y = Nat224.Create(); + int pos = index * SECP224R1_FE_INTS * 2; + + for (int j = 0; j < SECP224R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP224R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP224R1FieldElement(x), new SecP224R1FieldElement(y), SECP224R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs index 5780b7481..968bc0baa 100644 --- a/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP224R1FieldElement.cs @@ -2,13 +2,15 @@ using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP224R1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP224R1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs index b3a5dd646..26c788b5f 100644 --- a/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP256K1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")); + public static readonly BigInteger q = SecP256K1FieldElement.Q; private const int SECP256K1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP256K1_FE_INTS = 8; + private static readonly ECFieldElement[] SECP256K1_AFFINE_ZS = new ECFieldElement[] { new SecP256K1FieldElement(BigInteger.One) }; protected readonly SecP256K1Point m_infinity; @@ -91,7 +91,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP256K1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP256K1Curve m_outer; private readonly uint[] m_table; @@ -104,12 +104,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat256.Create(), y = Nat256.Create(); int pos = 0; @@ -127,7 +127,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP256K1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP256K1FieldElement(x), new SecP256K1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = index * SECP256K1_FE_INTS * 2; + + for (int j = 0; j < SECP256K1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP256K1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP256K1FieldElement(x), new SecP256K1FieldElement(y), SECP256K1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP256K1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP256K1FieldElement.cs index 9a604bdb7..d24f8d0df 100644 --- a/crypto/src/math/ec/custom/sec/SecP256K1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP256K1FieldElement.cs @@ -3,13 +3,15 @@ using System.Diagnostics; using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP256K1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP256K1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs index 2d9a88b72..504d7edc6 100644 --- a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP256R1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")); + public static readonly BigInteger q = SecP256R1FieldElement.Q; private const int SECP256R1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP256R1_FE_INTS = 8; + private static readonly ECFieldElement[] SECP256R1_AFFINE_ZS = new ECFieldElement[] { new SecP256R1FieldElement(BigInteger.One) }; protected readonly SecP256R1Point m_infinity; @@ -93,7 +93,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP256R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP256R1Curve m_outer; private readonly uint[] m_table; @@ -106,12 +106,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat256.Create(), y = Nat256.Create(); int pos = 0; @@ -129,7 +129,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP256R1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP256R1FieldElement(x), new SecP256R1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = index * SECP256R1_FE_INTS * 2; + + for (int j = 0; j < SECP256R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP256R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP256R1FieldElement(x), new SecP256R1FieldElement(y), SECP256R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP256R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP256R1FieldElement.cs index 808e99ea6..be4021485 100644 --- a/crypto/src/math/ec/custom/sec/SecP256R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP256R1FieldElement.cs @@ -2,13 +2,15 @@ using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP256R1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP256R1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs index 26b057198..5c6afc2e5 100644 --- a/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP384R1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")); + public static readonly BigInteger q = SecP384R1FieldElement.Q; private const int SECP384R1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP384R1_FE_INTS = 12; + private static readonly ECFieldElement[] SECP384R1_AFFINE_ZS = new ECFieldElement[] { new SecP384R1FieldElement(BigInteger.One) }; protected readonly SecP384R1Point m_infinity; @@ -93,7 +93,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP384R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP384R1Curve m_outer; private readonly uint[] m_table; @@ -106,12 +106,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat.Create(SECP384R1_FE_INTS), y = Nat.Create(SECP384R1_FE_INTS); int pos = 0; @@ -129,7 +129,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP384R1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP384R1FieldElement(x), new SecP384R1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat.Create(SECP384R1_FE_INTS), y = Nat.Create(SECP384R1_FE_INTS); + int pos = index * SECP384R1_FE_INTS * 2; + + for (int j = 0; j < SECP384R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP384R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP384R1FieldElement(x), new SecP384R1FieldElement(y), SECP384R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP384R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP384R1FieldElement.cs index 7eedccae6..9d3f51d87 100644 --- a/crypto/src/math/ec/custom/sec/SecP384R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP384R1FieldElement.cs @@ -2,13 +2,15 @@ using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP384R1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP384R1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs index 810be85b5..cca86e2cb 100644 --- a/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs @@ -8,11 +8,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecP521R1Curve : AbstractFpCurve { - public static readonly BigInteger q = new BigInteger(1, - Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")); + public static readonly BigInteger q = SecP521R1FieldElement.Q; private const int SECP521R1_DEFAULT_COORDS = COORD_JACOBIAN; private const int SECP521R1_FE_INTS = 17; + private static readonly ECFieldElement[] SECP521R1_AFFINE_ZS = new ECFieldElement[] { new SecP521R1FieldElement(BigInteger.One) }; protected readonly SecP521R1Point m_infinity; @@ -93,7 +93,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecP521R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecP521R1Curve m_outer; private readonly uint[] m_table; @@ -106,12 +106,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { uint[] x = Nat.Create(SECP521R1_FE_INTS), y = Nat.Create(SECP521R1_FE_INTS); int pos = 0; @@ -129,7 +129,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECP521R1_FE_INTS * 2); } - return m_outer.CreateRawPoint(new SecP521R1FieldElement(x), new SecP521R1FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat.Create(SECP521R1_FE_INTS), y = Nat.Create(SECP521R1_FE_INTS); + int pos = index * SECP521R1_FE_INTS * 2; + + for (int j = 0; j < SECP521R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP521R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP521R1FieldElement(x), new SecP521R1FieldElement(y), SECP521R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecP521R1FieldElement.cs b/crypto/src/math/ec/custom/sec/SecP521R1FieldElement.cs index 96658a8e5..a428a1243 100644 --- a/crypto/src/math/ec/custom/sec/SecP521R1FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecP521R1FieldElement.cs @@ -2,13 +2,15 @@ using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal class SecP521R1FieldElement : AbstractFpFieldElement { - public static readonly BigInteger Q = SecP521R1Curve.q; + public static readonly BigInteger Q = new BigInteger(1, + Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")); protected internal readonly uint[] x; diff --git a/crypto/src/math/ec/custom/sec/SecT113Field.cs b/crypto/src/math/ec/custom/sec/SecT113Field.cs index 49773b66d..3c9e0938d 100644 --- a/crypto/src/math/ec/custom/sec/SecT113Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT113Field.cs @@ -30,11 +30,30 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec z[1] = x[1]; } + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + } + public static ulong[] FromBigInteger(BigInteger x) { - ulong[] z = Nat128.FromBigInteger64(x); - Reduce15(z, 0); - return z; + return Nat.FromBigInteger64(113, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat128.CreateExt64(); + + Nat128.Copy64(x, z); + for (int i = 1; i < 113; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } } public static void Invert(ulong[] x, ulong[] z) diff --git a/crypto/src/math/ec/custom/sec/SecT113FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT113FieldElement.cs index bb87b00fc..63de2b88c 100644 --- a/crypto/src/math/ec/custom/sec/SecT113FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT113FieldElement.cs @@ -150,6 +150,18 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec return new SecT113FieldElement(z); } + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat128.Create64(); + SecT113Field.HalfTrace(x, z); + return new SecT113FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + public override int Trace() { return (int)SecT113Field.Trace(x); diff --git a/crypto/src/math/ec/custom/sec/SecT113R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT113R1Curve.cs index e85f68e60..ea9ea0b0c 100644 --- a/crypto/src/math/ec/custom/sec/SecT113R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT113R1Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT113R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT113R1_FE_LONGS = 2; + private static readonly ECFieldElement[] SECT113R1_AFFINE_ZS = new ECFieldElement[] { new SecT113FieldElement(BigInteger.One) }; protected readonly SecT113R1Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT113R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT113R1Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat128.Create64(), y = Nat128.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT113R1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT113FieldElement(x), new SecT113FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat128.Create64(), y = Nat128.Create64(); + int pos = index * SECT113R1_FE_LONGS * 2; + + for (int j = 0; j < SECT113R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT113R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT113FieldElement(x), new SecT113FieldElement(y), SECT113R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT113R2Curve.cs b/crypto/src/math/ec/custom/sec/SecT113R2Curve.cs index efe422806..84b20e026 100644 --- a/crypto/src/math/ec/custom/sec/SecT113R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT113R2Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT113R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT113R2_FE_LONGS = 2; + private static readonly ECFieldElement[] SECT113R2_AFFINE_ZS = new ECFieldElement[] { new SecT113FieldElement(BigInteger.One) }; protected readonly SecT113R2Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT113R2LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT113R2Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat128.Create64(), y = Nat128.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT113R2_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT113FieldElement(x), new SecT113FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat128.Create64(), y = Nat128.Create64(); + int pos = index * SECT113R2_FE_LONGS * 2; + + for (int j = 0; j < SECT113R2_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT113R2_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT113FieldElement(x), new SecT113FieldElement(y), SECT113R2_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT131Field.cs b/crypto/src/math/ec/custom/sec/SecT131Field.cs index 1b6697afe..db703d9e0 100644 --- a/crypto/src/math/ec/custom/sec/SecT131Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT131Field.cs @@ -35,11 +35,31 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec z[2] = x[2]; } + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + } + public static ulong[] FromBigInteger(BigInteger x) { - ulong[] z = Nat192.FromBigInteger64(x); - Reduce61(z, 0); - return z; + return Nat.FromBigInteger64(131, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(5); + + Nat192.Copy64(x, z); + for (int i = 1; i < 131; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } } public static void Invert(ulong[] x, ulong[] z) @@ -323,7 +343,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { Interleave.Expand64To128(x[0], zz, 0); Interleave.Expand64To128(x[1], zz, 2); - zz[4] = Interleave.Expand8to16((uint)x[2]); } } diff --git a/crypto/src/math/ec/custom/sec/SecT131FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT131FieldElement.cs index f96c7ca39..4884e7152 100644 --- a/crypto/src/math/ec/custom/sec/SecT131FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT131FieldElement.cs @@ -150,6 +150,18 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec return new SecT131FieldElement(z); } + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat192.Create64(); + SecT131Field.HalfTrace(x, z); + return new SecT131FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + public override int Trace() { return (int)SecT131Field.Trace(x); diff --git a/crypto/src/math/ec/custom/sec/SecT131R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT131R1Curve.cs index 06f0a79ae..1a8c01670 100644 --- a/crypto/src/math/ec/custom/sec/SecT131R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT131R1Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT131R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT131R1_FE_LONGS = 3; + private static readonly ECFieldElement[] SECT131R1_AFFINE_ZS = new ECFieldElement[] { new SecT131FieldElement(BigInteger.One) }; protected readonly SecT131R1Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT131R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT131R1Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat192.Create64(), y = Nat192.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT131R1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT131FieldElement(x), new SecT131FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = index * SECT131R1_FE_LONGS * 2; + + for (int j = 0; j < SECT131R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT131R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT131FieldElement(x), new SecT131FieldElement(y), SECT131R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT131R2Curve.cs b/crypto/src/math/ec/custom/sec/SecT131R2Curve.cs index 0120b3059..4a90a74f3 100644 --- a/crypto/src/math/ec/custom/sec/SecT131R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT131R2Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT131R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT131R2_FE_LONGS = 3; + private static readonly ECFieldElement[] SECT131R2_AFFINE_ZS = new ECFieldElement[] { new SecT131FieldElement(BigInteger.One) }; protected readonly SecT131R2Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT131R2LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT131R2Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat192.Create64(), y = Nat192.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT131R2_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT131FieldElement(x), new SecT131FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = index * SECT131R2_FE_LONGS * 2; + + for (int j = 0; j < SECT131R2_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT131R2_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT131FieldElement(x), new SecT131FieldElement(y), SECT131R2_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT163Field.cs b/crypto/src/math/ec/custom/sec/SecT163Field.cs index b1e9aa725..b7f60d860 100644 --- a/crypto/src/math/ec/custom/sec/SecT163Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT163Field.cs @@ -36,11 +36,31 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec z[2] = x[2]; } + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + } + public static ulong[] FromBigInteger(BigInteger x) { - ulong[] z = Nat192.FromBigInteger64(x); - Reduce29(z, 0); - return z; + return Nat.FromBigInteger64(163, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat192.CreateExt64(); + + Nat192.Copy64(x, z); + for (int i = 1; i < 163; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } } public static void Invert(ulong[] x, ulong[] z) @@ -331,10 +351,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { Interleave.Expand64To128(x[0], zz, 0); Interleave.Expand64To128(x[1], zz, 2); - - ulong x2 = x[2]; - zz[4] = Interleave.Expand32to64((uint)x2); - zz[5] = Interleave.Expand8to16((uint)(x2 >> 32)); + Interleave.Expand64To128(x[2], zz, 4); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT163FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT163FieldElement.cs index 903645999..214a56343 100644 --- a/crypto/src/math/ec/custom/sec/SecT163FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT163FieldElement.cs @@ -150,6 +150,18 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec return new SecT163FieldElement(z); } + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat192.Create64(); + SecT163Field.HalfTrace(x, z); + return new SecT163FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + public override int Trace() { return (int)SecT163Field.Trace(x); diff --git a/crypto/src/math/ec/custom/sec/SecT163K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT163K1Curve.cs index 5e1431f46..6cdb7bdd6 100644 --- a/crypto/src/math/ec/custom/sec/SecT163K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT163K1Curve.cs @@ -11,6 +11,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT163K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT163K1_FE_LONGS = 3; + private static readonly ECFieldElement[] SECT163K1_AFFINE_ZS = new ECFieldElement[] { new SecT163FieldElement(BigInteger.One) }; protected readonly SecT163K1Point m_infinity; @@ -120,7 +121,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT163K1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT163K1Curve m_outer; private readonly ulong[] m_table; @@ -133,12 +134,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat192.Create64(), y = Nat192.Create64(); int pos = 0; @@ -156,7 +157,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT163K1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = index * SECT163K1_FE_LONGS * 2; + + for (int j = 0; j < SECT163K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT163K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), SECT163K1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT163R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT163R1Curve.cs index e212ad4ea..bee0d3c80 100644 --- a/crypto/src/math/ec/custom/sec/SecT163R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT163R1Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT163R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT163R1_FE_LONGS = 3; + private static readonly ECFieldElement[] SECT163R1_AFFINE_ZS = new ECFieldElement[] { new SecT163FieldElement(BigInteger.One) }; protected readonly SecT163R1Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT163R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT163R1Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat192.Create64(), y = Nat192.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT163R1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = index * SECT163R1_FE_LONGS * 2; + + for (int j = 0; j < SECT163R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT163R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), SECT163R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT163R2Curve.cs b/crypto/src/math/ec/custom/sec/SecT163R2Curve.cs index b0365388a..35e91ddf1 100644 --- a/crypto/src/math/ec/custom/sec/SecT163R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT163R2Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT163R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT163R2_FE_LONGS = 3; + private static readonly ECFieldElement[] SECT163R2_AFFINE_ZS = new ECFieldElement[] { new SecT163FieldElement(BigInteger.One) }; protected readonly SecT163R2Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT163R2LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT163R2Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat192.Create64(), y = Nat192.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT163R2_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = index * SECT163R2_FE_LONGS * 2; + + for (int j = 0; j < SECT163R2_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT163R2_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), SECT163R2_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT193Field.cs b/crypto/src/math/ec/custom/sec/SecT193Field.cs index 41acb4f94..3ad9b0af2 100644 --- a/crypto/src/math/ec/custom/sec/SecT193Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT193Field.cs @@ -37,11 +37,32 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec z[3] = x[3]; } + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + z[3] ^= x[3]; + } + public static ulong[] FromBigInteger(BigInteger x) { - ulong[] z = Nat256.FromBigInteger64(x); - Reduce63(z, 0); - return z; + return Nat.FromBigInteger64(193, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + + Nat256.Copy64(x, z); + for (int i = 1; i < 193; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } } public static void Invert(ulong[] x, ulong[] z) diff --git a/crypto/src/math/ec/custom/sec/SecT193FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT193FieldElement.cs index 9813bcb01..3a3ed09ce 100644 --- a/crypto/src/math/ec/custom/sec/SecT193FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT193FieldElement.cs @@ -150,6 +150,18 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec return new SecT193FieldElement(z); } + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat256.Create64(); + SecT193Field.HalfTrace(x, z); + return new SecT193FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + public override int Trace() { return (int)SecT193Field.Trace(x); diff --git a/crypto/src/math/ec/custom/sec/SecT193R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT193R1Curve.cs index e6cb3b4d8..8ba83689e 100644 --- a/crypto/src/math/ec/custom/sec/SecT193R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT193R1Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT193R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT193R1_FE_LONGS = 4; + private static readonly ECFieldElement[] SECT193R1_AFFINE_ZS = new ECFieldElement[] { new SecT193FieldElement(BigInteger.One) }; protected readonly SecT193R1Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT193R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT193R1Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat256.Create64(), y = Nat256.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT193R1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT193FieldElement(x), new SecT193FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = index * SECT193R1_FE_LONGS * 2; + + for (int j = 0; j < SECT193R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT193R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT193FieldElement(x), new SecT193FieldElement(y), SECT193R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT193R2Curve.cs b/crypto/src/math/ec/custom/sec/SecT193R2Curve.cs index cfd690c65..46790e7e4 100644 --- a/crypto/src/math/ec/custom/sec/SecT193R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT193R2Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT193R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT193R2_FE_LONGS = 4; + private static readonly ECFieldElement[] SECT193R2_AFFINE_ZS = new ECFieldElement[] { new SecT193FieldElement(BigInteger.One) }; protected readonly SecT193R2Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT193R2LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT193R2Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat256.Create64(), y = Nat256.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT193R2_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT193FieldElement(x), new SecT193FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = index * SECT193R2_FE_LONGS * 2; + + for (int j = 0; j < SECT193R2_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT193R2_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT193FieldElement(x), new SecT193FieldElement(y), SECT193R2_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT233Field.cs b/crypto/src/math/ec/custom/sec/SecT233Field.cs index 870dade50..d7916c57d 100644 --- a/crypto/src/math/ec/custom/sec/SecT233Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT233Field.cs @@ -38,11 +38,32 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec z[3] = x[3]; } + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + z[3] ^= x[3]; + } + public static ulong[] FromBigInteger(BigInteger x) { - ulong[] z = Nat256.FromBigInteger64(x); - Reduce23(z, 0); - return z; + return Nat.FromBigInteger64(233, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + + Nat256.Copy64(x, z); + for (int i = 1; i < 233; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } } public static void Invert(ulong[] x, ulong[] z) @@ -308,10 +329,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Interleave.Expand64To128(x[0], zz, 0); Interleave.Expand64To128(x[1], zz, 2); Interleave.Expand64To128(x[2], zz, 4); - - ulong x3 = x[3]; - zz[6] = Interleave.Expand32to64((uint)x3); - zz[7] = Interleave.Expand16to32((uint)(x3 >> 32)); + Interleave.Expand64To128(x[3], zz, 6); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT233FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT233FieldElement.cs index fbfe35e13..8aff8c87a 100644 --- a/crypto/src/math/ec/custom/sec/SecT233FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT233FieldElement.cs @@ -150,6 +150,18 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec return new SecT233FieldElement(z); } + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat256.Create64(); + SecT233Field.HalfTrace(x, z); + return new SecT233FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + public override int Trace() { return (int)SecT233Field.Trace(x); diff --git a/crypto/src/math/ec/custom/sec/SecT233K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT233K1Curve.cs index 07eae1564..c01247446 100644 --- a/crypto/src/math/ec/custom/sec/SecT233K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT233K1Curve.cs @@ -11,6 +11,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT233K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT233K1_FE_LONGS = 4; + private static readonly ECFieldElement[] SECT233K1_AFFINE_ZS = new ECFieldElement[] { new SecT233FieldElement(BigInteger.One) }; protected readonly SecT233K1Point m_infinity; @@ -120,7 +121,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT233K1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT233K1Curve m_outer; private readonly ulong[] m_table; @@ -133,12 +134,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat256.Create64(), y = Nat256.Create64(); int pos = 0; @@ -156,7 +157,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT233K1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT233FieldElement(x), new SecT233FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = index * SECT233K1_FE_LONGS * 2; + + for (int j = 0; j < SECT233K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT233K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT233FieldElement(x), new SecT233FieldElement(y), SECT233K1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT233R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT233R1Curve.cs index 5e8dee875..a5d3b86fd 100644 --- a/crypto/src/math/ec/custom/sec/SecT233R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT233R1Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT233R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT233R1_FE_LONGS = 4; + private static readonly ECFieldElement[] SECT233R1_AFFINE_ZS = new ECFieldElement[] { new SecT233FieldElement(BigInteger.One) }; protected readonly SecT233R1Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT233R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT233R1Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat256.Create64(), y = Nat256.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT233R1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT233FieldElement(x), new SecT233FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = index * SECT233R1_FE_LONGS * 2; + + for (int j = 0; j < SECT233R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT233R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT233FieldElement(x), new SecT233FieldElement(y), SECT233R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT239Field.cs b/crypto/src/math/ec/custom/sec/SecT239Field.cs index 2e6ed2ad6..eab929359 100644 --- a/crypto/src/math/ec/custom/sec/SecT239Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT239Field.cs @@ -38,11 +38,32 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec z[3] = x[3]; } + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + z[3] ^= x[3]; + } + public static ulong[] FromBigInteger(BigInteger x) { - ulong[] z = Nat256.FromBigInteger64(x); - Reduce17(z, 0); - return z; + return Nat.FromBigInteger64(239, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + + Nat256.Copy64(x, z); + for (int i = 1; i < 239; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } } public static void Invert(ulong[] x, ulong[] z) @@ -319,10 +340,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Interleave.Expand64To128(x[0], zz, 0); Interleave.Expand64To128(x[1], zz, 2); Interleave.Expand64To128(x[2], zz, 4); - - ulong x3 = x[3]; - zz[6] = Interleave.Expand32to64((uint)x3); - zz[7] = Interleave.Expand16to32((uint)(x3 >> 32)); + Interleave.Expand64To128(x[3], zz, 6); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT239FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT239FieldElement.cs index b1b58e89b..9f1bf671c 100644 --- a/crypto/src/math/ec/custom/sec/SecT239FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT239FieldElement.cs @@ -150,6 +150,18 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec return new SecT239FieldElement(z); } + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat256.Create64(); + SecT239Field.HalfTrace(x, z); + return new SecT239FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + public override int Trace() { return (int)SecT239Field.Trace(x); diff --git a/crypto/src/math/ec/custom/sec/SecT239K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT239K1Curve.cs index 33792e631..5748942e2 100644 --- a/crypto/src/math/ec/custom/sec/SecT239K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT239K1Curve.cs @@ -11,6 +11,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT239K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT239K1_FE_LONGS = 4; + private static readonly ECFieldElement[] SECT239K1_AFFINE_ZS = new ECFieldElement[] { new SecT239FieldElement(BigInteger.One) }; protected readonly SecT239K1Point m_infinity; @@ -120,7 +121,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT239K1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT239K1Curve m_outer; private readonly ulong[] m_table; @@ -133,12 +134,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat256.Create64(), y = Nat256.Create64(); int pos = 0; @@ -156,7 +157,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT239K1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT239FieldElement(x), new SecT239FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = index * SECT239K1_FE_LONGS * 2; + + for (int j = 0; j < SECT239K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT239K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT239FieldElement(x), new SecT239FieldElement(y), SECT239K1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT283Field.cs b/crypto/src/math/ec/custom/sec/SecT283Field.cs index 22b7eaaab..4e2cee0f8 100644 --- a/crypto/src/math/ec/custom/sec/SecT283Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT283Field.cs @@ -43,11 +43,33 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec z[4] = x[4]; } + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + z[3] ^= x[3]; + z[4] ^= x[4]; + } + public static ulong[] FromBigInteger(BigInteger x) { - ulong[] z = Nat320.FromBigInteger64(x); - Reduce37(z, 0); - return z; + return Nat.FromBigInteger64(283, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(9); + + Nat320.Copy64(x, z); + for (int i = 1; i < 283; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } } public static void Invert(ulong[] x, ulong[] z) @@ -392,10 +414,10 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected static void ImplSquare(ulong[] x, ulong[] zz) { - for (int i = 0; i < 4; ++i) - { - Interleave.Expand64To128(x[i], zz, i << 1); - } + Interleave.Expand64To128(x[0], zz, 0); + Interleave.Expand64To128(x[1], zz, 2); + Interleave.Expand64To128(x[2], zz, 4); + Interleave.Expand64To128(x[3], zz, 6); zz[8] = Interleave.Expand32to64((uint)x[4]); } } diff --git a/crypto/src/math/ec/custom/sec/SecT283FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT283FieldElement.cs index c1bb2e30c..6bd720acd 100644 --- a/crypto/src/math/ec/custom/sec/SecT283FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT283FieldElement.cs @@ -150,6 +150,18 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec return new SecT283FieldElement(z); } + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat320.Create64(); + SecT283Field.HalfTrace(x, z); + return new SecT283FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + public override int Trace() { return (int)SecT283Field.Trace(x); diff --git a/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs index 51725bc20..e97a0f01d 100644 --- a/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs @@ -11,6 +11,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT283K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT283K1_FE_LONGS = 5; + private static readonly ECFieldElement[] SECT283K1_AFFINE_ZS = new ECFieldElement[] { new SecT283FieldElement(BigInteger.One) }; protected readonly SecT283K1Point m_infinity; @@ -120,7 +121,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT283K1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT283K1Curve m_outer; private readonly ulong[] m_table; @@ -133,12 +134,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat320.Create64(), y = Nat320.Create64(); int pos = 0; @@ -156,7 +157,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT283K1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT283FieldElement(x), new SecT283FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat320.Create64(), y = Nat320.Create64(); + int pos = index * SECT283K1_FE_LONGS * 2; + + for (int j = 0; j < SECT283K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT283K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT283FieldElement(x), new SecT283FieldElement(y), SECT283K1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT283R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT283R1Curve.cs index 567df7686..a8a50c22a 100644 --- a/crypto/src/math/ec/custom/sec/SecT283R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT283R1Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT283R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT283R1_FE_LONGS = 5; + private static readonly ECFieldElement[] SECT283R1_AFFINE_ZS = new ECFieldElement[] { new SecT283FieldElement(BigInteger.One) }; protected readonly SecT283R1Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT283R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT283R1Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat320.Create64(), y = Nat320.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT283R1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT283FieldElement(x), new SecT283FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat320.Create64(), y = Nat320.Create64(); + int pos = index * SECT283R1_FE_LONGS * 2; + + for (int j = 0; j < SECT283R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT283R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT283FieldElement(x), new SecT283FieldElement(y), SECT283R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT409Field.cs b/crypto/src/math/ec/custom/sec/SecT409Field.cs index 861b77aa1..2e5609542 100644 --- a/crypto/src/math/ec/custom/sec/SecT409Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT409Field.cs @@ -40,11 +40,35 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec z[6] = x[6]; } + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + z[3] ^= x[3]; + z[4] ^= x[4]; + z[5] ^= x[5]; + z[6] ^= x[6]; + } + public static ulong[] FromBigInteger(BigInteger x) { - ulong[] z = Nat448.FromBigInteger64(x); - Reduce39(z, 0); - return z; + return Nat.FromBigInteger64(409, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(13); + + Nat448.Copy64(x, z); + for (int i = 1; i < 409; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } } public static void Invert(ulong[] x, ulong[] z) @@ -321,10 +345,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected static void ImplSquare(ulong[] x, ulong[] zz) { - for (int i = 0; i < 6; ++i) - { - Interleave.Expand64To128(x[i], zz, i << 1); - } + Interleave.Expand64To128(x[0], zz, 0); + Interleave.Expand64To128(x[1], zz, 2); + Interleave.Expand64To128(x[2], zz, 4); + Interleave.Expand64To128(x[3], zz, 6); + Interleave.Expand64To128(x[4], zz, 8); + Interleave.Expand64To128(x[5], zz, 10); zz[12] = Interleave.Expand32to64((uint)x[6]); } } diff --git a/crypto/src/math/ec/custom/sec/SecT409FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT409FieldElement.cs index 68a63312d..a9b08526a 100644 --- a/crypto/src/math/ec/custom/sec/SecT409FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT409FieldElement.cs @@ -150,6 +150,18 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec return new SecT409FieldElement(z); } + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat448.Create64(); + SecT409Field.HalfTrace(x, z); + return new SecT409FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + public override int Trace() { return (int)SecT409Field.Trace(x); diff --git a/crypto/src/math/ec/custom/sec/SecT409K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT409K1Curve.cs index 839ec8059..2f6503692 100644 --- a/crypto/src/math/ec/custom/sec/SecT409K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT409K1Curve.cs @@ -11,6 +11,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT409K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT409K1_FE_LONGS = 7; + private static readonly ECFieldElement[] SECT409K1_AFFINE_ZS = new ECFieldElement[] { new SecT409FieldElement(BigInteger.One) }; protected readonly SecT409K1Point m_infinity; @@ -120,7 +121,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT409K1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT409K1Curve m_outer; private readonly ulong[] m_table; @@ -133,12 +134,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat448.Create64(), y = Nat448.Create64(); int pos = 0; @@ -156,7 +157,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT409K1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT409FieldElement(x), new SecT409FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat448.Create64(), y = Nat448.Create64(); + int pos = index * SECT409K1_FE_LONGS * 2; + + for (int j = 0; j < SECT409K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT409K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT409FieldElement(x), new SecT409FieldElement(y), SECT409K1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT409R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT409R1Curve.cs index f70dd5f8e..0e767504b 100644 --- a/crypto/src/math/ec/custom/sec/SecT409R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT409R1Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT409R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT409R1_FE_LONGS = 7; + private static readonly ECFieldElement[] SECT409R1_AFFINE_ZS = new ECFieldElement[] { new SecT409FieldElement(BigInteger.One) }; protected readonly SecT409R1Point m_infinity; @@ -114,7 +115,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT409R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT409R1Curve m_outer; private readonly ulong[] m_table; @@ -127,12 +128,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat448.Create64(), y = Nat448.Create64(); int pos = 0; @@ -150,7 +151,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT409R1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT409FieldElement(x), new SecT409FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat448.Create64(), y = Nat448.Create64(); + int pos = index * SECT409R1_FE_LONGS * 2; + + for (int j = 0; j < SECT409R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT409R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT409FieldElement(x), new SecT409FieldElement(y), SECT409R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT571Field.cs b/crypto/src/math/ec/custom/sec/SecT571Field.cs index 98f4f7fc2..0d9b337fc 100644 --- a/crypto/src/math/ec/custom/sec/SecT571Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT571Field.cs @@ -55,11 +55,32 @@ 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]; + } + } + public static ulong[] FromBigInteger(BigInteger x) { - ulong[] z = Nat576.FromBigInteger64(x); - Reduce5(z, 0); - return z; + return Nat.FromBigInteger64(571, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat576.CreateExt64(); + + Nat576.Copy64(x, z); + for (int i = 1; i < 571; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } } public static void Invert(ulong[] x, ulong[] z) @@ -324,10 +345,15 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected static void ImplSquare(ulong[] x, ulong[] zz) { - for (int i = 0; i < 9; ++i) - { - Interleave.Expand64To128(x[i], zz, i << 1); - } + Interleave.Expand64To128(x[0], zz, 0); + Interleave.Expand64To128(x[1], zz, 2); + Interleave.Expand64To128(x[2], zz, 4); + Interleave.Expand64To128(x[3], zz, 6); + Interleave.Expand64To128(x[4], zz, 8); + Interleave.Expand64To128(x[5], zz, 10); + Interleave.Expand64To128(x[6], zz, 12); + Interleave.Expand64To128(x[7], zz, 14); + Interleave.Expand64To128(x[8], zz, 16); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT571FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT571FieldElement.cs index c9f3aa5c0..22edfe0a2 100644 --- a/crypto/src/math/ec/custom/sec/SecT571FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT571FieldElement.cs @@ -150,6 +150,18 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec return new SecT571FieldElement(z); } + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat576.Create64(); + SecT571Field.HalfTrace(x, z); + return new SecT571FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + public override int Trace() { return (int)SecT571Field.Trace(x); diff --git a/crypto/src/math/ec/custom/sec/SecT571K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT571K1Curve.cs index 3d84797f7..1ab3b0941 100644 --- a/crypto/src/math/ec/custom/sec/SecT571K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT571K1Curve.cs @@ -11,6 +11,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT571K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT571K1_FE_LONGS = 9; + private static readonly ECFieldElement[] SECT571K1_AFFINE_ZS = new ECFieldElement[] { new SecT571FieldElement(BigInteger.One) }; protected readonly SecT571K1Point m_infinity; @@ -120,7 +121,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT571K1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT571K1Curve m_outer; private readonly ulong[] m_table; @@ -133,12 +134,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat576.Create64(), y = Nat576.Create64(); int pos = 0; @@ -156,7 +157,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT571K1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT571FieldElement(x), new SecT571FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat576.Create64(), y = Nat576.Create64(); + int pos = index * SECT571K1_FE_LONGS * 2; + + for (int j = 0; j < SECT571K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT571K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT571FieldElement(x), new SecT571FieldElement(y), SECT571K1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/custom/sec/SecT571R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT571R1Curve.cs index 7ebf90856..840c29638 100644 --- a/crypto/src/math/ec/custom/sec/SecT571R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT571R1Curve.cs @@ -10,6 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { private const int SECT571R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private const int SECT571R1_FE_LONGS = 9; + private static readonly ECFieldElement[] SECT571R1_AFFINE_ZS = new ECFieldElement[] { new SecT571FieldElement(BigInteger.One) }; protected readonly SecT571R1Point m_infinity; @@ -118,7 +119,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec } private class SecT571R1LookupTable - : ECLookupTable + : AbstractECLookupTable { private readonly SecT571R1Curve m_outer; private readonly ulong[] m_table; @@ -131,12 +132,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_size = size; } - public virtual int Size + public override int Size { get { return m_size; } } - public virtual ECPoint Lookup(int index) + public override ECPoint Lookup(int index) { ulong[] x = Nat576.Create64(), y = Nat576.Create64(); int pos = 0; @@ -154,7 +155,26 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec pos += (SECT571R1_FE_LONGS * 2); } - return m_outer.CreateRawPoint(new SecT571FieldElement(x), new SecT571FieldElement(y), false); + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat576.Create64(), y = Nat576.Create64(); + int pos = index * SECT571R1_FE_LONGS * 2; + + for (int j = 0; j < SECT571R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT571R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT571FieldElement(x), new SecT571FieldElement(y), SECT571R1_AFFINE_ZS, false); } } } diff --git a/crypto/src/math/ec/endo/EndoPreCompInfo.cs b/crypto/src/math/ec/endo/EndoPreCompInfo.cs new file mode 100644 index 000000000..cb926fc98 --- /dev/null +++ b/crypto/src/math/ec/endo/EndoPreCompInfo.cs @@ -0,0 +1,26 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class EndoPreCompInfo + : PreCompInfo + { + protected ECEndomorphism m_endomorphism; + + protected ECPoint m_mappedPoint; + + public virtual ECEndomorphism Endomorphism + { + get { return m_endomorphism; } + set { this.m_endomorphism = value; } + } + + public virtual ECPoint MappedPoint + { + get { return m_mappedPoint; } + set { this.m_mappedPoint = value; } + } + } +} diff --git a/crypto/src/math/ec/endo/EndoUtilities.cs b/crypto/src/math/ec/endo/EndoUtilities.cs new file mode 100644 index 000000000..843103bca --- /dev/null +++ b/crypto/src/math/ec/endo/EndoUtilities.cs @@ -0,0 +1,79 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public abstract class EndoUtilities + { + public static readonly string PRECOMP_NAME = "bc_endo"; + + public static BigInteger[] DecomposeScalar(ScalarSplitParameters p, BigInteger k) + { + int bits = p.Bits; + BigInteger b1 = CalculateB(k, p.G1, bits); + BigInteger b2 = CalculateB(k, p.G2, bits); + + BigInteger a = k.Subtract((b1.Multiply(p.V1A)).Add(b2.Multiply(p.V2A))); + BigInteger b = (b1.Multiply(p.V1B)).Add(b2.Multiply(p.V2B)).Negate(); + + return new BigInteger[]{ a, b }; + } + + public static ECPoint MapPoint(ECEndomorphism endomorphism, ECPoint p) + { + EndoPreCompInfo precomp = (EndoPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, + new MapPointCallback(endomorphism, p)); + return precomp.MappedPoint; + } + + private static BigInteger CalculateB(BigInteger k, BigInteger g, int t) + { + bool negative = (g.SignValue < 0); + BigInteger b = k.Multiply(g.Abs()); + bool extra = b.TestBit(t - 1); + b = b.ShiftRight(t); + if (extra) + { + b = b.Add(BigInteger.One); + } + return negative ? b.Negate() : b; + } + + private class MapPointCallback + : IPreCompCallback + { + private readonly ECEndomorphism m_endomorphism; + private readonly ECPoint m_point; + + internal MapPointCallback(ECEndomorphism endomorphism, ECPoint point) + { + this.m_endomorphism = endomorphism; + this.m_point = point; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + EndoPreCompInfo existingEndo = existing as EndoPreCompInfo; + + if (CheckExisting(existingEndo, m_endomorphism)) + return existingEndo; + + ECPoint mappedPoint = m_endomorphism.PointMap.Map(m_point); + + EndoPreCompInfo result = new EndoPreCompInfo(); + result.Endomorphism = m_endomorphism; + result.MappedPoint = mappedPoint; + return result; + } + + private bool CheckExisting(EndoPreCompInfo existingEndo, ECEndomorphism endomorphism) + { + return null != existingEndo + && existingEndo.Endomorphism == endomorphism + && existingEndo.MappedPoint != null; + } + + } + } +} diff --git a/crypto/src/math/ec/endo/GlvTypeAEndomorphism.cs b/crypto/src/math/ec/endo/GlvTypeAEndomorphism.cs new file mode 100644 index 000000000..fda8f154c --- /dev/null +++ b/crypto/src/math/ec/endo/GlvTypeAEndomorphism.cs @@ -0,0 +1,38 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class GlvTypeAEndomorphism + : GlvEndomorphism + { + protected readonly GlvTypeAParameters m_parameters; + protected readonly ECPointMap m_pointMap; + + public GlvTypeAEndomorphism(ECCurve curve, GlvTypeAParameters parameters) + { + /* + * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way + * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the + * endomorphism is being used with. + */ + + this.m_parameters = parameters; + this.m_pointMap = new ScaleYNegateXPointMap(curve.FromBigInteger(parameters.I)); + } + + public virtual BigInteger[] DecomposeScalar(BigInteger k) + { + return EndoUtilities.DecomposeScalar(m_parameters.SplitParams, k); + } + + public virtual ECPointMap PointMap + { + get { return m_pointMap; } + } + + public virtual bool HasEfficientPointMap + { + get { return true; } + } + } +} diff --git a/crypto/src/math/ec/endo/GlvTypeAParameters.cs b/crypto/src/math/ec/endo/GlvTypeAParameters.cs new file mode 100644 index 000000000..68464c530 --- /dev/null +++ b/crypto/src/math/ec/endo/GlvTypeAParameters.cs @@ -0,0 +1,32 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class GlvTypeAParameters + { + protected readonly BigInteger m_i, m_lambda; + protected readonly ScalarSplitParameters m_splitParams; + + public GlvTypeAParameters(BigInteger i, BigInteger lambda, ScalarSplitParameters splitParams) + { + this.m_i = i; + this.m_lambda = lambda; + this.m_splitParams = splitParams; + } + + public virtual BigInteger I + { + get { return m_i; } + } + + public virtual BigInteger Lambda + { + get { return m_lambda; } + } + + public virtual ScalarSplitParameters SplitParams + { + get { return m_splitParams; } + } + } +} diff --git a/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs b/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs index d234d88bf..e4f12fed9 100644 --- a/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs +++ b/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs @@ -5,28 +5,24 @@ namespace Org.BouncyCastle.Math.EC.Endo public class GlvTypeBEndomorphism : GlvEndomorphism { - protected readonly ECCurve m_curve; protected readonly GlvTypeBParameters m_parameters; protected readonly ECPointMap m_pointMap; public GlvTypeBEndomorphism(ECCurve curve, GlvTypeBParameters parameters) { - this.m_curve = curve; + /* + * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way + * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the + * endomorphism is being used with. + */ + this.m_parameters = parameters; this.m_pointMap = new ScaleXPointMap(curve.FromBigInteger(parameters.Beta)); } public virtual BigInteger[] DecomposeScalar(BigInteger k) { - int bits = m_parameters.Bits; - BigInteger b1 = CalculateB(k, m_parameters.G1, bits); - BigInteger b2 = CalculateB(k, m_parameters.G2, bits); - - BigInteger[] v1 = m_parameters.V1, v2 = m_parameters.V2; - BigInteger a = k.Subtract((b1.Multiply(v1[0])).Add(b2.Multiply(v2[0]))); - BigInteger b = (b1.Multiply(v1[1])).Add(b2.Multiply(v2[1])).Negate(); - - return new BigInteger[]{ a, b }; + return EndoUtilities.DecomposeScalar(m_parameters.SplitParams, k); } public virtual ECPointMap PointMap @@ -38,18 +34,5 @@ namespace Org.BouncyCastle.Math.EC.Endo { get { return true; } } - - protected virtual BigInteger CalculateB(BigInteger k, BigInteger g, int t) - { - bool negative = (g.SignValue < 0); - BigInteger b = k.Multiply(g.Abs()); - bool extra = b.TestBit(t - 1); - b = b.ShiftRight(t); - if (extra) - { - b = b.Add(BigInteger.One); - } - return negative ? b.Negate() : b; - } } } diff --git a/crypto/src/math/ec/endo/GlvTypeBParameters.cs b/crypto/src/math/ec/endo/GlvTypeBParameters.cs index f93dfaf2b..5e2937be8 100644 --- a/crypto/src/math/ec/endo/GlvTypeBParameters.cs +++ b/crypto/src/math/ec/endo/GlvTypeBParameters.cs @@ -4,22 +4,23 @@ namespace Org.BouncyCastle.Math.EC.Endo { public class GlvTypeBParameters { - protected readonly BigInteger m_beta; - protected readonly BigInteger m_lambda; - protected readonly BigInteger[] m_v1, m_v2; - protected readonly BigInteger m_g1, m_g2; - protected readonly int m_bits; + protected readonly BigInteger m_beta, m_lambda; + protected readonly ScalarSplitParameters m_splitParams; + [Obsolete("Use constructor taking a ScalarSplitParameters instead")] public GlvTypeBParameters(BigInteger beta, BigInteger lambda, BigInteger[] v1, BigInteger[] v2, BigInteger g1, BigInteger g2, int bits) { this.m_beta = beta; this.m_lambda = lambda; - this.m_v1 = v1; - this.m_v2 = v2; - this.m_g1 = g1; - this.m_g2 = g2; - this.m_bits = bits; + this.m_splitParams = new ScalarSplitParameters(v1, v2, g1, g2, bits); + } + + public GlvTypeBParameters(BigInteger beta, BigInteger lambda, ScalarSplitParameters splitParams) + { + this.m_beta = beta; + this.m_lambda = lambda; + this.m_splitParams = splitParams; } public virtual BigInteger Beta @@ -32,29 +33,39 @@ namespace Org.BouncyCastle.Math.EC.Endo get { return m_lambda; } } + public virtual ScalarSplitParameters SplitParams + { + get { return m_splitParams; } + } + + [Obsolete("Access via SplitParams instead")] public virtual BigInteger[] V1 { - get { return m_v1; } + get { return new BigInteger[] { m_splitParams.V1A, m_splitParams.V1B }; } } + [Obsolete("Access via SplitParams instead")] public virtual BigInteger[] V2 { - get { return m_v2; } + get { return new BigInteger[] { m_splitParams.V2A, m_splitParams.V2B }; } } + [Obsolete("Access via SplitParams instead")] public virtual BigInteger G1 { - get { return m_g1; } + get { return m_splitParams.G1; } } + [Obsolete("Access via SplitParams instead")] public virtual BigInteger G2 { - get { return m_g2; } + get { return m_splitParams.G2; } } + [Obsolete("Access via SplitParams instead")] public virtual int Bits { - get { return m_bits; } + get { return m_splitParams.Bits; } } } } diff --git a/crypto/src/math/ec/endo/ScalarSplitParameters.cs b/crypto/src/math/ec/endo/ScalarSplitParameters.cs new file mode 100644 index 000000000..18d0bdb9e --- /dev/null +++ b/crypto/src/math/ec/endo/ScalarSplitParameters.cs @@ -0,0 +1,69 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class ScalarSplitParameters + { + private static void CheckVector(BigInteger[] v, string name) + { + if (v == null || v.Length != 2 || v[0] == null || v[1] == null) + throw new ArgumentException("Must consist of exactly 2 (non-null) values", name); + } + + protected readonly BigInteger m_v1A, m_v1B, m_v2A, m_v2B; + protected readonly BigInteger m_g1, m_g2; + protected readonly int m_bits; + + public ScalarSplitParameters(BigInteger[] v1, BigInteger[] v2, BigInteger g1, + BigInteger g2, int bits) + { + CheckVector(v1, "v1"); + CheckVector(v2, "v2"); + + this.m_v1A = v1[0]; + this.m_v1B = v1[1]; + this.m_v2A = v2[0]; + this.m_v2B = v2[1]; + this.m_g1 = g1; + this.m_g2 = g2; + this.m_bits = bits; + } + + public virtual BigInteger V1A + { + get { return m_v1A; } + } + + public virtual BigInteger V1B + { + get { return m_v1B; } + } + + public virtual BigInteger V2A + { + get { return m_v2A; } + } + + public virtual BigInteger V2B + { + get { return m_v2B; } + } + + public virtual BigInteger G1 + { + get { return m_g1; } + } + + public virtual BigInteger G2 + { + get { return m_g2; } + } + + public virtual int Bits + { + get { return m_bits; } + } + } +} diff --git a/crypto/src/math/ec/multiplier/GlvMultiplier.cs b/crypto/src/math/ec/multiplier/GlvMultiplier.cs index f19049474..9ef7d6e24 100644 --- a/crypto/src/math/ec/multiplier/GlvMultiplier.cs +++ b/crypto/src/math/ec/multiplier/GlvMultiplier.cs @@ -28,13 +28,14 @@ namespace Org.BouncyCastle.Math.EC.Multiplier BigInteger[] ab = glvEndomorphism.DecomposeScalar(k.Mod(n)); BigInteger a = ab[0], b = ab[1]; - ECPointMap pointMap = glvEndomorphism.PointMap; if (glvEndomorphism.HasEfficientPointMap) { - return ECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap, b); + return ECAlgorithms.ImplShamirsTrickWNaf(glvEndomorphism, p, a, b); } - return ECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap.Map(p), b); + ECPoint q = EndoUtilities.MapPoint(glvEndomorphism, p); + + return ECAlgorithms.ImplShamirsTrickWNaf(p, a, q, b); } } } diff --git a/crypto/src/math/ec/multiplier/WNafL2RMultiplier.cs b/crypto/src/math/ec/multiplier/WNafL2RMultiplier.cs index f671f6a5c..833bbb5ea 100644 --- a/crypto/src/math/ec/multiplier/WNafL2RMultiplier.cs +++ b/crypto/src/math/ec/multiplier/WNafL2RMultiplier.cs @@ -1,5 +1,7 @@ using System; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Math.EC.Multiplier { /** @@ -18,12 +20,12 @@ namespace Org.BouncyCastle.Math.EC.Multiplier */ protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { - // Clamp the window width in the range [2, 16] - int width = System.Math.Max(2, System.Math.Min(16, GetWindowSize(k.BitLength))); + int minWidth = WNafUtilities.GetWindowSize(k.BitLength); - WNafPreCompInfo wnafPreCompInfo = WNafUtilities.Precompute(p, width, true); - ECPoint[] preComp = wnafPreCompInfo.PreComp; - ECPoint[] preCompNeg = wnafPreCompInfo.PreCompNeg; + WNafPreCompInfo info = WNafUtilities.Precompute(p, minWidth, true); + ECPoint[] preComp = info.PreComp; + ECPoint[] preCompNeg = info.PreCompNeg; + int width = info.Width; int[] wnaf = WNafUtilities.GenerateCompactWindowNaf(width, k); @@ -46,7 +48,7 @@ namespace Org.BouncyCastle.Math.EC.Multiplier // Optimization can only be used for values in the lower half of the table if ((n << 2) < (1 << width)) { - int highest = LongArray.BitLengths[n]; + int highest = 32 - Integers.NumberOfLeadingZeros(n); // TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting? int scale = width - highest; @@ -83,16 +85,5 @@ namespace Org.BouncyCastle.Math.EC.Multiplier return R; } - - /** - * Determine window width to use for a scalar multiplication of the given size. - * - * @param bits the bit-length of the scalar to multiply by - * @return the window size to use - */ - protected virtual int GetWindowSize(int bits) - { - return WNafUtilities.GetWindowSize(bits); - } } } diff --git a/crypto/src/math/ec/multiplier/WNafPreCompInfo.cs b/crypto/src/math/ec/multiplier/WNafPreCompInfo.cs index 7e0a73154..f979f33d9 100644 --- a/crypto/src/math/ec/multiplier/WNafPreCompInfo.cs +++ b/crypto/src/math/ec/multiplier/WNafPreCompInfo.cs @@ -5,8 +5,12 @@ namespace Org.BouncyCastle.Math.EC.Multiplier * algorithm. */ public class WNafPreCompInfo - : PreCompInfo + : PreCompInfo { + internal volatile int m_promotionCountdown = 4; + + protected int m_confWidth = -1; + /** * Array holding the precomputed <code>ECPoint</code>s used for a Window * NAF multiplication. @@ -25,6 +29,35 @@ namespace Org.BouncyCastle.Math.EC.Multiplier */ protected ECPoint m_twice = null; + protected int m_width = -1; + + internal int DecrementPromotionCountdown() + { + int t = m_promotionCountdown; + if (t > 0) + { + m_promotionCountdown = --t; + } + return t; + } + + internal int PromotionCountdown + { + get { return m_promotionCountdown; } + set { this.m_promotionCountdown = value; } + } + + public virtual bool IsPromoted + { + get { return m_promotionCountdown <= 0; } + } + + public virtual int ConfWidth + { + get { return m_confWidth; } + set { this.m_confWidth = value; } + } + public virtual ECPoint[] PreComp { get { return m_preComp; } @@ -42,5 +75,11 @@ namespace Org.BouncyCastle.Math.EC.Multiplier get { return m_twice; } set { this.m_twice = value; } } + + public virtual int Width + { + get { return m_width; } + set { this.m_width = value; } + } } } diff --git a/crypto/src/math/ec/multiplier/WNafUtilities.cs b/crypto/src/math/ec/multiplier/WNafUtilities.cs index 24646deb2..42265b2d6 100644 --- a/crypto/src/math/ec/multiplier/WNafUtilities.cs +++ b/crypto/src/math/ec/multiplier/WNafUtilities.cs @@ -9,9 +9,23 @@ namespace Org.BouncyCastle.Math.EC.Multiplier public static readonly string PRECOMP_NAME = "bc_wnaf"; private static readonly int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{ 13, 41, 121, 337, 897, 2305 }; + private static readonly int MAX_WIDTH = 16; private static readonly ECPoint[] EMPTY_POINTS = new ECPoint[0]; + public static void ConfigureBasepoint(ECPoint p) + { + ECCurve c = p.Curve; + if (null == c) + return; + + BigInteger n = c.Order; + int bits = (null == n) ? c.FieldSize + 1 : n.BitLength; + int confWidth = System.Math.Min(MAX_WIDTH, GetWindowSize(bits) + 3); + + c.Precompute(p, PRECOMP_NAME, new ConfigureBasepointCallback(c, confWidth)); + } + public static int[] GenerateCompactNaf(BigInteger k) { if ((k.BitLength >> 16) != 0) @@ -298,7 +312,19 @@ namespace Org.BouncyCastle.Math.EC.Multiplier */ public static int GetWindowSize(int bits) { - return GetWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS); + return GetWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, MAX_WIDTH); + } + + /** + * Determine window width to use for a scalar multiplication of the given size. + * + * @param bits the bit-length of the scalar to multiply by + * @param maxWidth the maximum window width to return + * @return the window size to use + */ + public static int GetWindowSize(int bits, int maxWidth) + { + return GetWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, maxWidth); } /** @@ -310,6 +336,19 @@ namespace Org.BouncyCastle.Math.EC.Multiplier */ public static int GetWindowSize(int bits, int[] windowSizeCutoffs) { + return GetWindowSize(bits, windowSizeCutoffs, MAX_WIDTH); + } + + /** + * Determine window width to use for a scalar multiplication of the given size. + * + * @param bits the bit-length of the scalar to multiply by + * @param windowSizeCutoffs a monotonically increasing list of bit sizes at which to increment the window width + * @param maxWidth the maximum window width to return + * @return the window size to use + */ + public static int GetWindowSize(int bits, int[] windowSizeCutoffs, int maxWidth) + { int w = 0; for (; w < windowSizeCutoffs.Length; ++w) { @@ -318,23 +357,33 @@ namespace Org.BouncyCastle.Math.EC.Multiplier break; } } - return w + 2; + + return System.Math.Max(2, System.Math.Min(maxWidth, w + 2)); } - public static ECPoint MapPointWithPrecomp(ECPoint p, int width, bool includeNegated, + [Obsolete] + public static ECPoint MapPointWithPrecomp(ECPoint p, int minWidth, bool includeNegated, ECPointMap pointMap) { ECCurve c = p.Curve; - WNafPreCompInfo wnafPreCompP = Precompute(p, width, includeNegated); + WNafPreCompInfo infoP = Precompute(p, minWidth, includeNegated); ECPoint q = pointMap.Map(p); - c.Precompute(q, PRECOMP_NAME, new MapPointCallback(wnafPreCompP, includeNegated, pointMap)); + c.Precompute(q, PRECOMP_NAME, new MapPointCallback(infoP, includeNegated, pointMap)); return q; } - public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated) + public static WNafPreCompInfo Precompute(ECPoint p, int minWidth, bool includeNegated) { - return (WNafPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, new WNafCallback(p, width, includeNegated)); + return (WNafPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, + new PrecomputeCallback(p, minWidth, includeNegated)); + } + + public static WNafPreCompInfo PrecomputeWithPointMap(ECPoint p, ECPointMap pointMap, WNafPreCompInfo fromWNaf, + bool includeNegated) + { + return (WNafPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, + new PrecomputeWithPointMapCallback(p, pointMap, fromWNaf, includeNegated)); } private static byte[] Trim(byte[] a, int length) @@ -358,16 +407,55 @@ namespace Org.BouncyCastle.Math.EC.Multiplier return result; } + private class ConfigureBasepointCallback + : IPreCompCallback + { + private readonly ECCurve m_curve; + private readonly int m_confWidth; + + internal ConfigureBasepointCallback(ECCurve curve, int confWidth) + { + this.m_curve = curve; + this.m_confWidth = confWidth; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo; + + if (null != existingWNaf && existingWNaf.ConfWidth == m_confWidth) + { + existingWNaf.PromotionCountdown = 0; + return existingWNaf; + } + + WNafPreCompInfo result = new WNafPreCompInfo(); + + result.PromotionCountdown = 0; + result.ConfWidth = m_confWidth; + + if (null != existingWNaf) + { + result.PreComp = existingWNaf.PreComp; + result.PreCompNeg = existingWNaf.PreCompNeg; + result.Twice = existingWNaf.Twice; + result.Width = existingWNaf.Width; + } + + return result; + } + } + private class MapPointCallback : IPreCompCallback { - private readonly WNafPreCompInfo m_wnafPreCompP; + private readonly WNafPreCompInfo m_infoP; private readonly bool m_includeNegated; private readonly ECPointMap m_pointMap; - internal MapPointCallback(WNafPreCompInfo wnafPreCompP, bool includeNegated, ECPointMap pointMap) + internal MapPointCallback(WNafPreCompInfo infoP, bool includeNegated, ECPointMap pointMap) { - this.m_wnafPreCompP = wnafPreCompP; + this.m_infoP = infoP; this.m_includeNegated = includeNegated; this.m_pointMap = pointMap; } @@ -376,20 +464,23 @@ namespace Org.BouncyCastle.Math.EC.Multiplier { WNafPreCompInfo result = new WNafPreCompInfo(); - ECPoint twiceP = m_wnafPreCompP.Twice; - if (twiceP != null) + result.ConfWidth = m_infoP.ConfWidth; + + ECPoint twiceP = m_infoP.Twice; + if (null != twiceP) { ECPoint twiceQ = m_pointMap.Map(twiceP); result.Twice = twiceQ; } - ECPoint[] preCompP = m_wnafPreCompP.PreComp; + ECPoint[] preCompP = m_infoP.PreComp; ECPoint[] preCompQ = new ECPoint[preCompP.Length]; for (int i = 0; i < preCompP.Length; ++i) { preCompQ[i] = m_pointMap.Map(preCompP[i]); } result.PreComp = preCompQ; + result.Width = m_infoP.Width; if (m_includeNegated) { @@ -405,17 +496,17 @@ namespace Org.BouncyCastle.Math.EC.Multiplier } } - private class WNafCallback + private class PrecomputeCallback : IPreCompCallback { private readonly ECPoint m_p; - private readonly int m_width; + private readonly int m_minWidth; private readonly bool m_includeNegated; - internal WNafCallback(ECPoint p, int width, bool includeNegated) + internal PrecomputeCallback(ECPoint p, int minWidth, bool includeNegated) { this.m_p = p; - this.m_width = width; + this.m_minWidth = minWidth; this.m_includeNegated = includeNegated; } @@ -423,24 +514,39 @@ namespace Org.BouncyCastle.Math.EC.Multiplier { WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo; - int reqPreCompLen = 1 << System.Math.Max(0, m_width - 2); + int width = System.Math.Max(2, System.Math.Min(MAX_WIDTH, m_minWidth)); + int reqPreCompLen = 1 << (width - 2); - if (CheckExisting(existingWNaf, reqPreCompLen, m_includeNegated)) + if (CheckExisting(existingWNaf, width, reqPreCompLen, m_includeNegated)) + { + existingWNaf.DecrementPromotionCountdown(); return existingWNaf; + } + + WNafPreCompInfo result = new WNafPreCompInfo(); ECCurve c = m_p.Curve; ECPoint[] preComp = null, preCompNeg = null; ECPoint twiceP = null; - if (existingWNaf != null) + if (null != existingWNaf) { + int promotionCountdown = existingWNaf.DecrementPromotionCountdown(); + result.PromotionCountdown = promotionCountdown; + + int confWidth = existingWNaf.ConfWidth; + result.ConfWidth = confWidth; + preComp = existingWNaf.PreComp; preCompNeg = existingWNaf.PreCompNeg; twiceP = existingWNaf.Twice; } + width = System.Math.Min(MAX_WIDTH, System.Math.Max(result.ConfWidth, width)); + reqPreCompLen = 1 << (width - 2); + int iniPreCompLen = 0; - if (preComp == null) + if (null == preComp) { preComp = EMPTY_POINTS; } @@ -475,7 +581,7 @@ namespace Org.BouncyCastle.Math.EC.Multiplier else { ECPoint isoTwiceP = twiceP, last = preComp[curPreCompLen - 1]; - if (isoTwiceP == null) + if (null == isoTwiceP) { isoTwiceP = preComp[0].Twice(); twiceP = isoTwiceP; @@ -535,7 +641,7 @@ namespace Org.BouncyCastle.Math.EC.Multiplier if (m_includeNegated) { int pos; - if (preCompNeg == null) + if (null == preCompNeg) { pos = 0; preCompNeg = new ECPoint[reqPreCompLen]; @@ -556,23 +662,105 @@ namespace Org.BouncyCastle.Math.EC.Multiplier } } - WNafPreCompInfo result = new WNafPreCompInfo(); result.PreComp = preComp; result.PreCompNeg = preCompNeg; result.Twice = twiceP; + result.Width = width; + return result; + } + + private bool CheckExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, bool includeNegated) + { + return null != existingWNaf + && existingWNaf.Width >= System.Math.Max(existingWNaf.ConfWidth, width) + && CheckTable(existingWNaf.PreComp, reqPreCompLen) + && (!includeNegated || CheckTable(existingWNaf.PreCompNeg, reqPreCompLen)); + } + + private bool CheckTable(ECPoint[] table, int reqLen) + { + return null != table && table.Length >= reqLen; + } + } + + private class PrecomputeWithPointMapCallback + : IPreCompCallback + { + private readonly ECPoint m_point; + private readonly ECPointMap m_pointMap; + private readonly WNafPreCompInfo m_fromWNaf; + private readonly bool m_includeNegated; + + internal PrecomputeWithPointMapCallback(ECPoint point, ECPointMap pointMap, WNafPreCompInfo fromWNaf, + bool includeNegated) + { + this.m_point = point; + this.m_pointMap = pointMap; + this.m_fromWNaf = fromWNaf; + this.m_includeNegated = includeNegated; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo; + + int width = m_fromWNaf.Width; + int reqPreCompLen = m_fromWNaf.PreComp.Length; + + if (CheckExisting(existingWNaf, width, reqPreCompLen, m_includeNegated)) + { + existingWNaf.DecrementPromotionCountdown(); + return existingWNaf; + } + + /* + * TODO Ideally this method would support incremental calculation, but given the + * existing use-cases it would be of little-to-no benefit. + */ + WNafPreCompInfo result = new WNafPreCompInfo(); + + result.PromotionCountdown = m_fromWNaf.PromotionCountdown; + + ECPoint twiceFrom = m_fromWNaf.Twice; + if (null != twiceFrom) + { + ECPoint twice = m_pointMap.Map(twiceFrom); + result.Twice = twice; + } + + ECPoint[] preCompFrom = m_fromWNaf.PreComp; + ECPoint[] preComp = new ECPoint[preCompFrom.Length]; + for (int i = 0; i < preCompFrom.Length; ++i) + { + preComp[i] = m_pointMap.Map(preCompFrom[i]); + } + result.PreComp = preComp; + result.Width = width; + + if (m_includeNegated) + { + ECPoint[] preCompNeg = new ECPoint[preComp.Length]; + for (int i = 0; i < preCompNeg.Length; ++i) + { + preCompNeg[i] = preComp[i].Negate(); + } + result.PreCompNeg = preCompNeg; + } + return result; } - private bool CheckExisting(WNafPreCompInfo existingWNaf, int reqPreCompLen, bool includeNegated) + private bool CheckExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, bool includeNegated) { - return existingWNaf != null + return null != existingWNaf + && existingWNaf.Width >= width && CheckTable(existingWNaf.PreComp, reqPreCompLen) && (!includeNegated || CheckTable(existingWNaf.PreCompNeg, reqPreCompLen)); } private bool CheckTable(ECPoint[] table, int reqLen) { - return table != null && table.Length >= reqLen; + return null != table && table.Length >= reqLen; } } } diff --git a/crypto/src/math/ec/rfc7748/X25519Field.cs b/crypto/src/math/ec/rfc7748/X25519Field.cs index fd5599657..3a06941dd 100644 --- a/crypto/src/math/ec/rfc7748/X25519Field.cs +++ b/crypto/src/math/ec/rfc7748/X25519Field.cs @@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 private static readonly int[] RootNegOne = { 0x020EA0B0, 0x0386C9D2, 0x00478C4E, 0x0035697F, 0x005E8630, 0x01FBD7A7, 0x0340264F, 0x01F0B2B4, 0x00027E0E, 0x00570649 }; - private X25519Field() {} + protected X25519Field() {} public static void Add(int[] x, int[] y, int[] z) { @@ -67,6 +67,18 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[5] = z5; z[6] = z6; z[7] = z7; z[8] = z8; z[9] = z9; } + public static void CMov(int cond, int[] x, int xOff, int[] z, int zOff) + { + Debug.Assert(0 == cond || -1 == cond); + + for (int i = 0; i < Size; ++i) + { + int z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + z_i ^= (diff & cond); + z[zOff + i] = z_i; + } + } + public static void CNegate(int negate, int[] z) { Debug.Assert(negate >> 1 == 0); @@ -179,14 +191,21 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Mul(t, x2, z); } - public static bool IsZeroVar(int[] x) + public static int IsZero(int[] x) { int d = 0; for (int i = 0; i < Size; ++i) { d |= x[i]; } - return d == 0; + d |= d >> 16; + d &= 0xFFFF; + return (d - 1) >> 31; + } + + public static bool IsZeroVar(int[] x) + { + return 0 != IsZero(x); } public static void Mul(int[] x, int y, int[] z) diff --git a/crypto/src/math/ec/rfc7748/X448Field.cs b/crypto/src/math/ec/rfc7748/X448Field.cs index 5a682714d..f1e89e520 100644 --- a/crypto/src/math/ec/rfc7748/X448Field.cs +++ b/crypto/src/math/ec/rfc7748/X448Field.cs @@ -1,8 +1,6 @@ using System; using System.Diagnostics; -using Org.BouncyCastle.Math.Raw; - namespace Org.BouncyCastle.Math.EC.Rfc7748 { [CLSCompliantAttribute(false)] @@ -12,7 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 private const uint M28 = 0x0FFFFFFFU; - private X448Field() {} + protected X448Field() {} public static void Add(uint[] x, uint[] y, uint[] z) { @@ -74,6 +72,20 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[8] = z8; z[9] = z9; z[10] = z10; z[11] = z11; z[12] = z12; z[13] = z13; z[14] = z14; z[15] = z15; } + public static void CMov(int cond, uint[] x, int xOff, uint[] z, int zOff) + { + Debug.Assert(0 == cond || -1 == cond); + + uint MASK = (uint)cond; + + for (int i = 0; i < Size; ++i) + { + uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + z_i ^= (diff & MASK); + z[zOff + i] = z_i; + } + } + public static void CNegate(int negate, uint[] z) { Debug.Assert(negate >> 1 == 0); @@ -81,7 +93,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 uint[] t = Create(); Sub(t, z, t); - Nat.CMov(Size, negate, t, 0, z, 0); + CMov(-negate, t, 0, z, 0); } public static void Copy(uint[] x, int xOff, uint[] z, int zOff) @@ -195,14 +207,21 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Mul(t, x, z); } - public static bool IsZeroVar(uint[] x) + public static int IsZero(uint[] x) { uint d = 0; for (int i = 0; i < Size; ++i) { d |= x[i]; } - return d == 0U; + d |= d >> 16; + d &= 0xFFFF; + return ((int)d - 1) >> 31; + } + + public static bool IsZeroVar(uint[] x) + { + return 0U != IsZero(x); } public static void Mul(uint[] x, uint y, uint[] z) diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs index 702c48dd3..b798bdf2d 100644 --- a/crypto/src/math/ec/rfc8032/Ed25519.cs +++ b/crypto/src/math/ec/rfc8032/Ed25519.cs @@ -270,7 +270,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 private static sbyte[] GetWnaf(uint[] n, int width) { - Debug.Assert(n[ScalarUints - 1] >> 31 == 0); + Debug.Assert(n[ScalarUints - 1] >> 28 == 0); uint[] t = new uint[ScalarUints * 2]; { @@ -284,7 +284,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 } } - sbyte[] ws = new sbyte[256]; + sbyte[] ws = new sbyte[253]; uint pow2 = 1U << width; uint mask = pow2 - 1U; @@ -423,7 +423,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 DecodeScalar(k, 0, nA); PointAccum pR = new PointAccum(); - ScalarMultStraussVar(nS, nA, pA, pR); + ScalarMultStrausVar(nS, nA, pA, pR); byte[] check = new byte[PointBytes]; EncodePoint(pR, check, 0); @@ -597,10 +597,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 for (int i = 0; i < PrecompPoints; ++i) { - int mask = ((i ^ index) - 1) >> 31; - Nat.CMov(X25519Field.Size, mask, precompBase, off, p.ypx_h, 0); off += X25519Field.Size; - Nat.CMov(X25519Field.Size, mask, precompBase, off, p.ymx_h, 0); off += X25519Field.Size; - Nat.CMov(X25519Field.Size, mask, precompBase, off, p.xyd, 0); off += X25519Field.Size; + int cond = ((i ^ index) - 1) >> 31; + X25519Field.CMov(cond, precompBase, off, p.ypx_h, 0); off += X25519Field.Size; + X25519Field.CMov(cond, precompBase, off, p.ymx_h, 0); off += X25519Field.Size; + X25519Field.CMov(cond, precompBase, off, p.xyd, 0); off += X25519Field.Size; } } @@ -945,7 +945,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 X25519Field.Copy(p.z, 0, z, 0); } - private static void ScalarMultStraussVar(uint[] nb, uint[] np, PointExt p, PointAccum r) + private static void ScalarMultStrausVar(uint[] nb, uint[] np, PointExt p, PointAccum r) { Precompute(); @@ -958,13 +958,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 PointSetNeutral(r); - int bit = 255; - while (bit > 0 && ((byte)ws_b[bit] | (byte)ws_p[bit]) == 0) - { - --bit; - } - - for (; ; ) + for (int bit = 252;;) { int wb = ws_b[bit]; if (wb != 0) diff --git a/crypto/src/math/ec/rfc8032/Ed448.cs b/crypto/src/math/ec/rfc8032/Ed448.cs index 597062269..842839396 100644 --- a/crypto/src/math/ec/rfc8032/Ed448.cs +++ b/crypto/src/math/ec/rfc8032/Ed448.cs @@ -279,7 +279,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 private static sbyte[] GetWnaf(uint[] n, int width) { - Debug.Assert(n[ScalarUints - 1] >> 31 == 0U); + Debug.Assert(n[ScalarUints - 1] >> 30 == 0U); uint[] t = new uint[ScalarUints * 2]; { @@ -293,7 +293,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 } } - sbyte[] ws = new sbyte[448]; + sbyte[] ws = new sbyte[447]; uint pow2 = 1U << width; uint mask = pow2 - 1U; @@ -432,7 +432,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 DecodeScalar(k, 0, nA); PointExt pR = new PointExt(); - ScalarMultStraussVar(nS, nA, pA, pR); + ScalarMultStrausVar(nS, nA, pA, pR); byte[] check = new byte[PointBytes]; EncodePoint(pR, check, 0); @@ -568,9 +568,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 for (int i = 0; i < PrecompPoints; ++i) { - int mask = ((i ^ index) - 1) >> 31; - Nat.CMov(X448Field.Size, mask, precompBase, off, p.x, 0); off += X448Field.Size; - Nat.CMov(X448Field.Size, mask, precompBase, off, p.y, 0); off += X448Field.Size; + int cond = ((i ^ index) - 1) >> 31; + X448Field.CMov(cond, precompBase, off, p.x, 0); off += X448Field.Size; + X448Field.CMov(cond, precompBase, off, p.y, 0); off += X448Field.Size; } } @@ -1032,7 +1032,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 X448Field.Copy(p.y, 0, y, 0); } - private static void ScalarMultStraussVar(uint[] nb, uint[] np, PointExt p, PointExt r) + private static void ScalarMultStrausVar(uint[] nb, uint[] np, PointExt p, PointExt r) { Precompute(); @@ -1045,13 +1045,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 PointSetNeutral(r); - int bit = 447; - while (bit > 0 && ((byte)ws_b[bit] | (byte)ws_p[bit]) == 0) - { - --bit; - } - - for (;;) + for (int bit = 446;;) { int wb = ws_b[bit]; if (wb != 0) diff --git a/crypto/src/math/raw/Nat.cs b/crypto/src/math/raw/Nat.cs index f9e4e6714..9786d3ecf 100644 --- a/crypto/src/math/raw/Nat.cs +++ b/crypto/src/math/raw/Nat.cs @@ -161,6 +161,31 @@ namespace Org.BouncyCastle.Math.Raw return (uint)c; } + public static uint AddTo(int len, uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[xOff + i] + z[zOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddToEachOther(int len, uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)u[uOff + i] + v[vOff + i]; + u[uOff + i] = (uint)c; + v[vOff + i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + public static uint AddWordAt(int len, uint x, uint[] z, int zPos) { Debug.Assert(zPos <= (len - 1)); @@ -297,6 +322,32 @@ namespace Org.BouncyCastle.Math.Raw return new ulong[len]; } + public static int CSub(int len, int mask, uint[] x, uint[] y, uint[] z) + { + long MASK = (uint)-(mask & 1); + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)x[i] - (y[i] & MASK); + z[i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int CSub(int len, int mask, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long MASK = (uint)-(mask & 1); + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)x[xOff + i] - (y[yOff + i] & MASK); + z[zOff + i] = (uint)c; + c >>= 32; + } + return (int)c; + } + public static int Dec(int len, uint[] z) { for (int i = 0; i < len; ++i) @@ -384,6 +435,22 @@ namespace Org.BouncyCastle.Math.Raw return z; } + public static ulong[] FromBigInteger64(int bits, BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > bits) + throw new ArgumentException(); + + int len = (bits + 63) >> 6; + ulong[] z = Create64(len); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (ulong)x.LongValue; + x = x.ShiftRight(64); + } + return z; + } + public static uint GetBit(uint[] x, int bit) { if (bit == 0) @@ -538,10 +605,10 @@ namespace Org.BouncyCastle.Math.Raw ulong zc = 0; for (int i = 0; i < len; ++i) { - ulong c = MulWordAddTo(len, x[i], y, 0, zz, i) & M; - c += zc + (zz[i + len] & M); - zz[i + len] = (uint)c; - zc = c >> 32; + zc += MulWordAddTo(len, x[i], y, 0, zz, i) & M; + zc += zz[i + len] & M; + zz[i + len] = (uint)zc; + zc >>= 32; } return (uint)zc; } @@ -551,10 +618,10 @@ namespace Org.BouncyCastle.Math.Raw ulong zc = 0; for (int i = 0; i < len; ++i) { - ulong c = MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M; - c += zc + (zz[zzOff + len] & M); - zz[zzOff + len] = (uint)c; - zc = c >> 32; + zc += MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M; + zc += zz[zzOff + len] & M; + zz[zzOff + len] = (uint)zc; + zc >>= 32; ++zzOff; } return (uint)zc; @@ -886,11 +953,18 @@ namespace Org.BouncyCastle.Math.Raw } while (j > 0); + ulong d = 0UL; + int zzPos = 2; + for (int i = 1; i < len; ++i) { - c = SquareWordAdd(x, i, zz); - AddWordAt(extLen, c, zz, i << 1); + d += SquareWordAddTo(x, i, zz); + d += zz[zzPos]; + zz[zzPos++] = (uint)d; d >>= 32; + d += zz[zzPos]; + zz[zzPos++] = (uint)d; d >>= 32; } + Debug.Assert(0UL == d); ShiftUpBit(extLen, zz, x[0] << 31); } @@ -910,15 +984,23 @@ namespace Org.BouncyCastle.Math.Raw } while (j > 0); + ulong d = 0UL; + int zzPos = zzOff + 2; + for (int i = 1; i < len; ++i) { - c = SquareWordAdd(x, xOff, i, zz, zzOff); - AddWordAt(extLen, c, zz, zzOff, i << 1); + d += SquareWordAddTo(x, xOff, i, zz, zzOff); + d += zz[zzPos]; + zz[zzPos++] = (uint)d; d >>= 32; + d += zz[zzPos]; + zz[zzPos++] = (uint)d; d >>= 32; } + Debug.Assert(0UL == d); ShiftUpBit(extLen, zz, zzOff, x[xOff] << 31); } + [Obsolete("Use 'SquareWordAddTo' instead")] public static uint SquareWordAdd(uint[] x, int xPos, uint[] z) { ulong c = 0, xVal = (ulong)x[xPos]; @@ -933,6 +1015,7 @@ namespace Org.BouncyCastle.Math.Raw return (uint)c; } + [Obsolete("Use 'SquareWordAddTo' instead")] public static uint SquareWordAdd(uint[] x, int xOff, int xPos, uint[] z, int zOff) { ulong c = 0, xVal = (ulong)x[xOff + xPos]; @@ -948,6 +1031,35 @@ namespace Org.BouncyCastle.Math.Raw return (uint)c; } + public static uint SquareWordAddTo(uint[] x, int xPos, uint[] z) + { + ulong c = 0, xVal = (ulong)x[xPos]; + int i = 0; + do + { + c += xVal * x[i] + z[xPos + i]; + z[xPos + i] = (uint)c; + c >>= 32; + } + while (++i < xPos); + return (uint)c; + } + + public static uint SquareWordAddTo(uint[] x, int xOff, int xPos, uint[] z, int zOff) + { + ulong c = 0, xVal = (ulong)x[xOff + xPos]; + int i = 0; + do + { + c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M); + z[xPos + zOff] = (uint)c; + c >>= 32; + ++zOff; + } + while (++i < xPos); + return (uint)c; + } + public static int Sub(int len, uint[] x, uint[] y, uint[] z) { long c = 0; diff --git a/crypto/src/math/raw/Nat128.cs b/crypto/src/math/raw/Nat128.cs index 27ed5abe4..7617a9ee9 100644 --- a/crypto/src/math/raw/Nat128.cs +++ b/crypto/src/math/raw/Nat128.cs @@ -422,9 +422,10 @@ namespace Org.BouncyCastle.Math.Raw c += x_i * y_3 + zz[i + 3]; zz[i + 3] = (uint)c; c >>= 32; - c += zc + zz[i + 4]; - zz[i + 4] = (uint)c; - zc = c >> 32; + + zc += c + zz[i + 4]; + zz[i + 4] = (uint)zc; + zc >>= 32; } return (uint)zc; } @@ -452,9 +453,10 @@ namespace Org.BouncyCastle.Math.Raw c += x_i * y_3 + zz[zzOff + 3]; zz[zzOff + 3] = (uint)c; c >>= 32; - c += zc + zz[zzOff + 4]; - zz[zzOff + 4] = (uint)c; - zc = c >> 32; + + zc += c + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)zc; + zc >>= 32; ++zzOff; } return (uint)zc; diff --git a/crypto/src/math/raw/Nat160.cs b/crypto/src/math/raw/Nat160.cs index 57212cae0..f5514d7b4 100644 --- a/crypto/src/math/raw/Nat160.cs +++ b/crypto/src/math/raw/Nat160.cs @@ -384,9 +384,10 @@ namespace Org.BouncyCastle.Math.Raw c += x_i * y_4 + zz[i + 4]; zz[i + 4] = (uint)c; c >>= 32; - c += zc + zz[i + 5]; - zz[i + 5] = (uint)c; - zc = c >> 32; + + zc += c + zz[i + 5]; + zz[i + 5] = (uint)zc; + zc >>= 32; } return (uint)zc; } @@ -418,9 +419,10 @@ namespace Org.BouncyCastle.Math.Raw c += x_i * y_4 + zz[zzOff + 4]; zz[zzOff + 4] = (uint)c; c >>= 32; - c += zc + zz[zzOff + 5]; - zz[zzOff + 5] = (uint)c; - zc = c >> 32; + + zc += c + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)zc; + zc >>= 32; ++zzOff; } return (uint)zc; diff --git a/crypto/src/math/raw/Nat192.cs b/crypto/src/math/raw/Nat192.cs index 06c75aa54..1311dee04 100644 --- a/crypto/src/math/raw/Nat192.cs +++ b/crypto/src/math/raw/Nat192.cs @@ -498,9 +498,10 @@ namespace Org.BouncyCastle.Math.Raw c += x_i * y_5 + zz[i + 5]; zz[i + 5] = (uint)c; c >>= 32; - c += zc + zz[i + 6]; - zz[i + 6] = (uint)c; - zc = c >> 32; + + zc += c + zz[i + 6]; + zz[i + 6] = (uint)zc; + zc >>= 32; } return (uint)zc; } @@ -536,9 +537,10 @@ namespace Org.BouncyCastle.Math.Raw c += x_i * y_5 + zz[zzOff + 5]; zz[zzOff + 5] = (uint)c; c >>= 32; - c += zc + zz[zzOff + 6]; - zz[zzOff + 6] = (uint)c; - zc = c >> 32; + + zc += c + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)zc; + zc >>= 32; ++zzOff; } return (uint)zc; diff --git a/crypto/src/math/raw/Nat224.cs b/crypto/src/math/raw/Nat224.cs index ff1eb6306..565abcb9c 100644 --- a/crypto/src/math/raw/Nat224.cs +++ b/crypto/src/math/raw/Nat224.cs @@ -509,9 +509,10 @@ namespace Org.BouncyCastle.Math.Raw c += x_i * y_6 + zz[i + 6]; zz[i + 6] = (uint)c; c >>= 32; - c += zc + zz[i + 7]; - zz[i + 7] = (uint)c; - zc = c >> 32; + + zc += c + zz[i + 7]; + zz[i + 7] = (uint)zc; + zc >>= 32; } return (uint)zc; } @@ -551,9 +552,10 @@ namespace Org.BouncyCastle.Math.Raw c += x_i * y_6 + zz[zzOff + 6]; zz[zzOff + 6] = (uint)c; c >>= 32; - c += zc + zz[zzOff + 7]; - zz[zzOff + 7] = (uint)c; - zc = c >> 32; + + zc += c + zz[zzOff + 7]; + zz[zzOff + 7] = (uint)zc; + zc >>= 32; ++zzOff; } return (uint)zc; diff --git a/crypto/src/math/raw/Nat256.cs b/crypto/src/math/raw/Nat256.cs index 2be03d642..5c473c405 100644 --- a/crypto/src/math/raw/Nat256.cs +++ b/crypto/src/math/raw/Nat256.cs @@ -632,9 +632,10 @@ namespace Org.BouncyCastle.Math.Raw c += x_i * y_7 + zz[i + 7]; zz[i + 7] = (uint)c; c >>= 32; - c += zc + zz[i + 8]; - zz[i + 8] = (uint)c; - zc = c >> 32; + + zc += c + zz[i + 8]; + zz[i + 8] = (uint)zc; + zc >>= 32; } return (uint)zc; } @@ -678,9 +679,10 @@ namespace Org.BouncyCastle.Math.Raw c += x_i * y_7 + zz[zzOff + 7]; zz[zzOff + 7] = (uint)c; c >>= 32; - c += zc + zz[zzOff + 8]; - zz[zzOff + 8] = (uint)c; - zc = c >> 32; + + zc += c + zz[zzOff + 8]; + zz[zzOff + 8] = (uint)zc; + zc >>= 32; ++zzOff; } return (uint)zc; diff --git a/crypto/src/ocsp/BasicOCSPResp.cs b/crypto/src/ocsp/BasicOCSPResp.cs index 63ab8921e..e79d556bd 100644 --- a/crypto/src/ocsp/BasicOCSPResp.cs +++ b/crypto/src/ocsp/BasicOCSPResp.cs @@ -54,7 +54,7 @@ namespace Org.BouncyCastle.Ocsp public int Version { - get { return data.Version.Value.IntValue + 1; } + get { return data.Version.IntValueExact + 1; } } public RespID ResponderId diff --git a/crypto/src/ocsp/OCSPReq.cs b/crypto/src/ocsp/OCSPReq.cs index 0cd95c6d6..5408f068f 100644 --- a/crypto/src/ocsp/OCSPReq.cs +++ b/crypto/src/ocsp/OCSPReq.cs @@ -103,7 +103,7 @@ namespace Org.BouncyCastle.Ocsp public int Version { - get { return req.TbsRequest.Version.Value.IntValue + 1; } + get { return req.TbsRequest.Version.IntValueExact + 1; } } public GeneralName RequestorName diff --git a/crypto/src/ocsp/OCSPResp.cs b/crypto/src/ocsp/OCSPResp.cs index dc99c6a9a..1e65b2f7a 100644 --- a/crypto/src/ocsp/OCSPResp.cs +++ b/crypto/src/ocsp/OCSPResp.cs @@ -43,7 +43,7 @@ namespace Org.BouncyCastle.Ocsp public int Status { - get { return this.resp.ResponseStatus.Value.IntValue; } + get { return this.resp.ResponseStatus.IntValueExact; } } public object GetResponseObject() diff --git a/crypto/src/ocsp/RespData.cs b/crypto/src/ocsp/RespData.cs index 105726ca7..7ec0e4b68 100644 --- a/crypto/src/ocsp/RespData.cs +++ b/crypto/src/ocsp/RespData.cs @@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Ocsp public int Version { - get { return data.Version.Value.IntValue + 1; } + get { return data.Version.IntValueExact + 1; } } public RespID GetResponderId() diff --git a/crypto/src/ocsp/RevokedStatus.cs b/crypto/src/ocsp/RevokedStatus.cs index 6e5ad1b26..edbeb57da 100644 --- a/crypto/src/ocsp/RevokedStatus.cs +++ b/crypto/src/ocsp/RevokedStatus.cs @@ -51,7 +51,7 @@ namespace Org.BouncyCastle.Ocsp throw new InvalidOperationException("attempt to get a reason where none is available"); } - return info.RevocationReason.Value.IntValue; + return info.RevocationReason.IntValueExact; } } } diff --git a/crypto/src/pkix/Rfc3280CertPathUtilities.cs b/crypto/src/pkix/Rfc3280CertPathUtilities.cs index cdb69b7e0..c703194a4 100644 --- a/crypto/src/pkix/Rfc3280CertPathUtilities.cs +++ b/crypto/src/pkix/Rfc3280CertPathUtilities.cs @@ -1620,7 +1620,7 @@ namespace Org.BouncyCastle.Pkix Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraints.Current); if (constraint.TagNo == 0) { - tmpInt = DerInteger.GetInstance(constraint, false).Value.IntValue; + tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact; if (tmpInt < explicitPolicy) { return tmpInt; @@ -1675,7 +1675,7 @@ namespace Org.BouncyCastle.Pkix Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraints.Current); if (constraint.TagNo == 1) { - tmpInt = DerInteger.GetInstance(constraint, false).Value.IntValue; + tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact; if (tmpInt < policyMapping) { return tmpInt; @@ -1789,7 +1789,7 @@ namespace Org.BouncyCastle.Pkix if (iap != null) { - int _inhibitAnyPolicy = iap.Value.IntValue; + int _inhibitAnyPolicy = iap.IntValueExact; if (_inhibitAnyPolicy < inhibitAnyPolicy) return _inhibitAnyPolicy; @@ -2062,7 +2062,7 @@ namespace Org.BouncyCastle.Pkix case 0: try { - tmpInt = DerInteger.GetInstance(constraint, false).Value.IntValue; + tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact; } catch (Exception e) { diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs index f7709160d..ddcb88992 100644 --- a/crypto/src/security/PrivateKeyFactory.cs +++ b/crypto/src/security/PrivateKeyFactory.cs @@ -213,18 +213,9 @@ namespace Org.BouncyCastle.Security } else { - byte[] encVal = Asn1OctetString.GetInstance(privKey).GetOctets(); - byte[] dVal = new byte[encVal.Length]; - - for (int i = 0; i != encVal.Length; i++) - { - dVal[i] = encVal[encVal.Length - 1 - i]; - } - + byte[] dVal = Arrays.Reverse(Asn1OctetString.GetInstance(privKey).GetOctets()); d = new BigInteger(1, dVal); } - - } else { diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs index 7a34d71df..7b19f1c0f 100644 --- a/crypto/src/security/PublicKeyFactory.cs +++ b/crypto/src/security/PublicKeyFactory.cs @@ -17,6 +17,7 @@ using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Security @@ -56,7 +57,7 @@ namespace Org.BouncyCastle.Security || algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) { RsaPublicKeyStructure pubKey = RsaPublicKeyStructure.GetInstance( - keyInfo.GetPublicKey()); + keyInfo.ParsePublicKey()); return new RsaKeyParameters(false, pubKey.Modulus, pubKey.PublicExponent); } @@ -64,7 +65,7 @@ namespace Org.BouncyCastle.Security { Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()); - DHPublicKey dhPublicKey = DHPublicKey.GetInstance(keyInfo.GetPublicKey()); + DHPublicKey dhPublicKey = DHPublicKey.GetInstance(keyInfo.ParsePublicKey()); BigInteger y = dhPublicKey.Y.Value; @@ -101,7 +102,7 @@ namespace Org.BouncyCastle.Security { Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()); - DerInteger derY = (DerInteger) keyInfo.GetPublicKey(); + DerInteger derY = (DerInteger)keyInfo.ParsePublicKey(); return ReadPkcsDHParam(algOid, derY.Value, seq); } @@ -109,7 +110,7 @@ namespace Org.BouncyCastle.Security { ElGamalParameter para = new ElGamalParameter( Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object())); - DerInteger derY = (DerInteger) keyInfo.GetPublicKey(); + DerInteger derY = (DerInteger)keyInfo.ParsePublicKey(); return new ElGamalPublicKeyParameters( derY.Value, @@ -118,7 +119,7 @@ namespace Org.BouncyCastle.Security else if (algOid.Equals(X9ObjectIdentifiers.IdDsa) || algOid.Equals(OiwObjectIdentifiers.DsaWithSha1)) { - DerInteger derY = (DerInteger) keyInfo.GetPublicKey(); + DerInteger derY = (DerInteger)keyInfo.ParsePublicKey(); Asn1Encodable ae = algID.Parameters; DsaParameters parameters = null; @@ -158,64 +159,57 @@ namespace Org.BouncyCastle.Security } else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001)) { - Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( - (Asn1Sequence) algID.Parameters); + Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters); + DerObjectIdentifier publicKeyParamSet = gostParams.PublicKeyParamSet; + + ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(publicKeyParamSet); + if (ecP == null) + return null; Asn1OctetString key; try { - key = (Asn1OctetString) keyInfo.GetPublicKey(); + key = (Asn1OctetString)keyInfo.ParsePublicKey(); } - catch (IOException) + catch (IOException e) { - throw new ArgumentException("invalid info structure in GOST3410 public key"); + throw new ArgumentException("error recovering GOST3410_2001 public key", e); } - byte[] keyEnc = key.GetOctets(); - byte[] x = new byte[32]; - byte[] y = new byte[32]; + int fieldSize = 32; + int keySize = 2 * fieldSize; - for (int i = 0; i != y.Length; i++) - { - x[i] = keyEnc[32 - 1 - i]; - } + byte[] keyEnc = key.GetOctets(); + if (keyEnc.Length != keySize) + throw new ArgumentException("invalid length for GOST3410_2001 public key"); - for (int i = 0; i != x.Length; i++) + byte[] x9Encoding = new byte[1 + keySize]; + x9Encoding[0] = 0x04; + for (int i = 1; i <= fieldSize; ++i) { - y[i] = keyEnc[64 - 1 - i]; + x9Encoding[i] = keyEnc[fieldSize - i]; + x9Encoding[i + fieldSize] = keyEnc[keySize - i]; } - ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet); - - if (ecP == null) - return null; - - ECPoint q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y)); + ECPoint q = ecP.Curve.DecodePoint(x9Encoding); - return new ECPublicKeyParameters("ECGOST3410", q, gostParams.PublicKeyParamSet); + return new ECPublicKeyParameters("ECGOST3410", q, publicKeyParamSet); } else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94)) { - Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( - (Asn1Sequence) algID.Parameters); + Gost3410PublicKeyAlgParameters algParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters); - DerOctetString derY; + Asn1OctetString key; try { - derY = (DerOctetString) keyInfo.GetPublicKey(); + key = (Asn1OctetString)keyInfo.ParsePublicKey(); } - catch (IOException) + catch (IOException e) { - throw new ArgumentException("invalid info structure in GOST3410 public key"); + throw new ArgumentException("error recovering GOST3410_94 public key", e); } - byte[] keyEnc = derY.GetOctets(); - byte[] keyBytes = new byte[keyEnc.Length]; - - for (int i = 0; i != keyEnc.Length; i++) - { - keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // was little endian - } + byte[] keyBytes = Arrays.Reverse(key.GetOctets()); // was little endian BigInteger y = new BigInteger(1, keyBytes); @@ -236,21 +230,40 @@ namespace Org.BouncyCastle.Security else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448)) { return new Ed448PublicKeyParameters(GetRawKey(keyInfo, Ed448PublicKeyParameters.KeySize), 0); - } else if ( - algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256) || - algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512)) + } + else if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256) + || algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512)) { + Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters); + DerObjectIdentifier publicKeyParamSet = gostParams.PublicKeyParamSet; - byte[] keyEnc = ((DerOctetString)Asn1Object.FromByteArray(keyInfo.PublicKeyData.GetOctets())).str; + ECGost3410Parameters ecDomainParameters =new ECGost3410Parameters( + new ECNamedDomainParameters(publicKeyParamSet, ECGost3410NamedCurves.GetByOid(publicKeyParamSet)), + publicKeyParamSet, + gostParams.DigestParamSet, + gostParams.EncryptionParamSet); + + Asn1OctetString key; + try + { + key = (Asn1OctetString)keyInfo.ParsePublicKey(); + } + catch (IOException e) + { + throw new ArgumentException("error recovering GOST3410_2012 public key", e); + } int fieldSize = 32; if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512)) { fieldSize = 64; } - int keySize = 2 * fieldSize; + byte[] keyEnc = key.GetOctets(); + if (keyEnc.Length != keySize) + throw new ArgumentException("invalid length for GOST3410_2012 public key"); + byte[] x9Encoding = new byte[1 + keySize]; x9Encoding[0] = 0x04; for (int i = 1; i <= fieldSize; ++i) @@ -259,17 +272,9 @@ namespace Org.BouncyCastle.Security x9Encoding[i + fieldSize] = keyEnc[keySize - i]; } - Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(keyInfo.AlgorithmID.Parameters); - - ECGost3410Parameters ecDomainParameters = - new ECGost3410Parameters( - new ECNamedDomainParameters(gostParams.PublicKeyParamSet, ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet)), - gostParams.PublicKeyParamSet, - gostParams.DigestParamSet, - gostParams.EncryptionParamSet); - - return new ECPublicKeyParameters(ecDomainParameters.Curve.DecodePoint(x9Encoding), ecDomainParameters); + ECPoint q = ecDomainParameters.Curve.DecodePoint(x9Encoding); + return new ECPublicKeyParameters(q, ecDomainParameters); } else { diff --git a/crypto/src/tsp/GenTimeAccuracy.cs b/crypto/src/tsp/GenTimeAccuracy.cs index 8a2f29989..400bf6f9e 100644 --- a/crypto/src/tsp/GenTimeAccuracy.cs +++ b/crypto/src/tsp/GenTimeAccuracy.cs @@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Tsp private int GetTimeComponent( DerInteger time) { - return time == null ? 0 : time.Value.IntValue; + return time == null ? 0 : time.IntValueExact; } public override string ToString() diff --git a/crypto/src/tsp/TimeStampRequest.cs b/crypto/src/tsp/TimeStampRequest.cs index 0b41adef7..f5c6a09e6 100644 --- a/crypto/src/tsp/TimeStampRequest.cs +++ b/crypto/src/tsp/TimeStampRequest.cs @@ -72,7 +72,7 @@ namespace Org.BouncyCastle.Tsp public int Version { - get { return req.Version.Value.IntValue; } + get { return req.Version.IntValueExact; } } public string MessageImprintAlgOid diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs index aa8d31df4..7b060bf3c 100644 --- a/crypto/src/util/Arrays.cs +++ b/crypto/src/util/Arrays.cs @@ -366,35 +366,23 @@ namespace Org.BouncyCastle.Utilities return hc; } - public static byte[] Clone( - byte[] data) + public static bool[] Clone(bool[] data) { - return data == null ? null : (byte[])data.Clone(); + return data == null ? null : (bool[])data.Clone(); } - public static byte[] Clone( - byte[] data, - byte[] existing) + public static byte[] Clone(byte[] data) { - if (data == null) - { - return null; - } - if ((existing == null) || (existing.Length != data.Length)) - { - return Clone(data); - } - Array.Copy(data, 0, existing, 0, existing.Length); - return existing; + return data == null ? null : (byte[])data.Clone(); } - public static int[] Clone( - int[] data) + public static int[] Clone(int[] data) { return data == null ? null : (int[])data.Clone(); } - internal static uint[] Clone(uint[] data) + [CLSCompliantAttribute(false)] + public static uint[] Clone(uint[] data) { return data == null ? null : (uint[])data.Clone(); } @@ -405,25 +393,28 @@ namespace Org.BouncyCastle.Utilities } [CLSCompliantAttribute(false)] - public static ulong[] Clone( - ulong[] data) + public static ulong[] Clone(ulong[] data) { - return data == null ? null : (ulong[]) data.Clone(); + return data == null ? null : (ulong[])data.Clone(); + } + + public static byte[] Clone(byte[] data, byte[] existing) + { + if (data == null) + return null; + if (existing == null || existing.Length != data.Length) + return Clone(data); + Array.Copy(data, 0, existing, 0, existing.Length); + return existing; } [CLSCompliantAttribute(false)] - public static ulong[] Clone( - ulong[] data, - ulong[] existing) + public static ulong[] Clone(ulong[] data, ulong[] existing) { if (data == null) - { return null; - } - if ((existing == null) || (existing.Length != data.Length)) - { + if (existing == null || existing.Length != data.Length) return Clone(data); - } Array.Copy(data, 0, existing, 0, existing.Length); return existing; } @@ -721,5 +712,19 @@ namespace Org.BouncyCastle.Utilities return result; } + + public static bool IsNullOrContainsNull(object[] array) + { + if (null == array) + return true; + + int count = array.Length; + for (int i = 0; i < count; ++i) + { + if (null == array[i]) + return true; + } + return false; + } } } diff --git a/crypto/src/util/Integers.cs b/crypto/src/util/Integers.cs index e746b0ef4..bd05a053e 100644 --- a/crypto/src/util/Integers.cs +++ b/crypto/src/util/Integers.cs @@ -4,6 +4,21 @@ namespace Org.BouncyCastle.Utilities { public abstract class Integers { + public static int NumberOfLeadingZeros(int i) + { + if (i <= 0) + return (~i >> (31 - 5)) & (1 << 5); + + uint u = (uint)i; + int n = 1; + if (0 == (u >> 16)) { n += 16; u <<= 16; } + if (0 == (u >> 24)) { n += 8; u <<= 8; } + if (0 == (u >> 28)) { n += 4; u <<= 4; } + if (0 == (u >> 30)) { n += 2; u <<= 2; } + n -= (int)(u >> 31); + return n; + } + public static int RotateLeft(int i, int distance) { return (i << distance) ^ (int)((uint)i >> -distance); diff --git a/crypto/src/util/collections/CollectionUtilities.cs b/crypto/src/util/collections/CollectionUtilities.cs index cac158226..e0c79bdf4 100644 --- a/crypto/src/util/collections/CollectionUtilities.cs +++ b/crypto/src/util/collections/CollectionUtilities.cs @@ -49,23 +49,18 @@ namespace Org.BouncyCastle.Utilities.Collections public static string ToString(IEnumerable c) { - StringBuilder sb = new StringBuilder("["); - IEnumerator e = c.GetEnumerator(); + if (!e.MoveNext()) + return "[]"; - if (e.MoveNext()) + StringBuilder sb = new StringBuilder("["); + sb.Append(e.Current.ToString()); + while (e.MoveNext()) { + sb.Append(", "); sb.Append(e.Current.ToString()); - - while (e.MoveNext()) - { - sb.Append(", "); - sb.Append(e.Current.ToString()); - } } - sb.Append(']'); - return sb.ToString(); } } diff --git a/crypto/src/x509/AttributeCertificateHolder.cs b/crypto/src/x509/AttributeCertificateHolder.cs index 04460cd59..8ea90c24d 100644 --- a/crypto/src/x509/AttributeCertificateHolder.cs +++ b/crypto/src/x509/AttributeCertificateHolder.cs @@ -128,8 +128,8 @@ namespace Org.BouncyCastle.X509 ObjectDigestInfo odi = holder.ObjectDigestInfo; return odi == null - ? -1 - : odi.DigestedObjectType.Value.IntValue; + ? -1 + : odi.DigestedObjectType.IntValueExact; } } diff --git a/crypto/src/x509/X509Certificate.cs b/crypto/src/x509/X509Certificate.cs index 6f2f40411..fd156e487 100644 --- a/crypto/src/x509/X509Certificate.cs +++ b/crypto/src/x509/X509Certificate.cs @@ -32,8 +32,11 @@ namespace Org.BouncyCastle.X509 private readonly BasicConstraints basicConstraints; private readonly bool[] keyUsage; - private bool hashValueSet; - private int hashValue; + private readonly object cacheLock = new object(); + private AsymmetricKeyParameter publicKeyValue; + + private volatile bool hashValueSet; + private volatile int hashValue; protected X509Certificate() { @@ -295,7 +298,7 @@ namespace Org.BouncyCastle.X509 /// </summary> public virtual bool[] GetKeyUsage() { - return keyUsage == null ? null : (bool[]) keyUsage.Clone(); + return Arrays.Clone(keyUsage); } // TODO Replace with something that returns a list of DerObjectIdentifier @@ -387,7 +390,24 @@ namespace Org.BouncyCastle.X509 /// <returns>The public key parameters.</returns> public virtual AsymmetricKeyParameter GetPublicKey() { - return PublicKeyFactory.CreateKey(c.SubjectPublicKeyInfo); + // Cache the public key to support repeated-use optimizations + lock (cacheLock) + { + if (null != publicKeyValue) + return publicKeyValue; + } + + AsymmetricKeyParameter temp = PublicKeyFactory.CreateKey(c.SubjectPublicKeyInfo); + + lock (cacheLock) + { + if (null == publicKeyValue) + { + publicKeyValue = temp; + } + + return publicKeyValue; + } } /// <summary> @@ -399,35 +419,40 @@ namespace Org.BouncyCastle.X509 return c.GetDerEncoded(); } - public override bool Equals( - object obj) + public override bool Equals(object other) { - if (obj == this) + if (this == other) return true; - X509Certificate other = obj as X509Certificate; - - if (other == null) + X509Certificate that = other as X509Certificate; + if (null == that) return false; - return c.Equals(other.c); + if (this.hashValueSet && that.hashValueSet) + { + if (this.hashValue != that.hashValue) + return false; + } + else if (!this.c.Signature.Equals(that.c.Signature)) + { + return false; + } + + return this.c.Equals(that.c); // NB: May prefer this implementation of Equals if more than one certificate implementation in play -// return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded()); + //return Arrays.AreEqual(this.GetEncoded(), that.GetEncoded()); } public override int GetHashCode() { - lock (this) + if (!hashValueSet) { - if (!hashValueSet) - { - hashValue = c.GetHashCode(); - hashValueSet = true; - } + hashValue = this.c.GetHashCode(); + hashValueSet = true; } - return hashValue; + return hashValue; } // public void setBagAttribute( diff --git a/crypto/src/x509/X509Crl.cs b/crypto/src/x509/X509Crl.cs index ecfb14132..8903e69d0 100644 --- a/crypto/src/x509/X509Crl.cs +++ b/crypto/src/x509/X509Crl.cs @@ -6,6 +6,7 @@ using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Utilities; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; @@ -14,7 +15,6 @@ using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Date; using Org.BouncyCastle.Utilities.Encoders; using Org.BouncyCastle.X509.Extension; -using Org.BouncyCastle.Crypto.Operators; namespace Org.BouncyCastle.X509 { @@ -36,6 +36,9 @@ namespace Org.BouncyCastle.X509 private readonly byte[] sigAlgParams; private readonly bool isIndirect; + private volatile bool hashValueSet; + private volatile int hashValue; + public X509Crl( CertificateList c) { @@ -229,27 +232,41 @@ namespace Org.BouncyCastle.X509 return Arrays.Clone(sigAlgParams); } - public override bool Equals( - object obj) + public override bool Equals(object other) { - if (obj == this) - return true; + if (this == other) + return true; - X509Crl other = obj as X509Crl; + X509Crl that = other as X509Crl; + if (null == that) + return false; - if (other == null) - return false; + if (this.hashValueSet && that.hashValueSet) + { + if (this.hashValue != that.hashValue) + return false; + } + else if (!this.c.Signature.Equals(that.c.Signature)) + { + return false; + } - return c.Equals(other.c); + return this.c.Equals(that.c); - // NB: May prefer this implementation of Equals if more than one certificate implementation in play - //return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded()); + // NB: May prefer this implementation of Equals if more than one CRL implementation in play + //return Arrays.AreEqual(this.GetEncoded(), that.GetEncoded()); } - public override int GetHashCode() - { - return c.GetHashCode(); - } + public override int GetHashCode() + { + if (!hashValueSet) + { + hashValue = this.c.GetHashCode(); + hashValueSet = true; + } + + return hashValue; + } /** * Returns a string representation of this CRL. diff --git a/crypto/src/x509/X509CrlEntry.cs b/crypto/src/x509/X509CrlEntry.cs index caca29470..9e3608c18 100644 --- a/crypto/src/x509/X509CrlEntry.cs +++ b/crypto/src/x509/X509CrlEntry.cs @@ -1,6 +1,5 @@ using System; using System.Collections; -using System.IO; using System.Text; using Org.BouncyCastle.Asn1; @@ -27,6 +26,9 @@ namespace Org.BouncyCastle.X509 private X509Name previousCertificateIssuer; private X509Name certificateIssuer; + private volatile bool hashValueSet; + private volatile int hashValue; + public X509CrlEntry( CrlEntry c) { @@ -132,6 +134,35 @@ namespace Org.BouncyCastle.X509 get { return c.Extensions != null; } } + public override bool Equals(object other) + { + if (this == other) + return true; + + X509CrlEntry that = other as X509CrlEntry; + if (null == that) + return false; + + if (this.hashValueSet && that.hashValueSet) + { + if (this.hashValue != that.hashValue) + return false; + } + + return this.c.Equals(that.c); + } + + public override int GetHashCode() + { + if (!hashValueSet) + { + hashValue = this.c.GetHashCode(); + hashValueSet = true; + } + + return hashValue; + } + public override string ToString() { StringBuilder buf = new StringBuilder(); diff --git a/crypto/src/x509/X509V2AttributeCertificate.cs b/crypto/src/x509/X509V2AttributeCertificate.cs index c41b31239..1ceba101e 100644 --- a/crypto/src/x509/X509V2AttributeCertificate.cs +++ b/crypto/src/x509/X509V2AttributeCertificate.cs @@ -67,7 +67,7 @@ namespace Org.BouncyCastle.X509 public virtual int Version { - get { return cert.ACInfo.Version.Value.IntValue + 1; } + get { return cert.ACInfo.Version.IntValueExact + 1; } } public virtual BigInteger SerialNumber diff --git a/crypto/test/src/asn1/test/ASN1IntegerTest.cs b/crypto/test/src/asn1/test/ASN1IntegerTest.cs index 0937a7844..355b408eb 100644 --- a/crypto/test/src/asn1/test/ASN1IntegerTest.cs +++ b/crypto/test/src/asn1/test/ASN1IntegerTest.cs @@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Asn1.Tests new DerInteger(Hex.Decode("ffda47bfc776bcd269da4832626ac332adfca6dd835e8ecd83cd1ebe7d709b0e")); - new DerEnumerated(Hex.Decode("ffda47bfc776bcd269da4832626ac332adfca6dd835e8ecd83cd1ebe7d709b0e")); + new DerEnumerated(Hex.Decode("005a47bfc776bcd269da4832626ac332adfca6dd835e8ecd83cd1ebe7d709b0e")); SetAllowUnsafeProperty(false); @@ -102,6 +102,17 @@ namespace Org.BouncyCastle.Asn1.Tests { IsEquals("malformed enumerated", e.Message); } + + try + { + new DerEnumerated(Hex.Decode("005a47bfc776bcd269da4832626ac332adfca6dd835e8ecd83cd1ebe7d709b0e")); + + Fail("no exception"); + } + catch (ArgumentException e) + { + IsEquals("malformed enumerated", e.Message); + } #endif } @@ -173,7 +184,7 @@ namespace Org.BouncyCastle.Asn1.Tests try { byte[] rawInt = Hex.Decode("FF81FF"); - DerInteger i = new DerInteger(rawInt); + new DerInteger(rawInt); Fail("Expecting illegal argument exception."); } catch (ArgumentException e) @@ -212,7 +223,7 @@ namespace Org.BouncyCastle.Asn1.Tests try { byte[] rawInt = Hex.Decode("FFFFFFFF01FF"); - DerInteger i = new DerInteger(rawInt); + new DerInteger(rawInt); Fail("Expecting illegal argument exception."); } catch (ArgumentException e) @@ -235,7 +246,7 @@ namespace Org.BouncyCastle.Asn1.Tests { SetAllowUnsafeProperty(true); byte[] rawInt = Hex.Decode("0000000010FF"); - DerInteger i = new DerInteger(rawInt); + new DerInteger(rawInt); Fail("Expecting illegal argument exception."); } catch (ArgumentException e) @@ -254,7 +265,7 @@ namespace Org.BouncyCastle.Asn1.Tests { SetAllowUnsafeProperty(true); byte[] rawInt = Hex.Decode("FFFFFFFF10FF"); - DerInteger i = new DerInteger(rawInt); + new DerInteger(rawInt); Fail("Expecting illegal argument exception."); } catch (ArgumentException e) diff --git a/crypto/test/src/asn1/test/DeclarationOfMajorityUnitTest.cs b/crypto/test/src/asn1/test/DeclarationOfMajorityUnitTest.cs index 37c6fb519..2097a68b6 100644 --- a/crypto/test/src/asn1/test/DeclarationOfMajorityUnitTest.cs +++ b/crypto/test/src/asn1/test/DeclarationOfMajorityUnitTest.cs @@ -20,11 +20,11 @@ namespace Org.BouncyCastle.Asn1.Tests DerGeneralizedTime dateOfBirth = new DerGeneralizedTime("20070315173729Z"); DeclarationOfMajority decl = new DeclarationOfMajority(dateOfBirth); - checkConstruction(decl, DeclarationOfMajority.Choice.DateOfBirth, dateOfBirth, -1); + CheckConstruction(decl, DeclarationOfMajority.Choice.DateOfBirth, dateOfBirth, -1); decl = new DeclarationOfMajority(6); - checkConstruction(decl, DeclarationOfMajority.Choice.NotYoungerThan, null, 6); + CheckConstruction(decl, DeclarationOfMajority.Choice.NotYoungerThan, null, 6); decl = DeclarationOfMajority.GetInstance(null); @@ -45,28 +45,24 @@ namespace Org.BouncyCastle.Asn1.Tests } } - private void checkConstruction( + private void CheckConstruction( DeclarationOfMajority decl, DeclarationOfMajority.Choice type, DerGeneralizedTime dateOfBirth, int notYoungerThan) { - checkValues(decl, type, dateOfBirth, notYoungerThan); + CheckValues(decl, type, dateOfBirth, notYoungerThan); decl = DeclarationOfMajority.GetInstance(decl); - checkValues(decl, type, dateOfBirth, notYoungerThan); + CheckValues(decl, type, dateOfBirth, notYoungerThan); - Asn1InputStream aIn = new Asn1InputStream(decl.ToAsn1Object().GetEncoded()); + decl = DeclarationOfMajority.GetInstance(Asn1Object.FromByteArray(decl.GetEncoded())); - DerTaggedObject info = (DerTaggedObject) aIn.ReadObject(); - - decl = DeclarationOfMajority.GetInstance(info); - - checkValues(decl, type, dateOfBirth, notYoungerThan); + CheckValues(decl, type, dateOfBirth, notYoungerThan); } - private void checkValues( + private void CheckValues( DeclarationOfMajority decl, DeclarationOfMajority.Choice type, DerGeneralizedTime dateOfBirth, diff --git a/crypto/test/src/asn1/test/LinkedCertificateTest.cs b/crypto/test/src/asn1/test/LinkedCertificateTest.cs index 0eca5fda2..88ea5a07d 100644 --- a/crypto/test/src/asn1/test/LinkedCertificateTest.cs +++ b/crypto/test/src/asn1/test/LinkedCertificateTest.cs @@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Asn1.Tests Fail("getInstance() failed to detect bad object."); } - catch (ArgumentException e) + catch (ArgumentException) { // expected } diff --git a/crypto/test/src/asn1/test/MiscTest.cs b/crypto/test/src/asn1/test/MiscTest.cs index 553a72ef4..d33a16a3e 100644 --- a/crypto/test/src/asn1/test/MiscTest.cs +++ b/crypto/test/src/asn1/test/MiscTest.cs @@ -46,7 +46,7 @@ namespace Org.BouncyCastle.Asn1.Tests } catch (ArgumentException e) { - IsTrue("wrong exc", "malformed integer".Equals(e.Message)); + IsTrue("wrong exc", e.Message.StartsWith("malformed integer")); } try @@ -55,7 +55,7 @@ namespace Org.BouncyCastle.Asn1.Tests } catch (ArgumentException e) { - IsTrue("wrong exc", "malformed integer".Equals(e.Message)); + IsTrue("wrong exc", e.Message.StartsWith("malformed integer")); } try @@ -64,7 +64,7 @@ namespace Org.BouncyCastle.Asn1.Tests } catch (ArgumentException e) { - IsTrue("wrong exc", "malformed enumerated".Equals(e.Message)); + IsTrue("wrong exc", e.Message.StartsWith("malformed enumerated")); } try @@ -73,7 +73,7 @@ namespace Org.BouncyCastle.Asn1.Tests } catch (ArgumentException e) { - IsTrue("wrong exc", "malformed enumerated".Equals(e.Message)); + IsTrue("wrong exc", e.Message.StartsWith("malformed enumerated")); } } diff --git a/crypto/test/src/cmp/test/ProtectedMessageTest.cs b/crypto/test/src/cmp/test/ProtectedMessageTest.cs index 70bf670da..034463310 100644 --- a/crypto/test/src/cmp/test/ProtectedMessageTest.cs +++ b/crypto/test/src/cmp/test/ProtectedMessageTest.cs @@ -220,8 +220,9 @@ namespace Org.BouncyCastle.Cmp.Tests GeneralName sender = new GeneralName(new X509Name("CN=Sender")); GeneralName recipient = new GeneralName(new X509Name("CN=Recip")); - ProtectedPkiMessageBuilder msgBuilder = new ProtectedPkiMessageBuilder(sender, recipient); - msgBuilder.AddCmpCertificate(cert); + ProtectedPkiMessageBuilder msgBuilder = new ProtectedPkiMessageBuilder(sender, recipient) + .SetBody(new PkiBody(PkiBody.TYPE_INIT_REP, CertRepMessage.GetInstance(new DerSequence(new DerSequence())))) + .AddCmpCertificate(cert); ISignatureFactory sigFact = new Asn1SignatureFactory("MD5WithRSA", rsaKeyPair.Private); @@ -254,8 +255,9 @@ namespace Org.BouncyCastle.Cmp.Tests GeneralName sender = new GeneralName(new X509Name("CN=Sender")); GeneralName recipient = new GeneralName(new X509Name("CN=Recip")); - ProtectedPkiMessageBuilder msgBuilder = new ProtectedPkiMessageBuilder(sender, recipient); - msgBuilder.AddCmpCertificate(cert); + ProtectedPkiMessageBuilder msgBuilder = new ProtectedPkiMessageBuilder(sender, recipient) + .SetBody(new PkiBody(PkiBody.TYPE_INIT_REP, CertRepMessage.GetInstance(new DerSequence(new DerSequence())))) + .AddCmpCertificate(cert); // // Default instance. diff --git a/crypto/test/src/crypto/test/OAEPTest.cs b/crypto/test/src/crypto/test/OAEPTest.cs index 781e92ba5..4903ea09b 100644 --- a/crypto/test/src/crypto/test/OAEPTest.cs +++ b/crypto/test/src/crypto/test/OAEPTest.cs @@ -310,7 +310,7 @@ namespace Org.BouncyCastle.Crypto.Tests // Asn1Object pubKeyObj = Asn1Object.FromByteArray(pubKeyEnc); RsaPublicKeyStructure pubStruct = RsaPublicKeyStructure.GetInstance( - SubjectPublicKeyInfo.GetInstance(pubKeyObj).GetPublicKey()); + SubjectPublicKeyInfo.GetInstance(pubKeyObj).ParsePublicKey()); // // extract the private key info. diff --git a/crypto/test/src/crypto/test/SCryptTest.cs b/crypto/test/src/crypto/test/SCryptTest.cs index ea9dda9b1..5d2cae8be 100644 --- a/crypto/test/src/crypto/test/SCryptTest.cs +++ b/crypto/test/src/crypto/test/SCryptTest.cs @@ -65,7 +65,7 @@ namespace Org.BouncyCastle.Crypto.Tests SCrypt.Generate(pass, salt, N, r, p, len); Fail(msg); } - catch (ArgumentException e) + catch (ArgumentException) { //Console.Error.WriteLine(e.StackTrace); } diff --git a/crypto/test/src/math/ec/test/ECPointTest.cs b/crypto/test/src/math/ec/test/ECPointTest.cs index dbd739023..e1a2b8a6a 100644 --- a/crypto/test/src/math/ec/test/ECPointTest.cs +++ b/crypto/test/src/math/ec/test/ECPointTest.cs @@ -5,9 +5,11 @@ using NUnit.Framework; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Crypto.EC; +using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Tests { @@ -399,10 +401,15 @@ namespace Org.BouncyCastle.Math.EC.Tests ImplTestMultiply(q, n.BitLength); ImplTestMultiply(infinity, n.BitLength); + int logSize = 32 - Integers.NumberOfLeadingZeros(curve.FieldSize - 1); + int rounds = System.Math.Max(2, System.Math.Min(10, 32 - 3 * logSize)); + ECPoint p = q; - for (int i = 0; i < 10; ++i) + for (int i = 0; ; ) { ImplTestEncoding(p); + if (++i == rounds) + break; p = p.Twice(); } } @@ -446,14 +453,42 @@ namespace Org.BouncyCastle.Math.EC.Tests { Assert.IsTrue(g.IsValid()); - BigInteger h = c.Cofactor; - if (h != null && h.CompareTo(BigInteger.One) > 0) + if (ECAlgorithms.IsF2mCurve(c)) { - if (ECAlgorithms.IsF2mCurve(c)) + BigInteger h = c.Cofactor; + if (null != h) { - ECPoint order2 = c.CreatePoint(BigInteger.Zero, c.B.Sqrt().ToBigInteger()); - ECPoint bad = g.Add(order2); - Assert.IsFalse(bad.IsValid()); + if (!h.TestBit(0)) + { + ECFieldElement sqrtB = c.B.Sqrt(); + ECPoint order2 = c.CreatePoint(BigInteger.Zero, sqrtB.ToBigInteger()); + Assert.IsTrue(order2.Twice().IsInfinity); + Assert.IsFalse(order2.IsValid()); + ECPoint bad2 = g.Add(order2); + Assert.IsFalse(bad2.IsValid()); + ECPoint good2 = bad2.Add(order2); + Assert.IsTrue(good2.IsValid()); + + if (!h.TestBit(1)) + { + ECFieldElement L = SolveQuadraticEquation(c, c.A); + Assert.IsNotNull(L); + ECFieldElement T = sqrtB; + ECFieldElement x = T.Sqrt(); + ECFieldElement y = T.Add(x.Multiply(L)); + ECPoint order4 = c.CreatePoint(x.ToBigInteger(), y.ToBigInteger()); + Assert.IsTrue(order4.Twice().Equals(order2)); + Assert.IsFalse(order4.IsValid()); + ECPoint bad4_1 = g.Add(order4); + Assert.IsFalse(bad4_1.IsValid()); + ECPoint bad4_2 = bad4_1.Add(order4); + Assert.IsFalse(bad4_2.IsValid()); + ECPoint bad4_3 = bad4_2.Add(order4); + Assert.IsFalse(bad4_3.IsValid()); + ECPoint good4 = bad4_3.Add(order4); + Assert.IsTrue(good4.IsValid()); + } + } } } } @@ -543,6 +578,55 @@ namespace Org.BouncyCastle.Math.EC.Tests } } + [Test] + public void TestExampleFpB0() + { + /* + * The supersingular curve y^2 = x^3 - 3.x (i.e. with 'B' == 0) from RFC 6508 2.1, with + * curve parameters from RFC 6509 Appendix A. + */ + BigInteger p = FromHex( + "997ABB1F0A563FDA65C61198DAD0657A" + + "416C0CE19CB48261BE9AE358B3E01A2E" + + "F40AAB27E2FC0F1B228730D531A59CB0" + + "E791B39FF7C88A19356D27F4A666A6D0" + + "E26C6487326B4CD4512AC5CD65681CE1" + + "B6AFF4A831852A82A7CF3C521C3C09AA" + + "9F94D6AF56971F1FFCE3E82389857DB0" + + "80C5DF10AC7ACE87666D807AFEA85FEB"); + BigInteger a = p.Subtract(BigInteger.ValueOf(3)); + BigInteger b = BigInteger.Zero; + byte[] S = null; + BigInteger n = p.Add(BigInteger.One).ShiftRight(2); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, "04" + // Px + + "53FC09EE332C29AD0A7990053ED9B52A" + + "2B1A2FD60AEC69C698B2F204B6FF7CBF" + + "B5EDB6C0F6CE2308AB10DB9030B09E10" + + "43D5F22CDB9DFA55718BD9E7406CE890" + + "9760AF765DD5BCCB337C86548B72F2E1" + + "A702C3397A60DE74A7C1514DBA66910D" + + "D5CFB4CC80728D87EE9163A5B63F73EC" + + "80EC46C4967E0979880DC8ABEAE63895" + // Py + + "0A8249063F6009F1F9F1F0533634A135" + + "D3E82016029906963D778D821E141178" + + "F5EA69F4654EC2B9E7F7F5E5F0DE55F6" + + "6B598CCF9A140B2E416CFF0CA9E032B9" + + "70DAE117AD547C6CCAD696B5B7652FE0" + + "AC6F1E80164AA989492D979FC5A4D5F2" + + "13515AD7E9CB99A980BDAD5AD5BB4636" + + "ADB9B5706A67DCDE75573FD71BEF16D7"); + + X9ECParameters x9 = new X9ECParameters(curve, G, n, h, S); + + ImplAddSubtractMultiplyTwiceEncodingTestAllCoords(x9); + } + private void AssertPointsEqual(string message, ECPoint a, ECPoint b) { // NOTE: We intentionally test points for equality in both directions @@ -565,5 +649,52 @@ namespace Org.BouncyCastle.Math.EC.Tests Assert.IsTrue(Arrays.AreEqual(a, b)); } } + + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.Decode(encoding)); + //WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.Decode(hex)); + } + + private static ECFieldElement SolveQuadraticEquation(ECCurve c, ECFieldElement rhs) + { + if (rhs.IsZero) + return rhs; + + ECFieldElement gamma, z, zeroElement = c.FromBigInteger(BigInteger.Zero); + + int m = c.FieldSize; + do + { + ECFieldElement t = c.FromBigInteger(BigInteger.Arbitrary(m)); + z = zeroElement; + ECFieldElement w = rhs; + for (int i = 1; i < m; i++) + { + ECFieldElement w2 = w.Square(); + z = z.Square().Add(w2.Multiply(t)); + w = w2.Add(rhs); + } + if (!w.IsZero) + { + return null; + } + gamma = z.Square().Add(z); + } + while (gamma.IsZero); + + return z; + } } } diff --git a/crypto/test/src/test/NamedCurveTest.cs b/crypto/test/src/test/NamedCurveTest.cs index 5b29a4152..2273d2fd1 100644 --- a/crypto/test/src/test/NamedCurveTest.cs +++ b/crypto/test/src/test/NamedCurveTest.cs @@ -251,15 +251,15 @@ namespace Org.BouncyCastle.Tests // Current test cases don't work for GOST34.10 2012 return; - keyAlgorithm = "ECGOST3410-2012"; - if (name.IndexOf("256") > 0) - { - sgr = SignerUtilities.GetSigner("ECGOST3410-2012-256"); - } - else - { - sgr = SignerUtilities.GetSigner("ECGOST3410-2012-512"); - } + //keyAlgorithm = "ECGOST3410-2012"; + //if (name.IndexOf("256") > 0) + //{ + // sgr = SignerUtilities.GetSigner("ECGOST3410-2012-256"); + //} + //else + //{ + // sgr = SignerUtilities.GetSigner("ECGOST3410-2012-512"); + //} } else { |