Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/Neo.Cryptography.BLS12_381/Bls12.Adder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ Fp12 IMillerLoopDriver<Fp12>.AdditionStep(in Fp12 f)
return Ell(in f, in coeffs, in P);
}

static Fp12 IMillerLoopDriver<Fp12>.SquareOutput(in Fp12 f) => f.Square();
public static Fp12 SquareOutput(in Fp12 f) => f.Square();

static Fp12 IMillerLoopDriver<Fp12>.Conjugate(in Fp12 f) => f.Conjugate();
public static Fp12 Conjugate(in Fp12 f) => f.Conjugate();

static Fp12 IMillerLoopDriver<Fp12>.One => Fp12.One;
public static Fp12 One => Fp12.One;
Comment thread
cschuchardt88 marked this conversation as resolved.
Outdated
}
}
11 changes: 8 additions & 3 deletions src/Neo.Cryptography.BLS12_381/Fp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Neo.Cryptography.BLS12_381;

private static readonly Fp _zero = new();

static int INumber<Fp>.Size => Size;
//static int INumber<Fp>.Size => Size;
public static ref readonly Fp Zero => ref _zero;
public static ref readonly Fp One => ref R;

Expand Down Expand Up @@ -114,7 +114,7 @@ public override int GetHashCode()

public byte[] ToArray()
{
byte[] result = GC.AllocateUninitializedArray<byte>(Size);
byte[] result = new byte[Size];
TryWrite(result);
return result;
}
Expand All @@ -139,7 +139,12 @@ public bool TryWrite(Span<byte> buffer)

public override string ToString()
{
return "0x" + Convert.ToHexString(ToArray()).ToLowerInvariant();
var data = ToArray();
var output = string.Empty;
foreach (var b in data)
output += b.ToString("x2");

return "0x" + output.ToLowerInvariant();
}

public bool LexicographicallyLargest()
Expand Down
4 changes: 2 additions & 2 deletions src/Neo.Cryptography.BLS12_381/Fp12.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Neo.Cryptography.BLS12_381;
private static readonly Fp12 _zero = new();
private static readonly Fp12 _one = new(in Fp6.One);

static int INumber<Fp12>.Size => Size;
//static int INumber<Fp12>.Size => Size;
public static ref readonly Fp12 Zero => ref _zero;
public static ref readonly Fp12 One => ref _one;

Expand Down Expand Up @@ -81,7 +81,7 @@ public override int GetHashCode()

public byte[] ToArray()
{
byte[] result = GC.AllocateUninitializedArray<byte>(Size);
byte[] result = new byte[Size];
TryWrite(result);
return result;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Neo.Cryptography.BLS12_381/Fp2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Neo.Cryptography.BLS12_381;
private static readonly Fp2 _zero = new();
private static readonly Fp2 _one = new(in Fp.One);

static int INumber<Fp2>.Size => Size;
//static int INumber<Fp2>.Size => Size;
public static ref readonly Fp2 Zero => ref _zero;
public static ref readonly Fp2 One => ref _one;

Expand Down Expand Up @@ -77,7 +77,7 @@ public override int GetHashCode()

public byte[] ToArray()
{
byte[] result = GC.AllocateUninitializedArray<byte>(Size);
byte[] result = new byte[Size];
TryWrite(result);
return result;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Neo.Cryptography.BLS12_381/Fp6.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace Neo.Cryptography.BLS12_381;
private static readonly Fp6 _zero = new();
private static readonly Fp6 _one = new(in Fp2.One);

static int INumber<Fp6>.Size => Size;
//static int INumber<Fp6>.Size => Size;
public static ref readonly Fp6 Zero => ref _zero;
public static ref readonly Fp6 One => ref _one;

Expand Down Expand Up @@ -80,7 +80,7 @@ public override int GetHashCode()

public byte[] ToArray()
{
byte[] result = GC.AllocateUninitializedArray<byte>(Size);
byte[] result = new byte[Size];
TryWrite(result);
return result;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.Cryptography.BLS12_381/G1Affine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public byte[] ToCompressed()

public byte[] ToUncompressed()
{
byte[] res = GC.AllocateUninitializedArray<byte>(96);
byte[] res = new byte[96];

ConditionalSelect(in X, in Fp.Zero, Infinity).TryWrite(res.AsSpan(0..48));
ConditionalSelect(in Y, in Fp.Zero, Infinity).TryWrite(res.AsSpan(48..96));
Expand Down
4 changes: 2 additions & 2 deletions src/Neo.Cryptography.BLS12_381/G2Affine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public byte[] ToCompressed()
// to guard against implementation mistakes we do not assume this.
var x = ConditionalSelect(in X, in Fp2.Zero, Infinity);

var res = GC.AllocateUninitializedArray<byte>(96);
var res = new byte[96];

x.C1.TryWrite(res.AsSpan(0..48));
x.C0.TryWrite(res.AsSpan(48..96));
Expand All @@ -124,7 +124,7 @@ public byte[] ToCompressed()

public byte[] ToUncompressed()
{
var res = GC.AllocateUninitializedArray<byte>(192);
var res = new byte[192];

var x = ConditionalSelect(in X, in Fp2.Zero, Infinity);
var y = ConditionalSelect(in Y, in Fp2.Zero, Infinity);
Expand Down
6 changes: 3 additions & 3 deletions src/Neo.Cryptography.BLS12_381/G2Prepared.Adder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ public Adder(in G2Affine q)
return null;
}

static object? IMillerLoopDriver<object?>.SquareOutput(in object? f) => null;
public static object? SquareOutput(in object? f) => null;

static object? IMillerLoopDriver<object?>.Conjugate(in object? f) => null;
public static object? Conjugate(in object? f) => null;

static object? IMillerLoopDriver<object?>.One => null;
public static object? One => null;
}
}
6 changes: 3 additions & 3 deletions src/Neo.Cryptography.BLS12_381/IMillerLoopDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ interface IMillerLoopDriver<T>
{
public T DoublingStep(in T f);
public T AdditionStep(in T f);
public static abstract T SquareOutput(in T f);
public static abstract T Conjugate(in T f);
public static abstract T One { get; }
//public static abstract T SquareOutput(in T f);
//public static abstract T Conjugate(in T f);
//public static abstract T One { get; }
}
126 changes: 117 additions & 9 deletions src/Neo.Cryptography.BLS12_381/INumber.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,142 @@
using System.Reflection;

namespace Neo.Cryptography.BLS12_381;

interface INumber<T> where T : unmanaged, INumber<T>
{
static abstract int Size { get; }
static abstract ref readonly T Zero { get; }
static abstract ref readonly T One { get; }
//static abstract int Size { get; }
//static abstract ref readonly T Zero { get; }
//static abstract ref readonly T One { get; }

static abstract T operator -(in T x);
static abstract T operator +(in T x, in T y);
static abstract T operator -(in T x, in T y);
static abstract T operator *(in T x, in T y);
//static abstract T operator -(in T x);
//static abstract T operator +(in T x, in T y);
//static abstract T operator -(in T x, in T y);
//static abstract T operator *(in T x, in T y);

abstract T Square();
}

static class NumberExtensions
{
public static int Size<T>() where T : unmanaged, INumber<T>
{
var propertyInfo = typeof(T).GetProperty("Size", BindingFlags.Static);
if (propertyInfo != null)
{
return (int)propertyInfo.GetValue(null);
}
throw new InvalidOperationException("Property Size not found on type " + typeof(T).Name);
}

public static T Zero<T>() where T : unmanaged, INumber<T>
{
var propertyInfo = typeof(T).GetProperty("Zero", BindingFlags.Static);
if (propertyInfo != null)
{
return (T)propertyInfo.GetValue(null);
}
throw new InvalidOperationException("Property Zero not found on type " + typeof(T).Name);
}

public static T One<T>() where T : unmanaged, INumber<T>
{
// Try to get the 'One' property.
var propertyInfo = typeof(T).GetProperty("One", BindingFlags.Static | BindingFlags.Public);
if (propertyInfo != null)
{
return (T)propertyInfo.GetValue(null);
}

// If 'One' is not a property, try to get it as a field.
var fieldInfo = typeof(T).GetField("One", BindingFlags.Static | BindingFlags.Public);
if (fieldInfo != null)
{
return (T)fieldInfo.GetValue(null);
}

throw new InvalidOperationException("Property or Field 'One' not found on type " + typeof(T).Name);
}

public static T Add<T>(in T x, in T y) where T : unmanaged, INumber<T>
{
// Define the parameter types for the multiplication operator
Type[] paramTypes = { typeof(T).MakeByRefType(), typeof(T).MakeByRefType() };

// Attempt to find the multiplication operator
MethodInfo method = typeof(T).GetMethod("op_Addition", BindingFlags.Static | BindingFlags.Public, null, paramTypes, null);

if (method != null)
{
return (T)method.Invoke(null, new object[] { x, y });
}
throw new InvalidOperationException("Addition operator not found for type " + typeof(T).Name);
}

public static T Subtract<T>(in T x, in T y) where T : unmanaged, INumber<T>
{
// Define the parameter types for the multiplication operator
Type[] paramTypes = { typeof(T).MakeByRefType(), typeof(T).MakeByRefType() };

// Attempt to find the multiplication operator
MethodInfo method = typeof(T).GetMethod("op_Subtraction", BindingFlags.Static | BindingFlags.Public, null, paramTypes, null);

if (method != null)
{
return (T)method.Invoke(null, new object[] { x, y });
}
throw new InvalidOperationException("Subtraction operator not found for type " + typeof(T).Name);
}

public static T Multiply<T>(in T x, in T y) where T : unmanaged, INumber<T>
{
// Define binding flags to search for public and static members
var bindingFlags = BindingFlags.Static | BindingFlags.Public;

// Define the parameter types for the multiplication operator
Type[] paramTypes = { typeof(T).MakeByRefType(), typeof(T).MakeByRefType() };

// Attempt to find the multiplication operator
MethodInfo method = typeof(T).GetMethod("op_Multiply", bindingFlags, null, paramTypes, null);

if (method != null)
{
return (T)method.Invoke(null, new object[] { x, y });
}

throw new InvalidOperationException("Multiplication operator not found for type " + typeof(T).Name);
}

public static T Negate<T>(in T x) where T : unmanaged, INumber<T>
{
// Define binding flags to search for public and static members
var bindingFlags = BindingFlags.Static | BindingFlags.Public;

// Define the parameter types for the multiplication operator
Type[] paramTypes = { typeof(T).MakeByRefType() };

// Attempt to find the multiplication operator
MethodInfo method = typeof(T).GetMethod("op_UnaryNegation", bindingFlags, null, paramTypes, null);

if (method != null)
{
return (T)method.Invoke(null, new object[] { x });
}
throw new InvalidOperationException("Unary negation operator not found for type " + typeof(T).Name);
}

public static T PowVartime<T>(this T self, ulong[] by) where T : unmanaged, INumber<T>
{
// Although this is labeled "vartime", it is only
// variable time with respect to the exponent.
var res = T.One;
var res = One<T>();
for (int j = by.Length - 1; j >= 0; j--)
{
for (int i = 63; i >= 0; i--)
{
res = res.Square();
if (((by[j] >> i) & 1) == 1)
{
res *= self;
res = Multiply(res, self);
}
}
}
Expand Down
18 changes: 17 additions & 1 deletion src/Neo.Cryptography.BLS12_381/MathUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,27 @@ public static (ulong result, ulong borrow) Sbb(ulong a, ulong b, ulong borrow)

public static (ulong low, ulong high) Mac(ulong z, ulong x, ulong y, ulong carry)
{
ulong high = Math.BigMul(x, y, out ulong low);
ulong high = BigMul(x, y, out ulong low);
(low, carry) = Adc(low, carry, 0);
(high, _) = Adc(high, 0, carry);
(low, carry) = Adc(low, z, 0);
(high, _) = Adc(high, 0, carry);
return (low, high);
}

public static ulong BigMul(ulong a, ulong b, out ulong low)
{
uint al = (uint)a;
uint ah = (uint)(a >> 32);
uint bl = (uint)b;
uint bh = (uint)(b >> 32);

ulong mull = ((ulong)al) * bl;
ulong t = ((ulong)ah) * bl + (mull >> 32);
ulong tl = ((ulong)al) * bh + (uint)t;

low = tl << 32 | (uint)mull;

return ((ulong)ah) * bh + (t >> 32) + (tl >> 32);
}
}
25 changes: 22 additions & 3 deletions src/Neo.Cryptography.BLS12_381/MillerLoopUtility.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
using System.Reflection;
using static Neo.Cryptography.BLS12_381.Constants;

namespace Neo.Cryptography.BLS12_381;

static class MillerLoopUtility
{
public static T SquareOutput<T, D>(in T f) where D : IMillerLoopDriver<T>
{
MethodInfo methodInfo = typeof(D).GetMethod("SquareOutput", BindingFlags.Static | BindingFlags.Public);
return (T)methodInfo?.Invoke(null, new object[] { f! })!;
}

public static T Conjugate<T, D>(in T f) where D : IMillerLoopDriver<T>
{
MethodInfo methodInfo = typeof(D).GetMethod("Conjugate", BindingFlags.Static | BindingFlags.Public);
return (T)methodInfo?.Invoke(null, new object[] { f! })!;
}

public static T One<T, D>() where D : IMillerLoopDriver<T>
{
var methodInfo = typeof(D).GetMethod("get_One", BindingFlags.Static | BindingFlags.Public);
return (T)methodInfo?.Invoke(null, null)!;
}

public static T MillerLoop<T, D>(D driver) where D : IMillerLoopDriver<T>
{
var f = D.One;
var f = One<T, D>();

var found_one = false;
foreach (var i in Enumerable.Range(0, 64).Reverse().Select(b => ((BLS_X >> 1 >> b) & 1) == 1))
Expand All @@ -22,13 +41,13 @@ public static T MillerLoop<T, D>(D driver) where D : IMillerLoopDriver<T>
if (i)
f = driver.AdditionStep(f);

f = D.SquareOutput(f);
f = SquareOutput<T, D>(f);
}

f = driver.DoublingStep(f);

if (BLS_X_IS_NEGATIVE)
f = D.Conjugate(f);
f = Conjugate<T, D>(f);

return f;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

<PropertyGroup>
<VersionPrefix>0.2.0</VersionPrefix>
<TargetFramework>net7.0</TargetFramework>
<TargetFrameworks>netstandard2.1;net7.0</TargetFrameworks>
Comment thread
cschuchardt88 marked this conversation as resolved.
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Nullable>enable</Nullable>
<LangVersion>11.0</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>

</Project>
Loading