Core/PacketIO: Updated packet structures to 9.2.7
Port From (https://github.com/TrinityCore/TrinityCore/commit/20f38369f30309e2c0cd53eca9cfe9c49376ed8c)
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal
|
||||
{
|
||||
// Array16<UInt32> Salsa20 state
|
||||
// Array16<UInt64> SHA-512 block
|
||||
internal struct Array16<T>
|
||||
{
|
||||
public T x0;
|
||||
public T x1;
|
||||
public T x2;
|
||||
public T x3;
|
||||
public T x4;
|
||||
public T x5;
|
||||
public T x6;
|
||||
public T x7;
|
||||
public T x8;
|
||||
public T x9;
|
||||
public T x10;
|
||||
public T x11;
|
||||
public T x12;
|
||||
public T x13;
|
||||
public T x14;
|
||||
public T x15;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal
|
||||
{
|
||||
// Array8<UInt32> Poly1305 key
|
||||
// Array8<UInt64> SHA-512 state/output
|
||||
internal struct Array8<T>
|
||||
{
|
||||
public T x0;
|
||||
public T x1;
|
||||
public T x2;
|
||||
public T x3;
|
||||
public T x4;
|
||||
public T x5;
|
||||
public T x6;
|
||||
public T x7;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal
|
||||
{
|
||||
// Loops? Arrays? Never heard of that stuff
|
||||
// Library avoids unnecessary heap allocations and unsafe code
|
||||
// so this ugly code becomes necessary :(
|
||||
internal static class ByteIntegerConverter
|
||||
{
|
||||
public static ulong LoadBigEndian64(byte[] buf, int offset)
|
||||
{
|
||||
return
|
||||
(ulong)(buf[offset + 7])
|
||||
| (((ulong)(buf[offset + 6])) << 8)
|
||||
| (((ulong)(buf[offset + 5])) << 16)
|
||||
| (((ulong)(buf[offset + 4])) << 24)
|
||||
| (((ulong)(buf[offset + 3])) << 32)
|
||||
| (((ulong)(buf[offset + 2])) << 40)
|
||||
| (((ulong)(buf[offset + 1])) << 48)
|
||||
| (((ulong)(buf[offset + 0])) << 56);
|
||||
}
|
||||
|
||||
public static void StoreBigEndian64(byte[] buf, int offset, ulong value)
|
||||
{
|
||||
buf[offset + 7] = unchecked((byte)value);
|
||||
buf[offset + 6] = unchecked((byte)(value >> 8));
|
||||
buf[offset + 5] = unchecked((byte)(value >> 16));
|
||||
buf[offset + 4] = unchecked((byte)(value >> 24));
|
||||
buf[offset + 3] = unchecked((byte)(value >> 32));
|
||||
buf[offset + 2] = unchecked((byte)(value >> 40));
|
||||
buf[offset + 1] = unchecked((byte)(value >> 48));
|
||||
buf[offset + 0] = unchecked((byte)(value >> 56));
|
||||
}
|
||||
|
||||
public static void Array16LoadBigEndian64(out Array16<ulong> output, byte[] input, int inputOffset)
|
||||
{
|
||||
output.x0 = LoadBigEndian64(input, inputOffset + 0);
|
||||
output.x1 = LoadBigEndian64(input, inputOffset + 8);
|
||||
output.x2 = LoadBigEndian64(input, inputOffset + 16);
|
||||
output.x3 = LoadBigEndian64(input, inputOffset + 24);
|
||||
output.x4 = LoadBigEndian64(input, inputOffset + 32);
|
||||
output.x5 = LoadBigEndian64(input, inputOffset + 40);
|
||||
output.x6 = LoadBigEndian64(input, inputOffset + 48);
|
||||
output.x7 = LoadBigEndian64(input, inputOffset + 56);
|
||||
output.x8 = LoadBigEndian64(input, inputOffset + 64);
|
||||
output.x9 = LoadBigEndian64(input, inputOffset + 72);
|
||||
output.x10 = LoadBigEndian64(input, inputOffset + 80);
|
||||
output.x11 = LoadBigEndian64(input, inputOffset + 88);
|
||||
output.x12 = LoadBigEndian64(input, inputOffset + 96);
|
||||
output.x13 = LoadBigEndian64(input, inputOffset + 104);
|
||||
output.x14 = LoadBigEndian64(input, inputOffset + 112);
|
||||
output.x15 = LoadBigEndian64(input, inputOffset + 120);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal struct FieldElement
|
||||
{
|
||||
internal int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
|
||||
|
||||
internal FieldElement(params int[] elements)
|
||||
{
|
||||
x0 = elements[0];
|
||||
x1 = elements[1];
|
||||
x2 = elements[2];
|
||||
x3 = elements[3];
|
||||
x4 = elements[4];
|
||||
x5 = elements[5];
|
||||
x6 = elements[6];
|
||||
x7 = elements[7];
|
||||
x8 = elements[8];
|
||||
x9 = elements[9];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
/*
|
||||
ge means group element.
|
||||
|
||||
Here the group is the set of pairs (x,y) of field elements (see fe.h)
|
||||
satisfying -x^2 + y^2 = 1 + d x^2y^2
|
||||
where d = -121665/121666.
|
||||
|
||||
Representations:
|
||||
ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
|
||||
ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
|
||||
ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
|
||||
ge_precomp (Duif): (y+x,y-x,2dxy)
|
||||
*/
|
||||
|
||||
internal struct GroupElementP2
|
||||
{
|
||||
public FieldElement X;
|
||||
public FieldElement Y;
|
||||
public FieldElement Z;
|
||||
} ;
|
||||
|
||||
internal struct GroupElementP3
|
||||
{
|
||||
public FieldElement X;
|
||||
public FieldElement Y;
|
||||
public FieldElement Z;
|
||||
public FieldElement T;
|
||||
} ;
|
||||
|
||||
internal struct GroupElementP1P1
|
||||
{
|
||||
public FieldElement X;
|
||||
public FieldElement Y;
|
||||
public FieldElement Z;
|
||||
public FieldElement T;
|
||||
} ;
|
||||
|
||||
internal struct GroupElementPreComp
|
||||
{
|
||||
public FieldElement yplusx;
|
||||
public FieldElement yminusx;
|
||||
public FieldElement xy2d;
|
||||
|
||||
public GroupElementPreComp(FieldElement yplusx, FieldElement yminusx, FieldElement xy2d)
|
||||
{
|
||||
this.yplusx = yplusx;
|
||||
this.yminusx = yminusx;
|
||||
this.xy2d = xy2d;
|
||||
}
|
||||
} ;
|
||||
|
||||
internal struct GroupElementCached
|
||||
{
|
||||
public FieldElement YplusX;
|
||||
public FieldElement YminusX;
|
||||
public FieldElement Z;
|
||||
public FieldElement T2d;
|
||||
} ;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class LookupTables
|
||||
{
|
||||
internal static readonly GroupElementPreComp[] Base2 = new GroupElementPreComp[]{
|
||||
new GroupElementPreComp(
|
||||
new FieldElement( 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 ),
|
||||
new FieldElement( -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 ),
|
||||
new FieldElement( -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 )
|
||||
),
|
||||
new GroupElementPreComp(
|
||||
new FieldElement( 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 ),
|
||||
new FieldElement( 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 ),
|
||||
new FieldElement( 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 )
|
||||
),
|
||||
new GroupElementPreComp(
|
||||
new FieldElement( 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 ),
|
||||
new FieldElement( 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 ),
|
||||
new FieldElement( 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 )
|
||||
),
|
||||
new GroupElementPreComp(
|
||||
new FieldElement( 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 ),
|
||||
new FieldElement( -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 ),
|
||||
new FieldElement( 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 )
|
||||
),
|
||||
new GroupElementPreComp(
|
||||
new FieldElement( -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 ),
|
||||
new FieldElement( -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 ),
|
||||
new FieldElement( 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 )
|
||||
),
|
||||
new GroupElementPreComp(
|
||||
new FieldElement( -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 ),
|
||||
new FieldElement( 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 ),
|
||||
new FieldElement( 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 )
|
||||
),
|
||||
new GroupElementPreComp(
|
||||
new FieldElement( -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 ),
|
||||
new FieldElement( -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 ),
|
||||
new FieldElement( -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 )
|
||||
),
|
||||
new GroupElementPreComp(
|
||||
new FieldElement( -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 ),
|
||||
new FieldElement( -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 ),
|
||||
new FieldElement( -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 )
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class LookupTables
|
||||
{
|
||||
internal static FieldElement d = new FieldElement(-10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class LookupTables
|
||||
{
|
||||
internal static FieldElement d2 = new FieldElement(-21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
public static void fe_0(out FieldElement h)
|
||||
{
|
||||
h = default(FieldElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
public static void fe_1(out FieldElement h)
|
||||
{
|
||||
h = default(FieldElement);
|
||||
h.x0 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
h = f + g
|
||||
Can overlap h with f or g.
|
||||
|
||||
Preconditions:
|
||||
|f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
|g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
|
||||
Postconditions:
|
||||
|h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
*/
|
||||
//void fe_add(fe h,const fe f,const fe g)
|
||||
internal static void fe_add(out FieldElement h, ref FieldElement f, ref FieldElement g)
|
||||
{
|
||||
int f0 = f.x0;
|
||||
int f1 = f.x1;
|
||||
int f2 = f.x2;
|
||||
int f3 = f.x3;
|
||||
int f4 = f.x4;
|
||||
int f5 = f.x5;
|
||||
int f6 = f.x6;
|
||||
int f7 = f.x7;
|
||||
int f8 = f.x8;
|
||||
int f9 = f.x9;
|
||||
int g0 = g.x0;
|
||||
int g1 = g.x1;
|
||||
int g2 = g.x2;
|
||||
int g3 = g.x3;
|
||||
int g4 = g.x4;
|
||||
int g5 = g.x5;
|
||||
int g6 = g.x6;
|
||||
int g7 = g.x7;
|
||||
int g8 = g.x8;
|
||||
int g9 = g.x9;
|
||||
int h0 = f0 + g0;
|
||||
int h1 = f1 + g1;
|
||||
int h2 = f2 + g2;
|
||||
int h3 = f3 + g3;
|
||||
int h4 = f4 + g4;
|
||||
int h5 = f5 + g5;
|
||||
int h6 = f6 + g6;
|
||||
int h7 = f7 + g7;
|
||||
int h8 = f8 + g8;
|
||||
int h9 = f9 + g9;
|
||||
|
||||
h.x0 = h0;
|
||||
h.x1 = h1;
|
||||
h.x2 = h2;
|
||||
h.x3 = h3;
|
||||
h.x4 = h4;
|
||||
h.x5 = h5;
|
||||
h.x6 = h6;
|
||||
h.x7 = h7;
|
||||
h.x8 = h8;
|
||||
h.x9 = h9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
Replace (f,g) with (g,g) if b == 1;
|
||||
replace (f,g) with (f,g) if b == 0.
|
||||
|
||||
Preconditions: b in {0,1}.
|
||||
*/
|
||||
|
||||
//void fe_cmov(fe f,const fe g,unsigned int b)
|
||||
internal static void fe_cmov(ref FieldElement f, ref FieldElement g, int b)
|
||||
{
|
||||
int f0 = f.x0;
|
||||
int f1 = f.x1;
|
||||
int f2 = f.x2;
|
||||
int f3 = f.x3;
|
||||
int f4 = f.x4;
|
||||
int f5 = f.x5;
|
||||
int f6 = f.x6;
|
||||
int f7 = f.x7;
|
||||
int f8 = f.x8;
|
||||
int f9 = f.x9;
|
||||
int g0 = g.x0;
|
||||
int g1 = g.x1;
|
||||
int g2 = g.x2;
|
||||
int g3 = g.x3;
|
||||
int g4 = g.x4;
|
||||
int g5 = g.x5;
|
||||
int g6 = g.x6;
|
||||
int g7 = g.x7;
|
||||
int g8 = g.x8;
|
||||
int g9 = g.x9;
|
||||
int x0 = f0 ^ g0;
|
||||
int x1 = f1 ^ g1;
|
||||
int x2 = f2 ^ g2;
|
||||
int x3 = f3 ^ g3;
|
||||
int x4 = f4 ^ g4;
|
||||
int x5 = f5 ^ g5;
|
||||
int x6 = f6 ^ g6;
|
||||
int x7 = f7 ^ g7;
|
||||
int x8 = f8 ^ g8;
|
||||
int x9 = f9 ^ g9;
|
||||
|
||||
b = -b;
|
||||
x0 &= b;
|
||||
x1 &= b;
|
||||
x2 &= b;
|
||||
x3 &= b;
|
||||
x4 &= b;
|
||||
x5 &= b;
|
||||
x6 &= b;
|
||||
x7 &= b;
|
||||
x8 &= b;
|
||||
x9 &= b;
|
||||
f.x0 = f0 ^ x0;
|
||||
f.x1 = f1 ^ x1;
|
||||
f.x2 = f2 ^ x2;
|
||||
f.x3 = f3 ^ x3;
|
||||
f.x4 = f4 ^ x4;
|
||||
f.x5 = f5 ^ x5;
|
||||
f.x6 = f6 ^ x6;
|
||||
f.x7 = f7 ^ x7;
|
||||
f.x8 = f8 ^ x8;
|
||||
f.x9 = f9 ^ x9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
Replace (f,g) with (g,f) if b == 1;
|
||||
replace (f,g) with (f,g) if b == 0.
|
||||
|
||||
Preconditions: b in {0,1}.
|
||||
*/
|
||||
public static void fe_cswap(ref FieldElement f, ref FieldElement g, uint b)
|
||||
{
|
||||
int f0 = f.x0;
|
||||
int f1 = f.x1;
|
||||
int f2 = f.x2;
|
||||
int f3 = f.x3;
|
||||
int f4 = f.x4;
|
||||
int f5 = f.x5;
|
||||
int f6 = f.x6;
|
||||
int f7 = f.x7;
|
||||
int f8 = f.x8;
|
||||
int f9 = f.x9;
|
||||
int g0 = g.x0;
|
||||
int g1 = g.x1;
|
||||
int g2 = g.x2;
|
||||
int g3 = g.x3;
|
||||
int g4 = g.x4;
|
||||
int g5 = g.x5;
|
||||
int g6 = g.x6;
|
||||
int g7 = g.x7;
|
||||
int g8 = g.x8;
|
||||
int g9 = g.x9;
|
||||
int x0 = f0 ^ g0;
|
||||
int x1 = f1 ^ g1;
|
||||
int x2 = f2 ^ g2;
|
||||
int x3 = f3 ^ g3;
|
||||
int x4 = f4 ^ g4;
|
||||
int x5 = f5 ^ g5;
|
||||
int x6 = f6 ^ g6;
|
||||
int x7 = f7 ^ g7;
|
||||
int x8 = f8 ^ g8;
|
||||
int x9 = f9 ^ g9;
|
||||
|
||||
int negb = unchecked((int)-b);
|
||||
x0 &= negb;
|
||||
x1 &= negb;
|
||||
x2 &= negb;
|
||||
x3 &= negb;
|
||||
x4 &= negb;
|
||||
x5 &= negb;
|
||||
x6 &= negb;
|
||||
x7 &= negb;
|
||||
x8 &= negb;
|
||||
x9 &= negb;
|
||||
f.x0 = f0 ^ x0;
|
||||
f.x1 = f1 ^ x1;
|
||||
f.x2 = f2 ^ x2;
|
||||
f.x3 = f3 ^ x3;
|
||||
f.x4 = f4 ^ x4;
|
||||
f.x5 = f5 ^ x5;
|
||||
f.x6 = f6 ^ x6;
|
||||
f.x7 = f7 ^ x7;
|
||||
f.x8 = f8 ^ x8;
|
||||
f.x9 = f9 ^ x9;
|
||||
g.x0 = g0 ^ x0;
|
||||
g.x1 = g1 ^ x1;
|
||||
g.x2 = g2 ^ x2;
|
||||
g.x3 = g3 ^ x3;
|
||||
g.x4 = g4 ^ x4;
|
||||
g.x5 = g5 ^ x5;
|
||||
g.x6 = g6 ^ x6;
|
||||
g.x7 = g7 ^ x7;
|
||||
g.x8 = g8 ^ x8;
|
||||
g.x9 = g9 ^ x9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
private static long load_3(byte[] data, int offset)
|
||||
{
|
||||
uint result;
|
||||
result = data[offset + 0];
|
||||
result |= (uint)data[offset + 1] << 8;
|
||||
result |= (uint)data[offset + 2] << 16;
|
||||
return (long)(ulong)result;
|
||||
}
|
||||
|
||||
private static long load_4(byte[] data, int offset)
|
||||
{
|
||||
uint result;
|
||||
result = data[offset + 0];
|
||||
result |= (uint)data[offset + 1] << 8;
|
||||
result |= (uint)data[offset + 2] << 16;
|
||||
result |= (uint)data[offset + 3] << 24;
|
||||
return (long)(ulong)result;
|
||||
}
|
||||
|
||||
// Ignores top bit of h.
|
||||
internal static void fe_frombytes(out FieldElement h, byte[] data, int offset)
|
||||
{
|
||||
var h0 = load_4(data, offset);
|
||||
var h1 = load_3(data, offset + 4) << 6;
|
||||
var h2 = load_3(data, offset + 7) << 5;
|
||||
var h3 = load_3(data, offset + 10) << 3;
|
||||
var h4 = load_3(data, offset + 13) << 2;
|
||||
var h5 = load_4(data, offset + 16);
|
||||
var h6 = load_3(data, offset + 20) << 7;
|
||||
var h7 = load_3(data, offset + 23) << 5;
|
||||
var h8 = load_3(data, offset + 26) << 4;
|
||||
var h9 = (load_3(data, offset + 29) & 8388607) << 2;
|
||||
|
||||
var carry9 = (h9 + (1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
|
||||
var carry1 = (h1 + (1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
|
||||
var carry3 = (h3 + (1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
|
||||
var carry5 = (h5 + (1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
|
||||
var carry7 = (h7 + (1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
|
||||
|
||||
var carry0 = (h0 + (1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
var carry2 = (h2 + (1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
|
||||
var carry4 = (h4 + (1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
var carry6 = (h6 + (1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
|
||||
var carry8 = (h8 + (1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
|
||||
|
||||
h.x0 = (int)h0;
|
||||
h.x1 = (int)h1;
|
||||
h.x2 = (int)h2;
|
||||
h.x3 = (int)h3;
|
||||
h.x4 = (int)h4;
|
||||
h.x5 = (int)h5;
|
||||
h.x6 = (int)h6;
|
||||
h.x7 = (int)h7;
|
||||
h.x8 = (int)h8;
|
||||
h.x9 = (int)h9;
|
||||
}
|
||||
|
||||
// does NOT ignore top bit
|
||||
internal static void fe_frombytes2(out FieldElement h, byte[] data, int offset)
|
||||
{
|
||||
var h0 = load_4(data, offset);
|
||||
var h1 = load_3(data, offset + 4) << 6;
|
||||
var h2 = load_3(data, offset + 7) << 5;
|
||||
var h3 = load_3(data, offset + 10) << 3;
|
||||
var h4 = load_3(data, offset + 13) << 2;
|
||||
var h5 = load_4(data, offset + 16);
|
||||
var h6 = load_3(data, offset + 20) << 7;
|
||||
var h7 = load_3(data, offset + 23) << 5;
|
||||
var h8 = load_3(data, offset + 26) << 4;
|
||||
var h9 = load_3(data, offset + 29) << 2;
|
||||
|
||||
var carry9 = (h9 + (1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
|
||||
var carry1 = (h1 + (1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
|
||||
var carry3 = (h3 + (1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
|
||||
var carry5 = (h5 + (1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
|
||||
var carry7 = (h7 + (1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
|
||||
|
||||
var carry0 = (h0 + (1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
var carry2 = (h2 + (1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
|
||||
var carry4 = (h4 + (1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
var carry6 = (h6 + (1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
|
||||
var carry8 = (h8 + (1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
|
||||
|
||||
h.x0 = (int)h0;
|
||||
h.x1 = (int)h1;
|
||||
h.x2 = (int)h2;
|
||||
h.x3 = (int)h3;
|
||||
h.x4 = (int)h4;
|
||||
h.x5 = (int)h5;
|
||||
h.x6 = (int)h6;
|
||||
h.x7 = (int)h7;
|
||||
h.x8 = (int)h8;
|
||||
h.x9 = (int)h9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
internal static void fe_invert(out FieldElement result, ref FieldElement z)
|
||||
{
|
||||
FieldElement t0, t1, t2, t3;
|
||||
int i;
|
||||
|
||||
/* qhasm: z2 = z1^2^1 */
|
||||
/* asm 1: fe_sq(>z2=fe#1,<z1=fe#11); for (i = 1;i < 1;++i) fe_sq(>z2=fe#1,>z2=fe#1); */
|
||||
/* asm 2: fe_sq(>z2=t0,<z1=z); for (i = 1;i < 1;++i) fe_sq(>z2=t0,>z2=t0); */
|
||||
fe_sq(out t0, ref z); //for (i = 1; i < 1; ++i) fe_sq(out t0, ref t0);
|
||||
|
||||
/* qhasm: z8 = z2^2^2 */
|
||||
/* asm 1: fe_sq(>z8=fe#2,<z2=fe#1); for (i = 1;i < 2;++i) fe_sq(>z8=fe#2,>z8=fe#2); */
|
||||
/* asm 2: fe_sq(>z8=t1,<z2=t0); for (i = 1;i < 2;++i) fe_sq(>z8=t1,>z8=t1); */
|
||||
fe_sq(out t1, ref t0); for (i = 1; i < 2; ++i) fe_sq(out t1, ref t1);
|
||||
|
||||
/* qhasm: z9 = z1*z8 */
|
||||
/* asm 1: fe_mul(>z9=fe#2,<z1=fe#11,<z8=fe#2); */
|
||||
/* asm 2: fe_mul(>z9=t1,<z1=z,<z8=t1); */
|
||||
fe_mul(out t1, ref z, ref t1);
|
||||
|
||||
/* qhasm: z11 = z2*z9 */
|
||||
/* asm 1: fe_mul(>z11=fe#1,<z2=fe#1,<z9=fe#2); */
|
||||
/* asm 2: fe_mul(>z11=t0,<z2=t0,<z9=t1); */
|
||||
fe_mul(out t0, ref t0, ref t1);
|
||||
|
||||
/* qhasm: z22 = z11^2^1 */
|
||||
/* asm 1: fe_sq(>z22=fe#3,<z11=fe#1); for (i = 1;i < 1;++i) fe_sq(>z22=fe#3,>z22=fe#3); */
|
||||
/* asm 2: fe_sq(>z22=t2,<z11=t0); for (i = 1;i < 1;++i) fe_sq(>z22=t2,>z22=t2); */
|
||||
fe_sq(out t2, ref t0); //for (i = 1; i < 1; ++i) fe_sq(out t2, ref t2);
|
||||
|
||||
/* qhasm: z_5_0 = z9*z22 */
|
||||
/* asm 1: fe_mul(>z_5_0=fe#2,<z9=fe#2,<z22=fe#3); */
|
||||
/* asm 2: fe_mul(>z_5_0=t1,<z9=t1,<z22=t2); */
|
||||
fe_mul(out t1, ref t1, ref t2);
|
||||
|
||||
/* qhasm: z_10_5 = z_5_0^2^5 */
|
||||
/* asm 1: fe_sq(>z_10_5=fe#3,<z_5_0=fe#2); for (i = 1;i < 5;++i) fe_sq(>z_10_5=fe#3,>z_10_5=fe#3); */
|
||||
/* asm 2: fe_sq(>z_10_5=t2,<z_5_0=t1); for (i = 1;i < 5;++i) fe_sq(>z_10_5=t2,>z_10_5=t2); */
|
||||
fe_sq(out t2, ref t1); for (i = 1; i < 5; ++i) fe_sq(out t2, ref t2);
|
||||
|
||||
/* qhasm: z_10_0 = z_10_5*z_5_0 */
|
||||
/* asm 1: fe_mul(>z_10_0=fe#2,<z_10_5=fe#3,<z_5_0=fe#2); */
|
||||
/* asm 2: fe_mul(>z_10_0=t1,<z_10_5=t2,<z_5_0=t1); */
|
||||
fe_mul(out t1, ref t2, ref t1);
|
||||
|
||||
/* qhasm: z_20_10 = z_10_0^2^10 */
|
||||
/* asm 1: fe_sq(>z_20_10=fe#3,<z_10_0=fe#2); for (i = 1;i < 10;++i) fe_sq(>z_20_10=fe#3,>z_20_10=fe#3); */
|
||||
/* asm 2: fe_sq(>z_20_10=t2,<z_10_0=t1); for (i = 1;i < 10;++i) fe_sq(>z_20_10=t2,>z_20_10=t2); */
|
||||
fe_sq(out t2, ref t1); for (i = 1; i < 10; ++i) fe_sq(out t2, ref t2);
|
||||
|
||||
/* qhasm: z_20_0 = z_20_10*z_10_0 */
|
||||
/* asm 1: fe_mul(>z_20_0=fe#3,<z_20_10=fe#3,<z_10_0=fe#2); */
|
||||
/* asm 2: fe_mul(>z_20_0=t2,<z_20_10=t2,<z_10_0=t1); */
|
||||
fe_mul(out t2, ref t2, ref t1);
|
||||
|
||||
/* qhasm: z_40_20 = z_20_0^2^20 */
|
||||
/* asm 1: fe_sq(>z_40_20=fe#4,<z_20_0=fe#3); for (i = 1;i < 20;++i) fe_sq(>z_40_20=fe#4,>z_40_20=fe#4); */
|
||||
/* asm 2: fe_sq(>z_40_20=t3,<z_20_0=t2); for (i = 1;i < 20;++i) fe_sq(>z_40_20=t3,>z_40_20=t3); */
|
||||
fe_sq(out t3, ref t2); for (i = 1; i < 20; ++i) fe_sq(out t3, ref t3);
|
||||
|
||||
/* qhasm: z_40_0 = z_40_20*z_20_0 */
|
||||
/* asm 1: fe_mul(>z_40_0=fe#3,<z_40_20=fe#4,<z_20_0=fe#3); */
|
||||
/* asm 2: fe_mul(>z_40_0=t2,<z_40_20=t3,<z_20_0=t2); */
|
||||
fe_mul(out t2, ref t3, ref t2);
|
||||
|
||||
/* qhasm: z_50_10 = z_40_0^2^10 */
|
||||
/* asm 1: fe_sq(>z_50_10=fe#3,<z_40_0=fe#3); for (i = 1;i < 10;++i) fe_sq(>z_50_10=fe#3,>z_50_10=fe#3); */
|
||||
/* asm 2: fe_sq(>z_50_10=t2,<z_40_0=t2); for (i = 1;i < 10;++i) fe_sq(>z_50_10=t2,>z_50_10=t2); */
|
||||
fe_sq(out t2, ref t2); for (i = 1; i < 10; ++i) fe_sq(out t2, ref t2);
|
||||
|
||||
/* qhasm: z_50_0 = z_50_10*z_10_0 */
|
||||
/* asm 1: fe_mul(>z_50_0=fe#2,<z_50_10=fe#3,<z_10_0=fe#2); */
|
||||
/* asm 2: fe_mul(>z_50_0=t1,<z_50_10=t2,<z_10_0=t1); */
|
||||
fe_mul(out t1, ref t2, ref t1);
|
||||
|
||||
/* qhasm: z_100_50 = z_50_0^2^50 */
|
||||
/* asm 1: fe_sq(>z_100_50=fe#3,<z_50_0=fe#2); for (i = 1;i < 50;++i) fe_sq(>z_100_50=fe#3,>z_100_50=fe#3); */
|
||||
/* asm 2: fe_sq(>z_100_50=t2,<z_50_0=t1); for (i = 1;i < 50;++i) fe_sq(>z_100_50=t2,>z_100_50=t2); */
|
||||
fe_sq(out t2, ref t1); for (i = 1; i < 50; ++i) fe_sq(out t2, ref t2);
|
||||
|
||||
/* qhasm: z_100_0 = z_100_50*z_50_0 */
|
||||
/* asm 1: fe_mul(>z_100_0=fe#3,<z_100_50=fe#3,<z_50_0=fe#2); */
|
||||
/* asm 2: fe_mul(>z_100_0=t2,<z_100_50=t2,<z_50_0=t1); */
|
||||
fe_mul(out t2, ref t2, ref t1);
|
||||
|
||||
/* qhasm: z_200_100 = z_100_0^2^100 */
|
||||
/* asm 1: fe_sq(>z_200_100=fe#4,<z_100_0=fe#3); for (i = 1;i < 100;++i) fe_sq(>z_200_100=fe#4,>z_200_100=fe#4); */
|
||||
/* asm 2: fe_sq(>z_200_100=t3,<z_100_0=t2); for (i = 1;i < 100;++i) fe_sq(>z_200_100=t3,>z_200_100=t3); */
|
||||
fe_sq(out t3, ref t2); for (i = 1; i < 100; ++i) fe_sq(out t3, ref t3);
|
||||
|
||||
/* qhasm: z_200_0 = z_200_100*z_100_0 */
|
||||
/* asm 1: fe_mul(>z_200_0=fe#3,<z_200_100=fe#4,<z_100_0=fe#3); */
|
||||
/* asm 2: fe_mul(>z_200_0=t2,<z_200_100=t3,<z_100_0=t2); */
|
||||
fe_mul(out t2, ref t3, ref t2);
|
||||
|
||||
/* qhasm: z_250_50 = z_200_0^2^50 */
|
||||
/* asm 1: fe_sq(>z_250_50=fe#3,<z_200_0=fe#3); for (i = 1;i < 50;++i) fe_sq(>z_250_50=fe#3,>z_250_50=fe#3); */
|
||||
/* asm 2: fe_sq(>z_250_50=t2,<z_200_0=t2); for (i = 1;i < 50;++i) fe_sq(>z_250_50=t2,>z_250_50=t2); */
|
||||
fe_sq(out t2, ref t2); for (i = 1; i < 50; ++i) fe_sq(out t2, ref t2);
|
||||
|
||||
/* qhasm: z_250_0 = z_250_50*z_50_0 */
|
||||
/* asm 1: fe_mul(>z_250_0=fe#2,<z_250_50=fe#3,<z_50_0=fe#2); */
|
||||
/* asm 2: fe_mul(>z_250_0=t1,<z_250_50=t2,<z_50_0=t1); */
|
||||
fe_mul(out t1, ref t2, ref t1);
|
||||
|
||||
/* qhasm: z_255_5 = z_250_0^2^5 */
|
||||
/* asm 1: fe_sq(>z_255_5=fe#2,<z_250_0=fe#2); for (i = 1;i < 5;++i) fe_sq(>z_255_5=fe#2,>z_255_5=fe#2); */
|
||||
/* asm 2: fe_sq(>z_255_5=t1,<z_250_0=t1); for (i = 1;i < 5;++i) fe_sq(>z_255_5=t1,>z_255_5=t1); */
|
||||
fe_sq(out t1, ref t1); for (i = 1; i < 5; ++i) fe_sq(out t1, ref t1);
|
||||
|
||||
/* qhasm: z_255_21 = z_255_5*z11 */
|
||||
/* asm 1: fe_mul(>z_255_21=fe#12,<z_255_5=fe#2,<z11=fe#1); */
|
||||
/* asm 2: fe_mul(>z_255_21=out,<z_255_5=t1,<z11=t0); */
|
||||
fe_mul(out result, ref t1, ref t0);
|
||||
|
||||
/* qhasm: return */
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
return 1 if f is in {1,3,5,...,q-2}
|
||||
return 0 if f is in {0,2,4,...,q-1}
|
||||
|
||||
Preconditions:
|
||||
|f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
*/
|
||||
//int fe_isnegative(const fe f)
|
||||
public static int fe_isnegative(ref FieldElement f)
|
||||
{
|
||||
FieldElement fr;
|
||||
fe_reduce(out fr, ref f);
|
||||
return fr.x0 & 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
return 1 if f == 0
|
||||
return 0 if f != 0
|
||||
|
||||
Preconditions:
|
||||
|f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
*/
|
||||
// Todo: Discuss this with upstream
|
||||
// Above comment is from the original code. But I believe the original code returned
|
||||
// 0 if f == 0
|
||||
// -1 if f != 0
|
||||
// This code actually returns 0 if f==0 and 1 if f != 0
|
||||
internal static int fe_isnonzero(ref FieldElement f)
|
||||
{
|
||||
FieldElement fr;
|
||||
fe_reduce(out fr, ref f);
|
||||
int differentBits = 0;
|
||||
differentBits |= fr.x0;
|
||||
differentBits |= fr.x1;
|
||||
differentBits |= fr.x2;
|
||||
differentBits |= fr.x3;
|
||||
differentBits |= fr.x4;
|
||||
differentBits |= fr.x5;
|
||||
differentBits |= fr.x6;
|
||||
differentBits |= fr.x7;
|
||||
differentBits |= fr.x8;
|
||||
differentBits |= fr.x9;
|
||||
return (int)((unchecked((uint)differentBits - 1) >> 31) ^ 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
h = f * g
|
||||
Can overlap h with f or g.
|
||||
|
||||
Preconditions:
|
||||
|f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
|
||||
|g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
|
||||
|
||||
Postconditions:
|
||||
|h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes on implementation strategy:
|
||||
|
||||
Using schoolbook multiplication.
|
||||
Karatsuba would save a little in some cost models.
|
||||
|
||||
Most multiplications by 2 and 19 are 32-bit precomputations;
|
||||
cheaper than 64-bit postcomputations.
|
||||
|
||||
There is one remaining multiplication by 19 in the carry chain;
|
||||
one *19 precomputation can be merged into this,
|
||||
but the resulting data flow is considerably less clean.
|
||||
|
||||
There are 12 carries below.
|
||||
10 of them are 2-way parallelizable and vectorizable.
|
||||
Can get away with 11 carries, but then data flow is much deeper.
|
||||
|
||||
With tighter constraints on inputs can squeeze carries into int32.
|
||||
*/
|
||||
|
||||
internal static void fe_mul(out FieldElement h, ref FieldElement f, ref FieldElement g)
|
||||
{
|
||||
int f0 = f.x0;
|
||||
int f1 = f.x1;
|
||||
int f2 = f.x2;
|
||||
int f3 = f.x3;
|
||||
int f4 = f.x4;
|
||||
int f5 = f.x5;
|
||||
int f6 = f.x6;
|
||||
int f7 = f.x7;
|
||||
int f8 = f.x8;
|
||||
int f9 = f.x9;
|
||||
int g0 = g.x0;
|
||||
int g1 = g.x1;
|
||||
int g2 = g.x2;
|
||||
int g3 = g.x3;
|
||||
int g4 = g.x4;
|
||||
int g5 = g.x5;
|
||||
int g6 = g.x6;
|
||||
int g7 = g.x7;
|
||||
int g8 = g.x8;
|
||||
int g9 = g.x9;
|
||||
|
||||
int g1_19 = 19 * g1; /* 1.959375*2^29 */
|
||||
int g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
|
||||
int g3_19 = 19 * g3;
|
||||
int g4_19 = 19 * g4;
|
||||
int g5_19 = 19 * g5;
|
||||
int g6_19 = 19 * g6;
|
||||
int g7_19 = 19 * g7;
|
||||
int g8_19 = 19 * g8;
|
||||
int g9_19 = 19 * g9;
|
||||
|
||||
int f1_2 = 2 * f1;
|
||||
int f3_2 = 2 * f3;
|
||||
int f5_2 = 2 * f5;
|
||||
int f7_2 = 2 * f7;
|
||||
int f9_2 = 2 * f9;
|
||||
|
||||
long f0g0 = f0 * (long)g0;
|
||||
long f0g1 = f0 * (long)g1;
|
||||
long f0g2 = f0 * (long)g2;
|
||||
long f0g3 = f0 * (long)g3;
|
||||
long f0g4 = f0 * (long)g4;
|
||||
long f0g5 = f0 * (long)g5;
|
||||
long f0g6 = f0 * (long)g6;
|
||||
long f0g7 = f0 * (long)g7;
|
||||
long f0g8 = f0 * (long)g8;
|
||||
long f0g9 = f0 * (long)g9;
|
||||
long f1g0 = f1 * (long)g0;
|
||||
long f1g1_2 = f1_2 * (long)g1;
|
||||
long f1g2 = f1 * (long)g2;
|
||||
long f1g3_2 = f1_2 * (long)g3;
|
||||
long f1g4 = f1 * (long)g4;
|
||||
long f1g5_2 = f1_2 * (long)g5;
|
||||
long f1g6 = f1 * (long)g6;
|
||||
long f1g7_2 = f1_2 * (long)g7;
|
||||
long f1g8 = f1 * (long)g8;
|
||||
long f1g9_38 = f1_2 * (long)g9_19;
|
||||
long f2g0 = f2 * (long)g0;
|
||||
long f2g1 = f2 * (long)g1;
|
||||
long f2g2 = f2 * (long)g2;
|
||||
long f2g3 = f2 * (long)g3;
|
||||
long f2g4 = f2 * (long)g4;
|
||||
long f2g5 = f2 * (long)g5;
|
||||
long f2g6 = f2 * (long)g6;
|
||||
long f2g7 = f2 * (long)g7;
|
||||
long f2g8_19 = f2 * (long)g8_19;
|
||||
long f2g9_19 = f2 * (long)g9_19;
|
||||
long f3g0 = f3 * (long)g0;
|
||||
long f3g1_2 = f3_2 * (long)g1;
|
||||
long f3g2 = f3 * (long)g2;
|
||||
long f3g3_2 = f3_2 * (long)g3;
|
||||
long f3g4 = f3 * (long)g4;
|
||||
long f3g5_2 = f3_2 * (long)g5;
|
||||
long f3g6 = f3 * (long)g6;
|
||||
long f3g7_38 = f3_2 * (long)g7_19;
|
||||
long f3g8_19 = f3 * (long)g8_19;
|
||||
long f3g9_38 = f3_2 * (long)g9_19;
|
||||
long f4g0 = f4 * (long)g0;
|
||||
long f4g1 = f4 * (long)g1;
|
||||
long f4g2 = f4 * (long)g2;
|
||||
long f4g3 = f4 * (long)g3;
|
||||
long f4g4 = f4 * (long)g4;
|
||||
long f4g5 = f4 * (long)g5;
|
||||
long f4g6_19 = f4 * (long)g6_19;
|
||||
long f4g7_19 = f4 * (long)g7_19;
|
||||
long f4g8_19 = f4 * (long)g8_19;
|
||||
long f4g9_19 = f4 * (long)g9_19;
|
||||
long f5g0 = f5 * (long)g0;
|
||||
long f5g1_2 = f5_2 * (long)g1;
|
||||
long f5g2 = f5 * (long)g2;
|
||||
long f5g3_2 = f5_2 * (long)g3;
|
||||
long f5g4 = f5 * (long)g4;
|
||||
long f5g5_38 = f5_2 * (long)g5_19;
|
||||
long f5g6_19 = f5 * (long)g6_19;
|
||||
long f5g7_38 = f5_2 * (long)g7_19;
|
||||
long f5g8_19 = f5 * (long)g8_19;
|
||||
long f5g9_38 = f5_2 * (long)g9_19;
|
||||
long f6g0 = f6 * (long)g0;
|
||||
long f6g1 = f6 * (long)g1;
|
||||
long f6g2 = f6 * (long)g2;
|
||||
long f6g3 = f6 * (long)g3;
|
||||
long f6g4_19 = f6 * (long)g4_19;
|
||||
long f6g5_19 = f6 * (long)g5_19;
|
||||
long f6g6_19 = f6 * (long)g6_19;
|
||||
long f6g7_19 = f6 * (long)g7_19;
|
||||
long f6g8_19 = f6 * (long)g8_19;
|
||||
long f6g9_19 = f6 * (long)g9_19;
|
||||
long f7g0 = f7 * (long)g0;
|
||||
long f7g1_2 = f7_2 * (long)g1;
|
||||
long f7g2 = f7 * (long)g2;
|
||||
long f7g3_38 = f7_2 * (long)g3_19;
|
||||
long f7g4_19 = f7 * (long)g4_19;
|
||||
long f7g5_38 = f7_2 * (long)g5_19;
|
||||
long f7g6_19 = f7 * (long)g6_19;
|
||||
long f7g7_38 = f7_2 * (long)g7_19;
|
||||
long f7g8_19 = f7 * (long)g8_19;
|
||||
long f7g9_38 = f7_2 * (long)g9_19;
|
||||
long f8g0 = f8 * (long)g0;
|
||||
long f8g1 = f8 * (long)g1;
|
||||
long f8g2_19 = f8 * (long)g2_19;
|
||||
long f8g3_19 = f8 * (long)g3_19;
|
||||
long f8g4_19 = f8 * (long)g4_19;
|
||||
long f8g5_19 = f8 * (long)g5_19;
|
||||
long f8g6_19 = f8 * (long)g6_19;
|
||||
long f8g7_19 = f8 * (long)g7_19;
|
||||
long f8g8_19 = f8 * (long)g8_19;
|
||||
long f8g9_19 = f8 * (long)g9_19;
|
||||
long f9g0 = f9 * (long)g0;
|
||||
long f9g1_38 = f9_2 * (long)g1_19;
|
||||
long f9g2_19 = f9 * (long)g2_19;
|
||||
long f9g3_38 = f9_2 * (long)g3_19;
|
||||
long f9g4_19 = f9 * (long)g4_19;
|
||||
long f9g5_38 = f9_2 * (long)g5_19;
|
||||
long f9g6_19 = f9 * (long)g6_19;
|
||||
long f9g7_38 = f9_2 * (long)g7_19;
|
||||
long f9g8_19 = f9 * (long)g8_19;
|
||||
long f9g9_38 = f9_2 * (long)g9_19;
|
||||
|
||||
long h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38;
|
||||
long h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19;
|
||||
long h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38;
|
||||
long h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19;
|
||||
long h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38;
|
||||
long h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19;
|
||||
long h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38;
|
||||
long h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19;
|
||||
long h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38;
|
||||
long h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0;
|
||||
|
||||
long carry0;
|
||||
long carry1;
|
||||
long carry2;
|
||||
long carry3;
|
||||
long carry4;
|
||||
long carry5;
|
||||
long carry6;
|
||||
long carry7;
|
||||
long carry8;
|
||||
long carry9;
|
||||
|
||||
/*
|
||||
|h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
|
||||
i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
|
||||
|h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
|
||||
i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9
|
||||
*/
|
||||
|
||||
carry0 = (h0 + (long)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
carry4 = (h4 + (long)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
/* |h0| <= 2^25 */
|
||||
/* |h4| <= 2^25 */
|
||||
/* |h1| <= 1.71*2^59 */
|
||||
/* |h5| <= 1.71*2^59 */
|
||||
|
||||
carry1 = (h1 + (long)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
|
||||
carry5 = (h5 + (long)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
|
||||
/* |h1| <= 2^24; from now on fits into int32 */
|
||||
/* |h5| <= 2^24; from now on fits into int32 */
|
||||
/* |h2| <= 1.41*2^60 */
|
||||
/* |h6| <= 1.41*2^60 */
|
||||
|
||||
carry2 = (h2 + (long)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
|
||||
carry6 = (h6 + (long)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
|
||||
/* |h2| <= 2^25; from now on fits into int32 unchanged */
|
||||
/* |h6| <= 2^25; from now on fits into int32 unchanged */
|
||||
/* |h3| <= 1.71*2^59 */
|
||||
/* |h7| <= 1.71*2^59 */
|
||||
|
||||
carry3 = (h3 + (long)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
|
||||
carry7 = (h7 + (long)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
|
||||
/* |h3| <= 2^24; from now on fits into int32 unchanged */
|
||||
/* |h7| <= 2^24; from now on fits into int32 unchanged */
|
||||
/* |h4| <= 1.72*2^34 */
|
||||
/* |h8| <= 1.41*2^60 */
|
||||
|
||||
carry4 = (h4 + (long)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
carry8 = (h8 + (long)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
|
||||
/* |h4| <= 2^25; from now on fits into int32 unchanged */
|
||||
/* |h8| <= 2^25; from now on fits into int32 unchanged */
|
||||
/* |h5| <= 1.01*2^24 */
|
||||
/* |h9| <= 1.71*2^59 */
|
||||
|
||||
carry9 = (h9 + (long)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
|
||||
/* |h9| <= 2^24; from now on fits into int32 unchanged */
|
||||
/* |h0| <= 1.1*2^39 */
|
||||
|
||||
carry0 = (h0 + (long)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
/* |h0| <= 2^25; from now on fits into int32 unchanged */
|
||||
/* |h1| <= 1.01*2^24 */
|
||||
|
||||
h.x0 = (int)h0;
|
||||
h.x1 = (int)h1;
|
||||
h.x2 = (int)h2;
|
||||
h.x3 = (int)h3;
|
||||
h.x4 = (int)h4;
|
||||
h.x5 = (int)h5;
|
||||
h.x6 = (int)h6;
|
||||
h.x7 = (int)h7;
|
||||
h.x8 = (int)h8;
|
||||
h.x9 = (int)h9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
|
||||
/*
|
||||
h = f * 121666
|
||||
Can overlap h with f.
|
||||
|
||||
Preconditions:
|
||||
|f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
|
||||
Postconditions:
|
||||
|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
*/
|
||||
|
||||
public static void fe_mul121666(out FieldElement h, ref FieldElement f)
|
||||
{
|
||||
int f0 = f.x0;
|
||||
int f1 = f.x1;
|
||||
int f2 = f.x2;
|
||||
int f3 = f.x3;
|
||||
int f4 = f.x4;
|
||||
int f5 = f.x5;
|
||||
int f6 = f.x6;
|
||||
int f7 = f.x7;
|
||||
int f8 = f.x8;
|
||||
int f9 = f.x9;
|
||||
|
||||
var h0 = f0 * 121666L;
|
||||
var h1 = f1 * 121666L;
|
||||
var h2 = f2 * 121666L;
|
||||
var h3 = f3 * 121666L;
|
||||
var h4 = f4 * 121666L;
|
||||
var h5 = f5 * 121666L;
|
||||
var h6 = f6 * 121666L;
|
||||
var h7 = f7 * 121666L;
|
||||
var h8 = f8 * 121666L;
|
||||
var h9 = f9 * 121666L;
|
||||
|
||||
var carry9 = (h9 + (1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
|
||||
var carry1 = (h1 + (1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
|
||||
var carry3 = (h3 + (1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
|
||||
var carry5 = (h5 + (1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
|
||||
var carry7 = (h7 + (1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
|
||||
|
||||
var carry0 = (h0 + (1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
var carry2 = (h2 + (1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
|
||||
var carry4 = (h4 + (1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
var carry6 = (h6 + (1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
|
||||
var carry8 = (h8 + (1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
|
||||
|
||||
h.x0 = (int)h0;
|
||||
h.x1 = (int)h1;
|
||||
h.x2 = (int)h2;
|
||||
h.x3 = (int)h3;
|
||||
h.x4 = (int)h4;
|
||||
h.x5 = (int)h5;
|
||||
h.x6 = (int)h6;
|
||||
h.x7 = (int)h7;
|
||||
h.x8 = (int)h8;
|
||||
h.x9 = (int)h9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
h = -f
|
||||
|
||||
Preconditions:
|
||||
|f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
|
||||
Postconditions:
|
||||
|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
*/
|
||||
internal static void fe_neg(out FieldElement h, ref FieldElement f)
|
||||
{
|
||||
int f0 = f.x0;
|
||||
int f1 = f.x1;
|
||||
int f2 = f.x2;
|
||||
int f3 = f.x3;
|
||||
int f4 = f.x4;
|
||||
int f5 = f.x5;
|
||||
int f6 = f.x6;
|
||||
int f7 = f.x7;
|
||||
int f8 = f.x8;
|
||||
int f9 = f.x9;
|
||||
int h0 = -f0;
|
||||
int h1 = -f1;
|
||||
int h2 = -f2;
|
||||
int h3 = -f3;
|
||||
int h4 = -f4;
|
||||
int h5 = -f5;
|
||||
int h6 = -f6;
|
||||
int h7 = -f7;
|
||||
int h8 = -f8;
|
||||
int h9 = -f9;
|
||||
|
||||
h.x0 = h0;
|
||||
h.x1 = h1;
|
||||
h.x2 = h2;
|
||||
h.x3 = h3;
|
||||
h.x4 = h4;
|
||||
h.x5 = h5;
|
||||
h.x6 = h6;
|
||||
h.x7 = h7;
|
||||
h.x8 = h8;
|
||||
h.x9 = h9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
internal static void fe_pow22523(out FieldElement result, ref FieldElement z)
|
||||
{
|
||||
FieldElement t0, t1, t2;
|
||||
int i;
|
||||
|
||||
/* qhasm: z2 = z1^2^1 */
|
||||
/* asm 1: fe_sq(>z2=fe#1,<z1=fe#11); for (i = 1;i < 1;++i) fe_sq(>z2=fe#1,>z2=fe#1); */
|
||||
/* asm 2: fe_sq(>z2=t0,<z1=z); for (i = 1;i < 1;++i) fe_sq(>z2=t0,>z2=t0); */
|
||||
fe_sq(out t0, ref z); //for (i = 1; i < 1; ++i) fe_sq(out t0, ref t0);
|
||||
|
||||
/* qhasm: z8 = z2^2^2 */
|
||||
/* asm 1: fe_sq(>z8=fe#2,<z2=fe#1); for (i = 1;i < 2;++i) fe_sq(>z8=fe#2,>z8=fe#2); */
|
||||
/* asm 2: fe_sq(>z8=t1,<z2=t0); for (i = 1;i < 2;++i) fe_sq(>z8=t1,>z8=t1); */
|
||||
fe_sq(out t1, ref t0); for (i = 1; i < 2; ++i) fe_sq(out t1, ref t1);
|
||||
|
||||
/* qhasm: z9 = z1*z8 */
|
||||
/* asm 1: fe_mul(>z9=fe#2,<z1=fe#11,<z8=fe#2); */
|
||||
/* asm 2: fe_mul(>z9=t1,<z1=z,<z8=t1); */
|
||||
fe_mul(out t1, ref z, ref t1);
|
||||
|
||||
/* qhasm: z11 = z2*z9 */
|
||||
/* asm 1: fe_mul(>z11=fe#1,<z2=fe#1,<z9=fe#2); */
|
||||
/* asm 2: fe_mul(>z11=t0,<z2=t0,<z9=t1); */
|
||||
fe_mul(out t0, ref t0, ref t1);
|
||||
|
||||
/* qhasm: z22 = z11^2^1 */
|
||||
/* asm 1: fe_sq(>z22=fe#1,<z11=fe#1); for (i = 1;i < 1;++i) fe_sq(>z22=fe#1,>z22=fe#1); */
|
||||
/* asm 2: fe_sq(>z22=t0,<z11=t0); for (i = 1;i < 1;++i) fe_sq(>z22=t0,>z22=t0); */
|
||||
fe_sq(out t0, ref t0); //for (i = 1; i < 1; ++i) fe_sq(out t0, ref t0);
|
||||
|
||||
/* qhasm: z_5_0 = z9*z22 */
|
||||
/* asm 1: fe_mul(>z_5_0=fe#1,<z9=fe#2,<z22=fe#1); */
|
||||
/* asm 2: fe_mul(>z_5_0=t0,<z9=t1,<z22=t0); */
|
||||
fe_mul(out t0, ref t1, ref t0);
|
||||
|
||||
/* qhasm: z_10_5 = z_5_0^2^5 */
|
||||
/* asm 1: fe_sq(>z_10_5=fe#2,<z_5_0=fe#1); for (i = 1;i < 5;++i) fe_sq(>z_10_5=fe#2,>z_10_5=fe#2); */
|
||||
/* asm 2: fe_sq(>z_10_5=t1,<z_5_0=t0); for (i = 1;i < 5;++i) fe_sq(>z_10_5=t1,>z_10_5=t1); */
|
||||
fe_sq(out t1, ref t0); for (i = 1; i < 5; ++i) fe_sq(out t1, ref t1);
|
||||
|
||||
/* qhasm: z_10_0 = z_10_5*z_5_0 */
|
||||
/* asm 1: fe_mul(>z_10_0=fe#1,<z_10_5=fe#2,<z_5_0=fe#1); */
|
||||
/* asm 2: fe_mul(>z_10_0=t0,<z_10_5=t1,<z_5_0=t0); */
|
||||
fe_mul(out t0, ref t1, ref t0);
|
||||
|
||||
/* qhasm: z_20_10 = z_10_0^2^10 */
|
||||
/* asm 1: fe_sq(>z_20_10=fe#2,<z_10_0=fe#1); for (i = 1;i < 10;++i) fe_sq(>z_20_10=fe#2,>z_20_10=fe#2); */
|
||||
/* asm 2: fe_sq(>z_20_10=t1,<z_10_0=t0); for (i = 1;i < 10;++i) fe_sq(>z_20_10=t1,>z_20_10=t1); */
|
||||
fe_sq(out t1, ref t0); for (i = 1; i < 10; ++i) fe_sq(out t1, ref t1);
|
||||
|
||||
/* qhasm: z_20_0 = z_20_10*z_10_0 */
|
||||
/* asm 1: fe_mul(>z_20_0=fe#2,<z_20_10=fe#2,<z_10_0=fe#1); */
|
||||
/* asm 2: fe_mul(>z_20_0=t1,<z_20_10=t1,<z_10_0=t0); */
|
||||
fe_mul(out t1, ref t1, ref t0);
|
||||
|
||||
/* qhasm: z_40_20 = z_20_0^2^20 */
|
||||
/* asm 1: fe_sq(>z_40_20=fe#3,<z_20_0=fe#2); for (i = 1;i < 20;++i) fe_sq(>z_40_20=fe#3,>z_40_20=fe#3); */
|
||||
/* asm 2: fe_sq(>z_40_20=t2,<z_20_0=t1); for (i = 1;i < 20;++i) fe_sq(>z_40_20=t2,>z_40_20=t2); */
|
||||
fe_sq(out t2, ref t1); for (i = 1; i < 20; ++i) fe_sq(out t2, ref t2);
|
||||
|
||||
/* qhasm: z_40_0 = z_40_20*z_20_0 */
|
||||
/* asm 1: fe_mul(>z_40_0=fe#2,<z_40_20=fe#3,<z_20_0=fe#2); */
|
||||
/* asm 2: fe_mul(>z_40_0=t1,<z_40_20=t2,<z_20_0=t1); */
|
||||
fe_mul(out t1, ref t2, ref t1);
|
||||
|
||||
/* qhasm: z_50_10 = z_40_0^2^10 */
|
||||
/* asm 1: fe_sq(>z_50_10=fe#2,<z_40_0=fe#2); for (i = 1;i < 10;++i) fe_sq(>z_50_10=fe#2,>z_50_10=fe#2); */
|
||||
/* asm 2: fe_sq(>z_50_10=t1,<z_40_0=t1); for (i = 1;i < 10;++i) fe_sq(>z_50_10=t1,>z_50_10=t1); */
|
||||
fe_sq(out t1, ref t1); for (i = 1; i < 10; ++i) fe_sq(out t1, ref t1);
|
||||
|
||||
/* qhasm: z_50_0 = z_50_10*z_10_0 */
|
||||
/* asm 1: fe_mul(>z_50_0=fe#1,<z_50_10=fe#2,<z_10_0=fe#1); */
|
||||
/* asm 2: fe_mul(>z_50_0=t0,<z_50_10=t1,<z_10_0=t0); */
|
||||
fe_mul(out t0, ref t1, ref t0);
|
||||
|
||||
/* qhasm: z_100_50 = z_50_0^2^50 */
|
||||
/* asm 1: fe_sq(>z_100_50=fe#2,<z_50_0=fe#1); for (i = 1;i < 50;++i) fe_sq(>z_100_50=fe#2,>z_100_50=fe#2); */
|
||||
/* asm 2: fe_sq(>z_100_50=t1,<z_50_0=t0); for (i = 1;i < 50;++i) fe_sq(>z_100_50=t1,>z_100_50=t1); */
|
||||
fe_sq(out t1, ref t0); for (i = 1; i < 50; ++i) fe_sq(out t1, ref t1);
|
||||
|
||||
/* qhasm: z_100_0 = z_100_50*z_50_0 */
|
||||
/* asm 1: fe_mul(>z_100_0=fe#2,<z_100_50=fe#2,<z_50_0=fe#1); */
|
||||
/* asm 2: fe_mul(>z_100_0=t1,<z_100_50=t1,<z_50_0=t0); */
|
||||
fe_mul(out t1, ref t1, ref t0);
|
||||
|
||||
/* qhasm: z_200_100 = z_100_0^2^100 */
|
||||
/* asm 1: fe_sq(>z_200_100=fe#3,<z_100_0=fe#2); for (i = 1;i < 100;++i) fe_sq(>z_200_100=fe#3,>z_200_100=fe#3); */
|
||||
/* asm 2: fe_sq(>z_200_100=t2,<z_100_0=t1); for (i = 1;i < 100;++i) fe_sq(>z_200_100=t2,>z_200_100=t2); */
|
||||
fe_sq(out t2, ref t1); for (i = 1; i < 100; ++i) fe_sq(out t2, ref t2);
|
||||
|
||||
/* qhasm: z_200_0 = z_200_100*z_100_0 */
|
||||
/* asm 1: fe_mul(>z_200_0=fe#2,<z_200_100=fe#3,<z_100_0=fe#2); */
|
||||
/* asm 2: fe_mul(>z_200_0=t1,<z_200_100=t2,<z_100_0=t1); */
|
||||
fe_mul(out t1, ref t2, ref t1);
|
||||
|
||||
/* qhasm: z_250_50 = z_200_0^2^50 */
|
||||
/* asm 1: fe_sq(>z_250_50=fe#2,<z_200_0=fe#2); for (i = 1;i < 50;++i) fe_sq(>z_250_50=fe#2,>z_250_50=fe#2); */
|
||||
/* asm 2: fe_sq(>z_250_50=t1,<z_200_0=t1); for (i = 1;i < 50;++i) fe_sq(>z_250_50=t1,>z_250_50=t1); */
|
||||
fe_sq(out t1, ref t1); for (i = 1; i < 50; ++i) fe_sq(out t1, ref t1);
|
||||
|
||||
/* qhasm: z_250_0 = z_250_50*z_50_0 */
|
||||
/* asm 1: fe_mul(>z_250_0=fe#1,<z_250_50=fe#2,<z_50_0=fe#1); */
|
||||
/* asm 2: fe_mul(>z_250_0=t0,<z_250_50=t1,<z_50_0=t0); */
|
||||
fe_mul(out t0, ref t1, ref t0);
|
||||
|
||||
/* qhasm: z_252_2 = z_250_0^2^2 */
|
||||
/* asm 1: fe_sq(>z_252_2=fe#1,<z_250_0=fe#1); for (i = 1;i < 2;++i) fe_sq(>z_252_2=fe#1,>z_252_2=fe#1); */
|
||||
/* asm 2: fe_sq(>z_252_2=t0,<z_250_0=t0); for (i = 1;i < 2;++i) fe_sq(>z_252_2=t0,>z_252_2=t0); */
|
||||
fe_sq(out t0, ref t0); for (i = 1; i < 2; ++i) fe_sq(out t0, ref t0);
|
||||
|
||||
/* qhasm: z_252_3 = z_252_2*z1 */
|
||||
/* asm 1: fe_mul(>z_252_3=fe#12,<z_252_2=fe#1,<z1=fe#11); */
|
||||
/* asm 2: fe_mul(>z_252_3=out,<z_252_2=t0,<z1=z); */
|
||||
fe_mul(out result, ref t0, ref z);
|
||||
|
||||
/* qhasm: return */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
h = f * f
|
||||
Can overlap h with f.
|
||||
|
||||
Preconditions:
|
||||
|f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
|
||||
|
||||
Postconditions:
|
||||
|h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
|
||||
*/
|
||||
|
||||
/*
|
||||
See fe_mul.c for discussion of implementation strategy.
|
||||
*/
|
||||
internal static void fe_sq(out FieldElement h, ref FieldElement f)
|
||||
{
|
||||
int f0 = f.x0;
|
||||
int f1 = f.x1;
|
||||
int f2 = f.x2;
|
||||
int f3 = f.x3;
|
||||
int f4 = f.x4;
|
||||
int f5 = f.x5;
|
||||
int f6 = f.x6;
|
||||
int f7 = f.x7;
|
||||
int f8 = f.x8;
|
||||
int f9 = f.x9;
|
||||
|
||||
int f0_2 = 2 * f0;
|
||||
int f1_2 = 2 * f1;
|
||||
int f2_2 = 2 * f2;
|
||||
int f3_2 = 2 * f3;
|
||||
int f4_2 = 2 * f4;
|
||||
int f5_2 = 2 * f5;
|
||||
int f6_2 = 2 * f6;
|
||||
int f7_2 = 2 * f7;
|
||||
int f5_38 = 38 * f5; /* 1.959375*2^30 */
|
||||
int f6_19 = 19 * f6; /* 1.959375*2^30 */
|
||||
int f7_38 = 38 * f7; /* 1.959375*2^30 */
|
||||
int f8_19 = 19 * f8; /* 1.959375*2^30 */
|
||||
int f9_38 = 38 * f9; /* 1.959375*2^30 */
|
||||
|
||||
var f0f0 = f0 * (long)f0;
|
||||
var f0f1_2 = f0_2 * (long)f1;
|
||||
var f0f2_2 = f0_2 * (long)f2;
|
||||
var f0f3_2 = f0_2 * (long)f3;
|
||||
var f0f4_2 = f0_2 * (long)f4;
|
||||
var f0f5_2 = f0_2 * (long)f5;
|
||||
var f0f6_2 = f0_2 * (long)f6;
|
||||
var f0f7_2 = f0_2 * (long)f7;
|
||||
var f0f8_2 = f0_2 * (long)f8;
|
||||
var f0f9_2 = f0_2 * (long)f9;
|
||||
var f1f1_2 = f1_2 * (long)f1;
|
||||
var f1f2_2 = f1_2 * (long)f2;
|
||||
var f1f3_4 = f1_2 * (long)f3_2;
|
||||
var f1f4_2 = f1_2 * (long)f4;
|
||||
var f1f5_4 = f1_2 * (long)f5_2;
|
||||
var f1f6_2 = f1_2 * (long)f6;
|
||||
var f1f7_4 = f1_2 * (long)f7_2;
|
||||
var f1f8_2 = f1_2 * (long)f8;
|
||||
var f1f9_76 = f1_2 * (long)f9_38;
|
||||
var f2f2 = f2 * (long)f2;
|
||||
var f2f3_2 = f2_2 * (long)f3;
|
||||
var f2f4_2 = f2_2 * (long)f4;
|
||||
var f2f5_2 = f2_2 * (long)f5;
|
||||
var f2f6_2 = f2_2 * (long)f6;
|
||||
var f2f7_2 = f2_2 * (long)f7;
|
||||
var f2f8_38 = f2_2 * (long)f8_19;
|
||||
var f2f9_38 = f2 * (long)f9_38;
|
||||
var f3f3_2 = f3_2 * (long)f3;
|
||||
var f3f4_2 = f3_2 * (long)f4;
|
||||
var f3f5_4 = f3_2 * (long)f5_2;
|
||||
var f3f6_2 = f3_2 * (long)f6;
|
||||
var f3f7_76 = f3_2 * (long)f7_38;
|
||||
var f3f8_38 = f3_2 * (long)f8_19;
|
||||
var f3f9_76 = f3_2 * (long)f9_38;
|
||||
var f4f4 = f4 * (long)f4;
|
||||
var f4f5_2 = f4_2 * (long)f5;
|
||||
var f4f6_38 = f4_2 * (long)f6_19;
|
||||
var f4f7_38 = f4 * (long)f7_38;
|
||||
var f4f8_38 = f4_2 * (long)f8_19;
|
||||
var f4f9_38 = f4 * (long)f9_38;
|
||||
var f5f5_38 = f5 * (long)f5_38;
|
||||
var f5f6_38 = f5_2 * (long)f6_19;
|
||||
var f5f7_76 = f5_2 * (long)f7_38;
|
||||
var f5f8_38 = f5_2 * (long)f8_19;
|
||||
var f5f9_76 = f5_2 * (long)f9_38;
|
||||
var f6f6_19 = f6 * (long)f6_19;
|
||||
var f6f7_38 = f6 * (long)f7_38;
|
||||
var f6f8_38 = f6_2 * (long)f8_19;
|
||||
var f6f9_38 = f6 * (long)f9_38;
|
||||
var f7f7_38 = f7 * (long)f7_38;
|
||||
var f7f8_38 = f7_2 * (long)f8_19;
|
||||
var f7f9_76 = f7_2 * (long)f9_38;
|
||||
var f8f8_19 = f8 * (long)f8_19;
|
||||
var f8f9_38 = f8 * (long)f9_38;
|
||||
var f9f9_38 = f9 * (long)f9_38;
|
||||
|
||||
var h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
|
||||
var h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
|
||||
var h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
|
||||
var h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
|
||||
var h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
|
||||
var h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
|
||||
var h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
|
||||
var h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
|
||||
var h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
|
||||
var h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
|
||||
|
||||
var carry0 = (h0 + (1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
var carry4 = (h4 + (1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
var carry1 = (h1 + (1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
|
||||
var carry5 = (h5 + (1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
|
||||
var carry2 = (h2 + (1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
|
||||
var carry6 = (h6 + (1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
|
||||
var carry3 = (h3 + (1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
|
||||
var carry7 = (h7 + (1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
|
||||
|
||||
carry4 = (h4 + (1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
|
||||
var carry8 = (h8 + (1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
|
||||
var carry9 = (h9 + (1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
|
||||
|
||||
carry0 = (h0 + (1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
|
||||
h.x0 = (int)h0;
|
||||
h.x1 = (int)h1;
|
||||
h.x2 = (int)h2;
|
||||
h.x3 = (int)h3;
|
||||
h.x4 = (int)h4;
|
||||
h.x5 = (int)h5;
|
||||
h.x6 = (int)h6;
|
||||
h.x7 = (int)h7;
|
||||
h.x8 = (int)h8;
|
||||
h.x9 = (int)h9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
h = 2 * f * f
|
||||
Can overlap h with f.
|
||||
|
||||
Preconditions:
|
||||
|f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
|
||||
|
||||
Postconditions:
|
||||
|h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
|
||||
*/
|
||||
|
||||
/*
|
||||
See fe_mul.c for discussion of implementation strategy.
|
||||
*/
|
||||
internal static void fe_sq2(out FieldElement h, ref FieldElement f)
|
||||
{
|
||||
int f0 = f.x0;
|
||||
int f1 = f.x1;
|
||||
int f2 = f.x2;
|
||||
int f3 = f.x3;
|
||||
int f4 = f.x4;
|
||||
int f5 = f.x5;
|
||||
int f6 = f.x6;
|
||||
int f7 = f.x7;
|
||||
int f8 = f.x8;
|
||||
int f9 = f.x9;
|
||||
|
||||
int f0_2 = 2 * f0;
|
||||
int f1_2 = 2 * f1;
|
||||
int f2_2 = 2 * f2;
|
||||
int f3_2 = 2 * f3;
|
||||
int f4_2 = 2 * f4;
|
||||
int f5_2 = 2 * f5;
|
||||
int f6_2 = 2 * f6;
|
||||
int f7_2 = 2 * f7;
|
||||
int f5_38 = 38 * f5; /* 1.959375*2^30 */
|
||||
int f6_19 = 19 * f6; /* 1.959375*2^30 */
|
||||
int f7_38 = 38 * f7; /* 1.959375*2^30 */
|
||||
int f8_19 = 19 * f8; /* 1.959375*2^30 */
|
||||
int f9_38 = 38 * f9; /* 1.959375*2^30 */
|
||||
|
||||
var f0f0 = f0 * (long)f0;
|
||||
var f0f1_2 = f0_2 * (long)f1;
|
||||
var f0f2_2 = f0_2 * (long)f2;
|
||||
var f0f3_2 = f0_2 * (long)f3;
|
||||
var f0f4_2 = f0_2 * (long)f4;
|
||||
var f0f5_2 = f0_2 * (long)f5;
|
||||
var f0f6_2 = f0_2 * (long)f6;
|
||||
var f0f7_2 = f0_2 * (long)f7;
|
||||
var f0f8_2 = f0_2 * (long)f8;
|
||||
var f0f9_2 = f0_2 * (long)f9;
|
||||
var f1f1_2 = f1_2 * (long)f1;
|
||||
var f1f2_2 = f1_2 * (long)f2;
|
||||
var f1f3_4 = f1_2 * (long)f3_2;
|
||||
var f1f4_2 = f1_2 * (long)f4;
|
||||
var f1f5_4 = f1_2 * (long)f5_2;
|
||||
var f1f6_2 = f1_2 * (long)f6;
|
||||
var f1f7_4 = f1_2 * (long)f7_2;
|
||||
var f1f8_2 = f1_2 * (long)f8;
|
||||
var f1f9_76 = f1_2 * (long)f9_38;
|
||||
var f2f2 = f2 * (long)f2;
|
||||
var f2f3_2 = f2_2 * (long)f3;
|
||||
var f2f4_2 = f2_2 * (long)f4;
|
||||
var f2f5_2 = f2_2 * (long)f5;
|
||||
var f2f6_2 = f2_2 * (long)f6;
|
||||
var f2f7_2 = f2_2 * (long)f7;
|
||||
var f2f8_38 = f2_2 * (long)f8_19;
|
||||
var f2f9_38 = f2 * (long)f9_38;
|
||||
var f3f3_2 = f3_2 * (long)f3;
|
||||
var f3f4_2 = f3_2 * (long)f4;
|
||||
var f3f5_4 = f3_2 * (long)f5_2;
|
||||
var f3f6_2 = f3_2 * (long)f6;
|
||||
var f3f7_76 = f3_2 * (long)f7_38;
|
||||
var f3f8_38 = f3_2 * (long)f8_19;
|
||||
var f3f9_76 = f3_2 * (long)f9_38;
|
||||
var f4f4 = f4 * (long)f4;
|
||||
var f4f5_2 = f4_2 * (long)f5;
|
||||
var f4f6_38 = f4_2 * (long)f6_19;
|
||||
var f4f7_38 = f4 * (long)f7_38;
|
||||
var f4f8_38 = f4_2 * (long)f8_19;
|
||||
var f4f9_38 = f4 * (long)f9_38;
|
||||
var f5f5_38 = f5 * (long)f5_38;
|
||||
var f5f6_38 = f5_2 * (long)f6_19;
|
||||
var f5f7_76 = f5_2 * (long)f7_38;
|
||||
var f5f8_38 = f5_2 * (long)f8_19;
|
||||
var f5f9_76 = f5_2 * (long)f9_38;
|
||||
var f6f6_19 = f6 * (long)f6_19;
|
||||
var f6f7_38 = f6 * (long)f7_38;
|
||||
var f6f8_38 = f6_2 * (long)f8_19;
|
||||
var f6f9_38 = f6 * (long)f9_38;
|
||||
var f7f7_38 = f7 * (long)f7_38;
|
||||
var f7f8_38 = f7_2 * (long)f8_19;
|
||||
var f7f9_76 = f7_2 * (long)f9_38;
|
||||
var f8f8_19 = f8 * (long)f8_19;
|
||||
var f8f9_38 = f8 * (long)f9_38;
|
||||
var f9f9_38 = f9 * (long)f9_38;
|
||||
|
||||
var h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
|
||||
var h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
|
||||
var h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
|
||||
var h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
|
||||
var h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
|
||||
var h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
|
||||
var h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
|
||||
var h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
|
||||
var h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
|
||||
var h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
|
||||
|
||||
h0 += h0;
|
||||
h1 += h1;
|
||||
h2 += h2;
|
||||
h3 += h3;
|
||||
h4 += h4;
|
||||
h5 += h5;
|
||||
h6 += h6;
|
||||
h7 += h7;
|
||||
h8 += h8;
|
||||
h9 += h9;
|
||||
|
||||
var carry0 = (h0 + (1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
var carry4 = (h4 + (1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
var carry1 = (h1 + (1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
|
||||
var carry5 = (h5 + (1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
|
||||
var carry2 = (h2 + (1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
|
||||
var carry6 = (h6 + (1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
|
||||
var carry3 = (h3 + (1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
|
||||
var carry7 = (h7 + (1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
|
||||
|
||||
carry4 = (h4 + (1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
|
||||
var carry8 = (h8 + (1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
|
||||
var carry9 = (h9 + (1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
|
||||
|
||||
carry0 = (h0 + (1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
|
||||
h.x0 = (int)h0;
|
||||
h.x1 = (int)h1;
|
||||
h.x2 = (int)h2;
|
||||
h.x3 = (int)h3;
|
||||
h.x4 = (int)h4;
|
||||
h.x5 = (int)h5;
|
||||
h.x6 = (int)h6;
|
||||
h.x7 = (int)h7;
|
||||
h.x8 = (int)h8;
|
||||
h.x9 = (int)h9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
h = f - g
|
||||
Can overlap h with f or g.
|
||||
|
||||
Preconditions:
|
||||
|f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
|g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
|
||||
Postconditions:
|
||||
|h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
*/
|
||||
|
||||
internal static void fe_sub(out FieldElement h, ref FieldElement f, ref FieldElement g)
|
||||
{
|
||||
int f0 = f.x0;
|
||||
int f1 = f.x1;
|
||||
int f2 = f.x2;
|
||||
int f3 = f.x3;
|
||||
int f4 = f.x4;
|
||||
int f5 = f.x5;
|
||||
int f6 = f.x6;
|
||||
int f7 = f.x7;
|
||||
int f8 = f.x8;
|
||||
int f9 = f.x9;
|
||||
|
||||
int g0 = g.x0;
|
||||
int g1 = g.x1;
|
||||
int g2 = g.x2;
|
||||
int g3 = g.x3;
|
||||
int g4 = g.x4;
|
||||
int g5 = g.x5;
|
||||
int g6 = g.x6;
|
||||
int g7 = g.x7;
|
||||
int g8 = g.x8;
|
||||
int g9 = g.x9;
|
||||
|
||||
int h0 = f0 - g0;
|
||||
int h1 = f1 - g1;
|
||||
int h2 = f2 - g2;
|
||||
int h3 = f3 - g3;
|
||||
int h4 = f4 - g4;
|
||||
int h5 = f5 - g5;
|
||||
int h6 = f6 - g6;
|
||||
int h7 = f7 - g7;
|
||||
int h8 = f8 - g8;
|
||||
int h9 = f9 - g9;
|
||||
|
||||
h.x0 = h0;
|
||||
h.x1 = h1;
|
||||
h.x2 = h2;
|
||||
h.x3 = h3;
|
||||
h.x4 = h4;
|
||||
h.x5 = h5;
|
||||
h.x6 = h6;
|
||||
h.x7 = h7;
|
||||
h.x8 = h8;
|
||||
h.x9 = h9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class FieldOperations
|
||||
{
|
||||
/*
|
||||
Preconditions:
|
||||
|h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
|
||||
Write p=2^255-19; q=floor(h/p).
|
||||
Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
|
||||
|
||||
Proof:
|
||||
Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
|
||||
Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
|
||||
|
||||
Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
|
||||
Then 0<y<1.
|
||||
|
||||
Write r=h-pq.
|
||||
Have 0<=r<=p-1=2^255-20.
|
||||
Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
|
||||
|
||||
Write x=r+19(2^-255)r+y.
|
||||
Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
|
||||
|
||||
Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
|
||||
so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
|
||||
*/
|
||||
internal static void fe_tobytes(byte[] s, int offset, ref FieldElement h)
|
||||
{
|
||||
FieldElement hr;
|
||||
fe_reduce(out hr, ref h);
|
||||
|
||||
int h0 = hr.x0;
|
||||
int h1 = hr.x1;
|
||||
int h2 = hr.x2;
|
||||
int h3 = hr.x3;
|
||||
int h4 = hr.x4;
|
||||
int h5 = hr.x5;
|
||||
int h6 = hr.x6;
|
||||
int h7 = hr.x7;
|
||||
int h8 = hr.x8;
|
||||
int h9 = hr.x9;
|
||||
|
||||
/*
|
||||
Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
|
||||
Have h0+...+2^230 h9 between 0 and 2^255-1;
|
||||
evidently 2^255 h10-2^255 q = 0.
|
||||
Goal: Output h0+...+2^230 h9.
|
||||
*/
|
||||
unchecked
|
||||
{
|
||||
s[offset + 0] = (byte) (h0 >> 0);
|
||||
s[offset + 1] = (byte) (h0 >> 8);
|
||||
s[offset + 2] = (byte) (h0 >> 16);
|
||||
s[offset + 3] = (byte) ((h0 >> 24) | (h1 << 2));
|
||||
s[offset + 4] = (byte) (h1 >> 6);
|
||||
s[offset + 5] = (byte) (h1 >> 14);
|
||||
s[offset + 6] = (byte) ((h1 >> 22) | (h2 << 3));
|
||||
s[offset + 7] = (byte) (h2 >> 5);
|
||||
s[offset + 8] = (byte) (h2 >> 13);
|
||||
s[offset + 9] = (byte) ((h2 >> 21) | (h3 << 5));
|
||||
s[offset + 10] = (byte) (h3 >> 3);
|
||||
s[offset + 11] = (byte) (h3 >> 11);
|
||||
s[offset + 12] = (byte) ((h3 >> 19) | (h4 << 6));
|
||||
s[offset + 13] = (byte) (h4 >> 2);
|
||||
s[offset + 14] = (byte) (h4 >> 10);
|
||||
s[offset + 15] = (byte) (h4 >> 18);
|
||||
s[offset + 16] = (byte) (h5 >> 0);
|
||||
s[offset + 17] = (byte) (h5 >> 8);
|
||||
s[offset + 18] = (byte) (h5 >> 16);
|
||||
s[offset + 19] = (byte) ((h5 >> 24) | (h6 << 1));
|
||||
s[offset + 20] = (byte) (h6 >> 7);
|
||||
s[offset + 21] = (byte) (h6 >> 15);
|
||||
s[offset + 22] = (byte) ((h6 >> 23) | (h7 << 3));
|
||||
s[offset + 23] = (byte) (h7 >> 5);
|
||||
s[offset + 24] = (byte) (h7 >> 13);
|
||||
s[offset + 25] = (byte) ((h7 >> 21) | (h8 << 4));
|
||||
s[offset + 26] = (byte) (h8 >> 4);
|
||||
s[offset + 27] = (byte) (h8 >> 12);
|
||||
s[offset + 28] = (byte) ((h8 >> 20) | (h9 << 6));
|
||||
s[offset + 29] = (byte) (h9 >> 2);
|
||||
s[offset + 30] = (byte) (h9 >> 10);
|
||||
s[offset + 31] = (byte) (h9 >> 18);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void fe_reduce(out FieldElement hr, ref FieldElement h)
|
||||
{
|
||||
int h0 = h.x0;
|
||||
int h1 = h.x1;
|
||||
int h2 = h.x2;
|
||||
int h3 = h.x3;
|
||||
int h4 = h.x4;
|
||||
int h5 = h.x5;
|
||||
int h6 = h.x6;
|
||||
int h7 = h.x7;
|
||||
int h8 = h.x8;
|
||||
int h9 = h.x9;
|
||||
|
||||
int q;
|
||||
|
||||
q = (19 * h9 + (1 << 24)) >> 25;
|
||||
q = (h0 + q) >> 26;
|
||||
q = (h1 + q) >> 25;
|
||||
q = (h2 + q) >> 26;
|
||||
q = (h3 + q) >> 25;
|
||||
q = (h4 + q) >> 26;
|
||||
q = (h5 + q) >> 25;
|
||||
q = (h6 + q) >> 26;
|
||||
q = (h7 + q) >> 25;
|
||||
q = (h8 + q) >> 26;
|
||||
q = (h9 + q) >> 25;
|
||||
|
||||
/* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
|
||||
h0 += 19 * q;
|
||||
/* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
|
||||
|
||||
var carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;
|
||||
var carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;
|
||||
var carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;
|
||||
var carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;
|
||||
var carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;
|
||||
var carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;
|
||||
var carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;
|
||||
var carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;
|
||||
var carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;
|
||||
var carry9 = h9 >> 25; h9 -= carry9 << 25;
|
||||
/* h10 = carry9 */
|
||||
|
||||
hr.x0 = h0;
|
||||
hr.x1 = h1;
|
||||
hr.x2 = h2;
|
||||
hr.x3 = h3;
|
||||
hr.x4 = h4;
|
||||
hr.x5 = h5;
|
||||
hr.x6 = h6;
|
||||
hr.x7 = h7;
|
||||
hr.x8 = h8;
|
||||
hr.x9 = h9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
/*
|
||||
r = p + q
|
||||
*/
|
||||
|
||||
internal static void ge_add(out GroupElementP1P1 r, ref GroupElementP3 p, ref GroupElementCached q)
|
||||
{
|
||||
FieldElement t0;
|
||||
|
||||
/* qhasm: YpX1 = Y1+X1 */
|
||||
/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
|
||||
/* asm 2: fe_add(>YpX1=r.X,<Y1=p.Y,<X1=p.X); */
|
||||
FieldOperations.fe_add(out r.X, ref p.Y, ref p.X);
|
||||
|
||||
/* qhasm: YmX1 = Y1-X1 */
|
||||
/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
|
||||
/* asm 2: fe_sub(>YmX1=r.Y,<Y1=p.Y,<X1=p.X); */
|
||||
FieldOperations.fe_sub(out r.Y, ref p.Y, ref p.X);
|
||||
|
||||
/* qhasm: A = YpX1*YpX2 */
|
||||
/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<YpX2=fe#15); */
|
||||
/* asm 2: fe_mul(>A=r.Z,<YpX1=r.X,<YpX2=q.YplusX); */
|
||||
FieldOperations.fe_mul(out r.Z, ref r.X, ref q.YplusX);
|
||||
|
||||
/* qhasm: B = YmX1*YmX2 */
|
||||
/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<YmX2=fe#16); */
|
||||
/* asm 2: fe_mul(>B=r.Y,<YmX1=r.Y,<YmX2=q.YminusX); */
|
||||
FieldOperations.fe_mul(out r.Y, ref r.Y, ref q.YminusX);
|
||||
|
||||
/* qhasm: C = T2d2*T1 */
|
||||
/* asm 1: fe_mul(>C=fe#4,<T2d2=fe#18,<T1=fe#14); */
|
||||
/* asm 2: fe_mul(>C=r.T,<T2d2=q.T2d,<T1=p.T); */
|
||||
FieldOperations.fe_mul(out r.T, ref q.T2d, ref p.T);
|
||||
|
||||
/* qhasm: ZZ = Z1*Z2 */
|
||||
/* asm 1: fe_mul(>ZZ=fe#1,<Z1=fe#13,<Z2=fe#17); */
|
||||
/* asm 2: fe_mul(>ZZ=r.X,<Z1=p.Z,<Z2=q.Z); */
|
||||
FieldOperations.fe_mul(out r.X, ref p.Z, ref q.Z);
|
||||
|
||||
/* qhasm: D = 2*ZZ */
|
||||
/* asm 1: fe_add(>D=fe#5,<ZZ=fe#1,<ZZ=fe#1); */
|
||||
/* asm 2: fe_add(>D=t0,<ZZ=r.X,<ZZ=r.X); */
|
||||
FieldOperations.fe_add(out t0, ref r.X, ref r.X);
|
||||
|
||||
/* qhasm: X3 = A-B */
|
||||
/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
|
||||
/* asm 2: fe_sub(>X3=r.X,<A=r.Z,<B=r.Y); */
|
||||
FieldOperations.fe_sub(out r.X, ref r.Z, ref r.Y);
|
||||
|
||||
/* qhasm: Y3 = A+B */
|
||||
/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
|
||||
/* asm 2: fe_add(>Y3=r.Y,<A=r.Z,<B=r.Y); */
|
||||
FieldOperations.fe_add(out r.Y, ref r.Z, ref r.Y);
|
||||
|
||||
/* qhasm: Z3 = D+C */
|
||||
/* asm 1: fe_add(>Z3=fe#3,<D=fe#5,<C=fe#4); */
|
||||
/* asm 2: fe_add(>Z3=r.Z,<D=t0,<C=r.T); */
|
||||
FieldOperations.fe_add(out r.Z, ref t0, ref r.T);
|
||||
|
||||
/* qhasm: T3 = D-C */
|
||||
/* asm 1: fe_sub(>T3=fe#4,<D=fe#5,<C=fe#4); */
|
||||
/* asm 2: fe_sub(>T3=r.T,<D=t0,<C=r.T); */
|
||||
FieldOperations.fe_sub(out r.T, ref t0, ref r.T);
|
||||
|
||||
/* qhasm: return */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
private static void slide(sbyte[] r, byte[] a)
|
||||
{
|
||||
for (int i = 0; i < 256; ++i)
|
||||
r[i] = (sbyte)(1 & (a[i >> 3] >> (i & 7)));
|
||||
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
if (r[i] != 0)
|
||||
{
|
||||
for (int b = 1; b <= 6 && (i + b) < 256; ++b)
|
||||
{
|
||||
if (r[i + b] != 0)
|
||||
{
|
||||
if (r[i] + (r[i + b] << b) <= 15)
|
||||
{
|
||||
r[i] += (sbyte)(r[i + b] << b); r[i + b] = 0;
|
||||
}
|
||||
else if (r[i] - (r[i + b] << b) >= -15)
|
||||
{
|
||||
r[i] -= (sbyte)(r[i + b] << b);
|
||||
for (int k = i + b; k < 256; ++k)
|
||||
{
|
||||
if (r[k] == 0)
|
||||
{
|
||||
r[k] = 1;
|
||||
break;
|
||||
}
|
||||
r[k] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
r = a * A + b * B
|
||||
where a = a[0]+256*a[1]+...+256^31 a[31].
|
||||
and b = b[0]+256*b[1]+...+256^31 b[31].
|
||||
B is the Ed25519 base point (x,4/5) with x positive.
|
||||
*/
|
||||
|
||||
public static void ge_double_scalarmult_vartime(out GroupElementP2 r, byte[] a, ref GroupElementP3 A, byte[] b)
|
||||
{
|
||||
GroupElementPreComp[] Bi = LookupTables.Base2;
|
||||
// todo: Perhaps remove these allocations?
|
||||
sbyte[] aslide = new sbyte[256];
|
||||
sbyte[] bslide = new sbyte[256];
|
||||
GroupElementCached[] Ai = new GroupElementCached[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
|
||||
GroupElementP1P1 t;
|
||||
GroupElementP3 u;
|
||||
GroupElementP3 A2;
|
||||
int i;
|
||||
|
||||
slide(aslide, a);
|
||||
slide(bslide, b);
|
||||
|
||||
ge_p3_to_cached(out Ai[0], ref A);
|
||||
ge_p3_dbl(out t, ref A); ge_p1p1_to_p3(out A2, ref t);
|
||||
ge_add(out t, ref A2, ref Ai[0]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[1], ref u);
|
||||
ge_add(out t, ref A2, ref Ai[1]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[2], ref u);
|
||||
ge_add(out t, ref A2, ref Ai[2]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[3], ref u);
|
||||
ge_add(out t, ref A2, ref Ai[3]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[4], ref u);
|
||||
ge_add(out t, ref A2, ref Ai[4]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[5], ref u);
|
||||
ge_add(out t, ref A2, ref Ai[5]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[6], ref u);
|
||||
ge_add(out t, ref A2, ref Ai[6]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[7], ref u);
|
||||
|
||||
ge_p2_0(out r);
|
||||
|
||||
for (i = 255; i >= 0; --i)
|
||||
{
|
||||
if ((aslide[i] != 0) || (bslide[i] != 0)) break;
|
||||
}
|
||||
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
ge_p2_dbl(out t, ref r);
|
||||
|
||||
if (aslide[i] > 0)
|
||||
{
|
||||
ge_p1p1_to_p3(out u, ref t);
|
||||
ge_add(out t, ref u, ref Ai[aslide[i] / 2]);
|
||||
}
|
||||
else if (aslide[i] < 0)
|
||||
{
|
||||
ge_p1p1_to_p3(out u, ref t);
|
||||
ge_sub(out t, ref u, ref Ai[(-aslide[i]) / 2]);
|
||||
}
|
||||
|
||||
if (bslide[i] > 0)
|
||||
{
|
||||
ge_p1p1_to_p3(out u, ref t);
|
||||
ge_madd(out t, ref u, ref Bi[bslide[i] / 2]);
|
||||
}
|
||||
else if (bslide[i] < 0)
|
||||
{
|
||||
ge_p1p1_to_p3(out u, ref t);
|
||||
ge_msub(out t, ref u, ref Bi[(-bslide[i]) / 2]);
|
||||
}
|
||||
|
||||
ge_p1p1_to_p2(out r, ref t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
public static int ge_frombytes_negate_vartime(out GroupElementP3 h, byte[] data, int offset)
|
||||
{
|
||||
FieldElement u, v, v3, vxx, check;
|
||||
|
||||
FieldOperations.fe_frombytes(out h.Y, data, offset);
|
||||
FieldOperations.fe_1(out h.Z);
|
||||
FieldOperations.fe_sq(out u, ref h.Y);
|
||||
FieldOperations.fe_mul(out v, ref u, ref LookupTables.d);
|
||||
FieldOperations.fe_sub(out u, ref u, ref h.Z); /* u = y^2-1 */
|
||||
FieldOperations.fe_add(out v, ref v, ref h.Z); /* v = dy^2+1 */
|
||||
|
||||
FieldOperations.fe_sq(out v3, ref v);
|
||||
FieldOperations.fe_mul(out v3, ref v3, ref v); /* v3 = v^3 */
|
||||
FieldOperations.fe_sq(out h.X, ref v3);
|
||||
FieldOperations.fe_mul(out h.X, ref h.X, ref v);
|
||||
FieldOperations.fe_mul(out h.X, ref h.X, ref u); /* x = uv^7 */
|
||||
|
||||
FieldOperations.fe_pow22523(out h.X, ref h.X); /* x = (uv^7)^((q-5)/8) */
|
||||
FieldOperations.fe_mul(out h.X, ref h.X, ref v3);
|
||||
FieldOperations.fe_mul(out h.X, ref h.X, ref u); /* x = uv^3(uv^7)^((q-5)/8) */
|
||||
|
||||
FieldOperations.fe_sq(out vxx, ref h.X);
|
||||
FieldOperations.fe_mul(out vxx, ref vxx, ref v);
|
||||
FieldOperations.fe_sub(out check, ref vxx, ref u); /* vx^2-u */
|
||||
if (FieldOperations.fe_isnonzero(ref check) != 0)
|
||||
{
|
||||
FieldOperations.fe_add(out check, ref vxx, ref u); /* vx^2+u */
|
||||
if (FieldOperations.fe_isnonzero(ref check) != 0)
|
||||
{
|
||||
h = default(GroupElementP3);
|
||||
return -1;
|
||||
}
|
||||
FieldOperations.fe_mul(out h.X, ref h.X, ref LookupTables.sqrtm1);
|
||||
}
|
||||
|
||||
if (FieldOperations.fe_isnegative(ref h.X) == (data[offset + 31] >> 7))
|
||||
FieldOperations.fe_neg(out h.X, ref h.X);
|
||||
|
||||
FieldOperations.fe_mul(out h.T, ref h.X, ref h.Y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
/*
|
||||
r = p + q
|
||||
*/
|
||||
public static void ge_madd(out GroupElementP1P1 r, ref GroupElementP3 p, ref GroupElementPreComp q)
|
||||
{
|
||||
FieldElement t0;
|
||||
|
||||
/* qhasm: YpX1 = Y1+X1 */
|
||||
/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
|
||||
/* asm 2: fe_add(>YpX1=r.X,<Y1=p.Y,<X1=p.X); */
|
||||
FieldOperations.fe_add(out r.X, ref p.Y, ref p.X);
|
||||
|
||||
/* qhasm: YmX1 = Y1-X1 */
|
||||
/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
|
||||
/* asm 2: fe_sub(>YmX1=r.Y,<Y1=p.Y,<X1=p.X); */
|
||||
FieldOperations.fe_sub(out r.Y, ref p.Y, ref p.X);
|
||||
|
||||
/* qhasm: A = YpX1*ypx2 */
|
||||
/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<ypx2=fe#15); */
|
||||
/* asm 2: fe_mul(>A=r.Z,<YpX1=r.X,<ypx2=q.yplusx); */
|
||||
FieldOperations.fe_mul(out r.Z, ref r.X, ref q.yplusx);
|
||||
|
||||
/* qhasm: B = YmX1*ymx2 */
|
||||
/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<ymx2=fe#16); */
|
||||
/* asm 2: fe_mul(>B=r.Y,<YmX1=r.Y,<ymx2=q.yminusx); */
|
||||
FieldOperations.fe_mul(out r.Y, ref r.Y, ref q.yminusx);
|
||||
|
||||
/* qhasm: C = xy2d2*T1 */
|
||||
/* asm 1: fe_mul(>C=fe#4,<xy2d2=fe#17,<T1=fe#14); */
|
||||
/* asm 2: fe_mul(>C=r.T,<xy2d2=q.xy2d,<T1=p.T); */
|
||||
FieldOperations.fe_mul(out r.T, ref q.xy2d, ref p.T);
|
||||
|
||||
/* qhasm: D = 2*Z1 */
|
||||
/* asm 1: fe_add(>D=fe#5,<Z1=fe#13,<Z1=fe#13); */
|
||||
/* asm 2: fe_add(>D=t0,<Z1=p.Z,<Z1=p.Z); */
|
||||
FieldOperations.fe_add(out t0, ref p.Z, ref p.Z);
|
||||
|
||||
/* qhasm: X3 = A-B */
|
||||
/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
|
||||
/* asm 2: fe_sub(>X3=r.X,<A=r.Z,<B=r.Y); */
|
||||
FieldOperations.fe_sub(out r.X, ref r.Z, ref r.Y);
|
||||
|
||||
/* qhasm: Y3 = A+B */
|
||||
/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
|
||||
/* asm 2: fe_add(>Y3=r.Y,<A=r.Z,<B=r.Y); */
|
||||
FieldOperations.fe_add(out r.Y, ref r.Z, ref r.Y);
|
||||
|
||||
/* qhasm: Z3 = D+C */
|
||||
/* asm 1: fe_add(>Z3=fe#3,<D=fe#5,<C=fe#4); */
|
||||
/* asm 2: fe_add(>Z3=r.Z,<D=t0,<C=r.T); */
|
||||
FieldOperations.fe_add(out r.Z, ref t0, ref r.T);
|
||||
|
||||
/* qhasm: T3 = D-C */
|
||||
/* asm 1: fe_sub(>T3=fe#4,<D=fe#5,<C=fe#4); */
|
||||
/* asm 2: fe_sub(>T3=r.T,<D=t0,<C=r.T); */
|
||||
FieldOperations.fe_sub(out r.T, ref t0, ref r.T);
|
||||
|
||||
/* qhasm: return */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
/*
|
||||
r = p - q
|
||||
*/
|
||||
public static void ge_msub(out GroupElementP1P1 r, ref GroupElementP3 p, ref GroupElementPreComp q)
|
||||
{
|
||||
FieldElement t0;
|
||||
|
||||
/* qhasm: YpX1 = Y1+X1 */
|
||||
/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
|
||||
/* asm 2: fe_add(>YpX1=r.X,<Y1=p.Y,<X1=p.X); */
|
||||
FieldOperations.fe_add(out r.X, ref p.Y, ref p.X);
|
||||
|
||||
/* qhasm: YmX1 = Y1-X1 */
|
||||
/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
|
||||
/* asm 2: fe_sub(>YmX1=r.Y,<Y1=p.Y,<X1=p.X); */
|
||||
FieldOperations.fe_sub(out r.Y, ref p.Y, ref p.X);
|
||||
|
||||
/* qhasm: A = YpX1*ymx2 */
|
||||
/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<ymx2=fe#16); */
|
||||
/* asm 2: fe_mul(>A=r.Z,<YpX1=r.X,<ymx2=q.yminusx); */
|
||||
FieldOperations.fe_mul(out r.Z, ref r.X, ref q.yminusx);
|
||||
|
||||
/* qhasm: B = YmX1*ypx2 */
|
||||
/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<ypx2=fe#15); */
|
||||
/* asm 2: fe_mul(>B=r.Y,<YmX1=r.Y,<ypx2=q.yplusx); */
|
||||
FieldOperations.fe_mul(out r.Y, ref r.Y, ref q.yplusx);
|
||||
|
||||
/* qhasm: C = xy2d2*T1 */
|
||||
/* asm 1: fe_mul(>C=fe#4,<xy2d2=fe#17,<T1=fe#14); */
|
||||
/* asm 2: fe_mul(>C=r.T,<xy2d2=q.xy2d,<T1=p.T); */
|
||||
FieldOperations.fe_mul(out r.T, ref q.xy2d, ref p.T);
|
||||
|
||||
/* qhasm: D = 2*Z1 */
|
||||
/* asm 1: fe_add(>D=fe#5,<Z1=fe#13,<Z1=fe#13); */
|
||||
/* asm 2: fe_add(>D=t0,<Z1=p.Z,<Z1=p.Z); */
|
||||
FieldOperations.fe_add(out t0, ref p.Z, ref p.Z);
|
||||
|
||||
/* qhasm: X3 = A-B */
|
||||
/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
|
||||
/* asm 2: fe_sub(>X3=r.X,<A=r.Z,<B=r.Y); */
|
||||
FieldOperations.fe_sub(out r.X, ref r.Z, ref r.Y);
|
||||
|
||||
/* qhasm: Y3 = A+B */
|
||||
/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
|
||||
/* asm 2: fe_add(>Y3=r.Y,<A=r.Z,<B=r.Y); */
|
||||
FieldOperations.fe_add(out r.Y, ref r.Z, ref r.Y);
|
||||
|
||||
/* qhasm: Z3 = D-C */
|
||||
/* asm 1: fe_sub(>Z3=fe#3,<D=fe#5,<C=fe#4); */
|
||||
/* asm 2: fe_sub(>Z3=r.Z,<D=t0,<C=r.T); */
|
||||
FieldOperations.fe_sub(out r.Z, ref t0, ref r.T);
|
||||
|
||||
/* qhasm: T3 = D+C */
|
||||
/* asm 1: fe_add(>T3=fe#4,<D=fe#5,<C=fe#4); */
|
||||
/* asm 2: fe_add(>T3=r.T,<D=t0,<C=r.T); */
|
||||
FieldOperations.fe_add(out r.T, ref t0, ref r.T);
|
||||
|
||||
/* qhasm: return */
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
/*
|
||||
r = p
|
||||
*/
|
||||
public static void ge_p1p1_to_p2(out GroupElementP2 r, ref GroupElementP1P1 p)
|
||||
{
|
||||
FieldOperations.fe_mul(out r.X, ref p.X, ref p.T);
|
||||
FieldOperations.fe_mul(out r.Y, ref p.Y, ref p.Z);
|
||||
FieldOperations.fe_mul(out r.Z, ref p.Z, ref p.T);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
/*
|
||||
r = p
|
||||
*/
|
||||
public static void ge_p1p1_to_p3(out GroupElementP3 r, ref GroupElementP1P1 p)
|
||||
{
|
||||
FieldOperations.fe_mul(out r.X, ref p.X, ref p.T);
|
||||
FieldOperations.fe_mul(out r.Y, ref p.Y, ref p.Z);
|
||||
FieldOperations.fe_mul(out r.Z, ref p.Z, ref p.T);
|
||||
FieldOperations.fe_mul(out r.T, ref p.X, ref p.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
public static void ge_p2_0(out GroupElementP2 h)
|
||||
{
|
||||
FieldOperations.fe_0(out h.X);
|
||||
FieldOperations.fe_1(out h.Y);
|
||||
FieldOperations.fe_1(out h.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
/*
|
||||
r = 2 * p
|
||||
*/
|
||||
|
||||
public static void ge_p2_dbl(out GroupElementP1P1 r, ref GroupElementP2 p)
|
||||
{
|
||||
FieldElement t0;
|
||||
|
||||
/* qhasm: XX=X1^2 */
|
||||
/* asm 1: fe_sq(>XX=fe#1,<X1=fe#11); */
|
||||
/* asm 2: fe_sq(>XX=r.X,<X1=p.X); */
|
||||
FieldOperations.fe_sq(out r.X, ref p.X);
|
||||
|
||||
/* qhasm: YY=Y1^2 */
|
||||
/* asm 1: fe_sq(>YY=fe#3,<Y1=fe#12); */
|
||||
/* asm 2: fe_sq(>YY=r.Z,<Y1=p.Y); */
|
||||
FieldOperations.fe_sq(out r.Z, ref p.Y);
|
||||
|
||||
/* qhasm: B=2*Z1^2 */
|
||||
/* asm 1: fe_sq2(>B=fe#4,<Z1=fe#13); */
|
||||
/* asm 2: fe_sq2(>B=r.T,<Z1=p.Z); */
|
||||
FieldOperations.fe_sq2(out r.T, ref p.Z);
|
||||
|
||||
/* qhasm: A=X1+Y1 */
|
||||
/* asm 1: fe_add(>A=fe#2,<X1=fe#11,<Y1=fe#12); */
|
||||
/* asm 2: fe_add(>A=r.Y,<X1=p.X,<Y1=p.Y); */
|
||||
FieldOperations.fe_add(out r.Y, ref p.X, ref p.Y);
|
||||
|
||||
/* qhasm: AA=A^2 */
|
||||
/* asm 1: fe_sq(>AA=fe#5,<A=fe#2); */
|
||||
/* asm 2: fe_sq(>AA=t0,<A=r.Y); */
|
||||
FieldOperations.fe_sq(out t0, ref r.Y);
|
||||
|
||||
/* qhasm: Y3=YY+XX */
|
||||
/* asm 1: fe_add(>Y3=fe#2,<YY=fe#3,<XX=fe#1); */
|
||||
/* asm 2: fe_add(>Y3=r.Y,<YY=r.Z,<XX=r.X); */
|
||||
FieldOperations.fe_add(out r.Y, ref r.Z, ref r.X);
|
||||
|
||||
/* qhasm: Z3=YY-XX */
|
||||
/* asm 1: fe_sub(>Z3=fe#3,<YY=fe#3,<XX=fe#1); */
|
||||
/* asm 2: fe_sub(>Z3=r.Z,<YY=r.Z,<XX=r.X); */
|
||||
FieldOperations.fe_sub(out r.Z, ref r.Z, ref r.X);
|
||||
|
||||
/* qhasm: X3=AA-Y3 */
|
||||
/* asm 1: fe_sub(>X3=fe#1,<AA=fe#5,<Y3=fe#2); */
|
||||
/* asm 2: fe_sub(>X3=r.X,<AA=t0,<Y3=r.Y); */
|
||||
FieldOperations.fe_sub(out r.X, ref t0, ref r.Y);
|
||||
|
||||
/* qhasm: T3=B-Z3 */
|
||||
/* asm 1: fe_sub(>T3=fe#4,<B=fe#4,<Z3=fe#3); */
|
||||
/* asm 2: fe_sub(>T3=r.T,<B=r.T,<Z3=r.Z); */
|
||||
FieldOperations.fe_sub(out r.T, ref r.T, ref r.Z);
|
||||
|
||||
/* qhasm: return */
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
public static void ge_p3_0(out GroupElementP3 h)
|
||||
{
|
||||
FieldOperations.fe_0(out h.X);
|
||||
FieldOperations.fe_1(out h.Y);
|
||||
FieldOperations.fe_1(out h.Z);
|
||||
FieldOperations.fe_0(out h.T);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
/*
|
||||
r = 2 * p
|
||||
*/
|
||||
public static void ge_p3_dbl(out GroupElementP1P1 r, ref GroupElementP3 p)
|
||||
{
|
||||
GroupElementP2 q;
|
||||
ge_p3_to_p2(out q, ref p);
|
||||
ge_p2_dbl(out r, ref q);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
/*
|
||||
r = p
|
||||
*/
|
||||
public static void ge_p3_to_cached(out GroupElementCached r, ref GroupElementP3 p)
|
||||
{
|
||||
FieldOperations.fe_add(out r.YplusX, ref p.Y, ref p.X);
|
||||
FieldOperations.fe_sub(out r.YminusX, ref p.Y, ref p.X);
|
||||
r.Z = p.Z;
|
||||
FieldOperations.fe_mul(out r.T2d, ref p.T, ref LookupTables.d2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
/*
|
||||
r = p
|
||||
*/
|
||||
public static void ge_p3_to_p2(out GroupElementP2 r, ref GroupElementP3 p)
|
||||
{
|
||||
r.X = p.X;
|
||||
r.Y = p.Y;
|
||||
r.Z = p.Z;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
public static void ge_p3_tobytes(byte[] s, int offset, ref GroupElementP3 h)
|
||||
{
|
||||
FieldElement recip;
|
||||
FieldElement x, y;
|
||||
|
||||
FieldOperations.fe_invert(out recip, ref h.Z);
|
||||
FieldOperations.fe_mul(out x, ref h.X, ref recip);
|
||||
FieldOperations.fe_mul(out y, ref h.Y, ref recip);
|
||||
FieldOperations.fe_tobytes(s, offset, ref y);
|
||||
s[offset + 31] ^= (byte)(FieldOperations.fe_isnegative(ref x) << 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
public static void ge_precomp_0(out GroupElementPreComp h)
|
||||
{
|
||||
FieldOperations.fe_1(out h.yplusx);
|
||||
FieldOperations.fe_1(out h.yminusx);
|
||||
FieldOperations.fe_0(out h.xy2d);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
static byte equal(byte b, byte c)
|
||||
{
|
||||
|
||||
byte ub = b;
|
||||
byte uc = c;
|
||||
byte x = (byte)(ub ^ uc); /* 0: yes; 1..255: no */
|
||||
uint y = x; /* 0: yes; 1..255: no */
|
||||
unchecked { y -= 1; } /* 4294967295: yes; 0..254: no */
|
||||
y >>= 31; /* 1: yes; 0: no */
|
||||
return (byte)y;
|
||||
}
|
||||
|
||||
static byte negative(sbyte b)
|
||||
{
|
||||
var x = unchecked((ulong)b); /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
|
||||
x >>= 63; /* 1: yes; 0: no */
|
||||
return (byte)x;
|
||||
}
|
||||
|
||||
static void cmov(ref GroupElementPreComp t, ref GroupElementPreComp u, byte b)
|
||||
{
|
||||
FieldOperations.fe_cmov(ref t.yplusx, ref u.yplusx, b);
|
||||
FieldOperations.fe_cmov(ref t.yminusx, ref u.yminusx, b);
|
||||
FieldOperations.fe_cmov(ref t.xy2d, ref u.xy2d, b);
|
||||
}
|
||||
|
||||
static void select(out GroupElementPreComp t, int pos, sbyte b)
|
||||
{
|
||||
GroupElementPreComp minust;
|
||||
var bnegative = negative(b);
|
||||
var babs = (byte)(b - (((-bnegative) & b) << 1));
|
||||
|
||||
ge_precomp_0(out t);
|
||||
var table = LookupTables.Base[pos];
|
||||
cmov(ref t, ref table[0], equal(babs, 1));
|
||||
cmov(ref t, ref table[1], equal(babs, 2));
|
||||
cmov(ref t, ref table[2], equal(babs, 3));
|
||||
cmov(ref t, ref table[3], equal(babs, 4));
|
||||
cmov(ref t, ref table[4], equal(babs, 5));
|
||||
cmov(ref t, ref table[5], equal(babs, 6));
|
||||
cmov(ref t, ref table[6], equal(babs, 7));
|
||||
cmov(ref t, ref table[7], equal(babs, 8));
|
||||
minust.yplusx = t.yminusx;
|
||||
minust.yminusx = t.yplusx;
|
||||
FieldOperations.fe_neg(out minust.xy2d, ref t.xy2d);
|
||||
cmov(ref t, ref minust, bnegative);
|
||||
}
|
||||
|
||||
/*
|
||||
h = a * B
|
||||
where a = a[0]+256*a[1]+...+256^31 a[31]
|
||||
B is the Ed25519 base point (x,4/5) with x positive.
|
||||
|
||||
Preconditions:
|
||||
a[31] <= 127
|
||||
*/
|
||||
|
||||
public static void ge_scalarmult_base(out GroupElementP3 h, byte[] a, int offset)
|
||||
{
|
||||
// todo: Perhaps remove this allocation
|
||||
var e = new sbyte[64];
|
||||
sbyte carry;
|
||||
|
||||
GroupElementP1P1 r;
|
||||
GroupElementP2 s;
|
||||
GroupElementPreComp t;
|
||||
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
e[2 * i + 0] = (sbyte)((a[offset + i] >> 0) & 15);
|
||||
e[2 * i + 1] = (sbyte)((a[offset + i] >> 4) & 15);
|
||||
}
|
||||
/* each e[i] is between 0 and 15 */
|
||||
/* e[63] is between 0 and 7 */
|
||||
|
||||
carry = 0;
|
||||
for (int i = 0; i < 63; ++i)
|
||||
{
|
||||
e[i] += carry;
|
||||
carry = (sbyte)(e[i] + 8);
|
||||
carry >>= 4;
|
||||
e[i] -= (sbyte)(carry << 4);
|
||||
}
|
||||
e[63] += carry;
|
||||
/* each e[i] is between -8 and 8 */
|
||||
|
||||
ge_p3_0(out h);
|
||||
for (int i = 1; i < 64; i += 2)
|
||||
{
|
||||
select(out t, i / 2, e[i]);
|
||||
ge_madd(out r, ref h, ref t); ge_p1p1_to_p3(out h, ref r);
|
||||
}
|
||||
|
||||
ge_p3_dbl(out r, ref h); ge_p1p1_to_p2(out s, ref r);
|
||||
ge_p2_dbl(out r, ref s); ge_p1p1_to_p2(out s, ref r);
|
||||
ge_p2_dbl(out r, ref s); ge_p1p1_to_p2(out s, ref r);
|
||||
ge_p2_dbl(out r, ref s); ge_p1p1_to_p3(out h, ref r);
|
||||
|
||||
for (int i = 0; i < 64; i += 2)
|
||||
{
|
||||
select(out t, i / 2, e[i]);
|
||||
ge_madd(out r, ref h, ref t); ge_p1p1_to_p3(out h, ref r);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
/*
|
||||
r = p - q
|
||||
*/
|
||||
|
||||
public static void ge_sub(out GroupElementP1P1 r, ref GroupElementP3 p, ref GroupElementCached q)
|
||||
{
|
||||
FieldElement t0;
|
||||
|
||||
/* qhasm: YpX1 = Y1+X1 */
|
||||
/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
|
||||
/* asm 2: fe_add(>YpX1=r.X,<Y1=p.Y,<X1=p.X); */
|
||||
FieldOperations.fe_add(out r.X, ref p.Y, ref p.X);
|
||||
|
||||
/* qhasm: YmX1 = Y1-X1 */
|
||||
/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
|
||||
/* asm 2: fe_sub(>YmX1=r.Y,<Y1=p.Y,<X1=p.X); */
|
||||
FieldOperations.fe_sub(out r.Y, ref p.Y, ref p.X);
|
||||
|
||||
/* qhasm: A = YpX1*YmX2 */
|
||||
/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<YmX2=fe#16); */
|
||||
/* asm 2: fe_mul(>A=r.Z,<YpX1=r.X,<YmX2=q.YminusX); */
|
||||
FieldOperations.fe_mul(out r.Z, ref r.X, ref q.YminusX);
|
||||
|
||||
/* qhasm: B = YmX1*YpX2 */
|
||||
/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<YpX2=fe#15); */
|
||||
/* asm 2: fe_mul(>B=r.Y,<YmX1=r.Y,<YpX2=q.YplusX); */
|
||||
FieldOperations.fe_mul(out r.Y, ref r.Y, ref q.YplusX);
|
||||
|
||||
/* qhasm: C = T2d2*T1 */
|
||||
/* asm 1: fe_mul(>C=fe#4,<T2d2=fe#18,<T1=fe#14); */
|
||||
/* asm 2: fe_mul(>C=r.T,<T2d2=q.T2d,<T1=p.T); */
|
||||
FieldOperations.fe_mul(out r.T, ref q.T2d, ref p.T);
|
||||
|
||||
/* qhasm: ZZ = Z1*Z2 */
|
||||
/* asm 1: fe_mul(>ZZ=fe#1,<Z1=fe#13,<Z2=fe#17); */
|
||||
/* asm 2: fe_mul(>ZZ=r.X,<Z1=p.Z,<Z2=q.Z); */
|
||||
FieldOperations.fe_mul(out r.X, ref p.Z, ref q.Z);
|
||||
|
||||
/* qhasm: D = 2*ZZ */
|
||||
/* asm 1: fe_add(>D=fe#5,<ZZ=fe#1,<ZZ=fe#1); */
|
||||
/* asm 2: fe_add(>D=t0,<ZZ=r.X,<ZZ=r.X); */
|
||||
FieldOperations.fe_add(out t0, ref r.X, ref r.X);
|
||||
|
||||
/* qhasm: X3 = A-B */
|
||||
/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
|
||||
/* asm 2: fe_sub(>X3=r.X,<A=r.Z,<B=r.Y); */
|
||||
FieldOperations.fe_sub(out r.X, ref r.Z, ref r.Y);
|
||||
|
||||
/* qhasm: Y3 = A+B */
|
||||
/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
|
||||
/* asm 2: fe_add(>Y3=r.Y,<A=r.Z,<B=r.Y); */
|
||||
FieldOperations.fe_add(out r.Y, ref r.Z, ref r.Y);
|
||||
|
||||
/* qhasm: Z3 = D-C */
|
||||
/* asm 1: fe_sub(>Z3=fe#3,<D=fe#5,<C=fe#4); */
|
||||
/* asm 2: fe_sub(>Z3=r.Z,<D=t0,<C=r.T); */
|
||||
FieldOperations.fe_sub(out r.Z, ref t0, ref r.T);
|
||||
|
||||
/* qhasm: T3 = D+C */
|
||||
/* asm 1: fe_add(>T3=fe#4,<D=fe#5,<C=fe#4); */
|
||||
/* asm 2: fe_add(>T3=r.T,<D=t0,<C=r.T); */
|
||||
FieldOperations.fe_add(out r.T, ref t0, ref r.T);
|
||||
|
||||
/* qhasm: return */
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class GroupOperations
|
||||
{
|
||||
public static void ge_tobytes(byte[] s, int offset, ref GroupElementP2 h)
|
||||
{
|
||||
FieldElement recip;
|
||||
FieldElement x, y;
|
||||
|
||||
FieldOperations.fe_invert(out recip, ref h.Z);
|
||||
FieldOperations.fe_mul(out x, ref h.X, ref recip);
|
||||
FieldOperations.fe_mul(out y, ref h.Y, ref recip);
|
||||
FieldOperations.fe_tobytes(s, offset, ref y);
|
||||
s[offset + 31] ^= (byte)(FieldOperations.fe_isnegative(ref x) << 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class Ed25519Operations
|
||||
{
|
||||
public static void crypto_sign_keypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed, int seedoffset)
|
||||
{
|
||||
GroupElementP3 A;
|
||||
int i;
|
||||
|
||||
Array.Copy(seed, seedoffset, sk, skoffset, 32);
|
||||
byte[] h = Sha512.Hash(sk, skoffset, 32);//ToDo: Remove alloc
|
||||
ScalarOperations.sc_clamp(h, 0);
|
||||
|
||||
GroupOperations.ge_scalarmult_base(out A, h, 0);
|
||||
GroupOperations.ge_p3_tobytes(pk, pkoffset, ref A);
|
||||
|
||||
for (i = 0; i < 32; ++i) sk[skoffset + 32 + i] = pk[pkoffset + i];
|
||||
CryptoBytes.Wipe(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class Ed25519Operations
|
||||
{
|
||||
// Original crypto_sign_open, for reference only
|
||||
/*public static int crypto_sign_open(
|
||||
byte[] m, out int mlen,
|
||||
byte[] sm, int smlen,
|
||||
byte[] pk)
|
||||
{
|
||||
byte[] h = new byte[64];
|
||||
byte[] checkr = new byte[32];
|
||||
GroupElementP3 A;
|
||||
GroupElementP2 R;
|
||||
int i;
|
||||
|
||||
mlen = -1;
|
||||
if (smlen < 64) return -1;
|
||||
if ((sm[63] & 224) != 0) return -1;
|
||||
if (GroupOperations.ge_frombytes_negate_vartime(out A, pk, 0) != 0) return -1;
|
||||
|
||||
for (i = 0; i < smlen; ++i) m[i] = sm[i];
|
||||
for (i = 0; i < 32; ++i) m[32 + i] = pk[i];
|
||||
Sha512BclWrapper.crypto_hash_sha512(h, m, 0, smlen);
|
||||
ScalarOperations.sc_reduce(h);
|
||||
|
||||
var sm32 = new byte[32];
|
||||
Array.Copy(sm, 32, sm32, 0, 32);
|
||||
GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32);
|
||||
GroupOperations.ge_tobytes(checkr, 0, ref R);
|
||||
if (Helpers.crypto_verify_32(checkr, sm) != 0)
|
||||
{
|
||||
for (i = 0; i < smlen; ++i)
|
||||
m[i] = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < smlen - 64; ++i)
|
||||
m[i] = sm[64 + i];
|
||||
for (i = smlen - 64; i < smlen; ++i)
|
||||
m[i] = 0;
|
||||
mlen = smlen - 64;
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
public static bool crypto_sign_verify(
|
||||
byte[] sig, int sigoffset,
|
||||
byte[] m, int moffset, int mlen,
|
||||
byte[] pk, int pkoffset,
|
||||
int phflag = -1,
|
||||
byte[] ctx = null)
|
||||
{
|
||||
byte[] h;
|
||||
byte[] checkr = new byte[32];
|
||||
GroupElementP3 A;
|
||||
GroupElementP2 R;
|
||||
|
||||
if ((sig[sigoffset + 63] & 224) != 0) return false;
|
||||
if (GroupOperations.ge_frombytes_negate_vartime(out A, pk, pkoffset) != 0)
|
||||
return false;
|
||||
|
||||
var hasher = new Sha512();
|
||||
|
||||
if (phflag == 0)
|
||||
{
|
||||
// Static ctx
|
||||
var ed25519Ctx = Encoding.ASCII.GetBytes("SigEd25519 no Ed25519 collisions");
|
||||
|
||||
hasher.Update(ed25519Ctx, 0, ed25519Ctx.Length);
|
||||
hasher.Update(new byte[1] { (byte)phflag }, 0, 1);
|
||||
hasher.Update(new byte[1] { ctx != null ? (byte)ctx.Length : (byte)0 }, 0, 1);
|
||||
|
||||
if (ctx != null)
|
||||
hasher.Update(ctx, 0, ctx.Length);
|
||||
}
|
||||
|
||||
hasher.Update(sig, sigoffset, 32);
|
||||
hasher.Update(pk, pkoffset, 32);
|
||||
hasher.Update(m, moffset, mlen);
|
||||
h = hasher.Finalize();
|
||||
|
||||
ScalarOperations.sc_reduce(h);
|
||||
|
||||
var sm32 = new byte[32];//todo: remove allocation
|
||||
Array.Copy(sig, sigoffset + 32, sm32, 0, 32);
|
||||
GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32);
|
||||
GroupOperations.ge_tobytes(checkr, 0, ref R);
|
||||
var result = CryptoBytes.ConstantTimeEquals(checkr, 0, sig, sigoffset, 32);
|
||||
CryptoBytes.Wipe(h);
|
||||
CryptoBytes.Wipe(checkr);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class ScalarOperations
|
||||
{
|
||||
public static void sc_clamp(byte[] s, int offset)
|
||||
{
|
||||
s[offset + 0] &= 248;
|
||||
s[offset + 31] &= 127;
|
||||
s[offset + 31] |= 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class ScalarOperations
|
||||
{
|
||||
static long load_3(byte[] input, int offset)
|
||||
{
|
||||
long result;
|
||||
result = (long)input[offset + 0];
|
||||
result |= ((long)input[offset + 1]) << 8;
|
||||
result |= ((long)input[offset + 2]) << 16;
|
||||
return result;
|
||||
}
|
||||
|
||||
static long load_4(byte[] input, int offset)
|
||||
{
|
||||
long result;
|
||||
result = (long)input[offset + 0];
|
||||
result |= ((long)input[offset + 1]) << 8;
|
||||
result |= ((long)input[offset + 2]) << 16;
|
||||
result |= ((long)input[offset + 3]) << 24;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Input:
|
||||
a[0]+256*a[1]+...+256^31*a[31] = a
|
||||
b[0]+256*b[1]+...+256^31*b[31] = b
|
||||
c[0]+256*c[1]+...+256^31*c[31] = c
|
||||
|
||||
Output:
|
||||
s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
|
||||
where l = 2^252 + 27742317777372353535851937790883648493.
|
||||
*/
|
||||
|
||||
public static void sc_muladd(byte[] s, byte[] a, byte[] b, byte[] c)
|
||||
{
|
||||
long a0 = 2097151 & load_3(a, 0);
|
||||
long a1 = 2097151 & (load_4(a, 2) >> 5);
|
||||
long a2 = 2097151 & (load_3(a, 5) >> 2);
|
||||
long a3 = 2097151 & (load_4(a, 7) >> 7);
|
||||
long a4 = 2097151 & (load_4(a, 10) >> 4);
|
||||
long a5 = 2097151 & (load_3(a, 13) >> 1);
|
||||
long a6 = 2097151 & (load_4(a, 15) >> 6);
|
||||
long a7 = 2097151 & (load_3(a, 18) >> 3);
|
||||
long a8 = 2097151 & load_3(a, 21);
|
||||
long a9 = 2097151 & (load_4(a, 23) >> 5);
|
||||
long a10 = 2097151 & (load_3(a, 26) >> 2);
|
||||
long a11 = (load_4(a, 28) >> 7);
|
||||
long b0 = 2097151 & load_3(b, 0);
|
||||
long b1 = 2097151 & (load_4(b, 2) >> 5);
|
||||
long b2 = 2097151 & (load_3(b, 5) >> 2);
|
||||
long b3 = 2097151 & (load_4(b, 7) >> 7);
|
||||
long b4 = 2097151 & (load_4(b, 10) >> 4);
|
||||
long b5 = 2097151 & (load_3(b, 13) >> 1);
|
||||
long b6 = 2097151 & (load_4(b, 15) >> 6);
|
||||
long b7 = 2097151 & (load_3(b, 18) >> 3);
|
||||
long b8 = 2097151 & load_3(b, 21);
|
||||
long b9 = 2097151 & (load_4(b, 23) >> 5);
|
||||
long b10 = 2097151 & (load_3(b, 26) >> 2);
|
||||
long b11 = (load_4(b, 28) >> 7);
|
||||
long c0 = 2097151 & load_3(c, 0);
|
||||
long c1 = 2097151 & (load_4(c, 2) >> 5);
|
||||
long c2 = 2097151 & (load_3(c, 5) >> 2);
|
||||
long c3 = 2097151 & (load_4(c, 7) >> 7);
|
||||
long c4 = 2097151 & (load_4(c, 10) >> 4);
|
||||
long c5 = 2097151 & (load_3(c, 13) >> 1);
|
||||
long c6 = 2097151 & (load_4(c, 15) >> 6);
|
||||
long c7 = 2097151 & (load_3(c, 18) >> 3);
|
||||
long c8 = 2097151 & load_3(c, 21);
|
||||
long c9 = 2097151 & (load_4(c, 23) >> 5);
|
||||
long c10 = 2097151 & (load_3(c, 26) >> 2);
|
||||
long c11 = (load_4(c, 28) >> 7);
|
||||
long s0;
|
||||
long s1;
|
||||
long s2;
|
||||
long s3;
|
||||
long s4;
|
||||
long s5;
|
||||
long s6;
|
||||
long s7;
|
||||
long s8;
|
||||
long s9;
|
||||
long s10;
|
||||
long s11;
|
||||
long s12;
|
||||
long s13;
|
||||
long s14;
|
||||
long s15;
|
||||
long s16;
|
||||
long s17;
|
||||
long s18;
|
||||
long s19;
|
||||
long s20;
|
||||
long s21;
|
||||
long s22;
|
||||
long s23;
|
||||
long carry0;
|
||||
long carry1;
|
||||
long carry2;
|
||||
long carry3;
|
||||
long carry4;
|
||||
long carry5;
|
||||
long carry6;
|
||||
long carry7;
|
||||
long carry8;
|
||||
long carry9;
|
||||
long carry10;
|
||||
long carry11;
|
||||
long carry12;
|
||||
long carry13;
|
||||
long carry14;
|
||||
long carry15;
|
||||
long carry16;
|
||||
long carry17;
|
||||
long carry18;
|
||||
long carry19;
|
||||
long carry20;
|
||||
long carry21;
|
||||
long carry22;
|
||||
|
||||
s0 = c0 + a0 * b0;
|
||||
s1 = c1 + a0 * b1 + a1 * b0;
|
||||
s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
|
||||
s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
|
||||
s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
|
||||
s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
|
||||
s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
|
||||
s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0;
|
||||
s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0;
|
||||
s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
|
||||
s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
|
||||
s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
|
||||
s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
|
||||
s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2;
|
||||
s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3;
|
||||
s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4;
|
||||
s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
|
||||
s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
|
||||
s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
|
||||
s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
|
||||
s20 = a9 * b11 + a10 * b10 + a11 * b9;
|
||||
s21 = a10 * b11 + a11 * b10;
|
||||
s22 = a11 * b11;
|
||||
s23 = 0;
|
||||
|
||||
carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
|
||||
carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
|
||||
carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
|
||||
carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
|
||||
carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
|
||||
carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
|
||||
carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
|
||||
carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
|
||||
carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
|
||||
carry18 = (s18 + (1 << 20)) >> 21; s19 += carry18; s18 -= carry18 << 21;
|
||||
carry20 = (s20 + (1 << 20)) >> 21; s21 += carry20; s20 -= carry20 << 21;
|
||||
carry22 = (s22 + (1 << 20)) >> 21; s23 += carry22; s22 -= carry22 << 21;
|
||||
|
||||
carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
|
||||
carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
|
||||
carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
|
||||
carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
|
||||
carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
|
||||
carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
|
||||
carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
|
||||
carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
|
||||
carry17 = (s17 + (1 << 20)) >> 21; s18 += carry17; s17 -= carry17 << 21;
|
||||
carry19 = (s19 + (1 << 20)) >> 21; s20 += carry19; s19 -= carry19 << 21;
|
||||
carry21 = (s21 + (1 << 20)) >> 21; s22 += carry21; s21 -= carry21 << 21;
|
||||
|
||||
s11 += s23 * 666643;
|
||||
s12 += s23 * 470296;
|
||||
s13 += s23 * 654183;
|
||||
s14 -= s23 * 997805;
|
||||
s15 += s23 * 136657;
|
||||
s16 -= s23 * 683901;
|
||||
s23 = 0;
|
||||
|
||||
s10 += s22 * 666643;
|
||||
s11 += s22 * 470296;
|
||||
s12 += s22 * 654183;
|
||||
s13 -= s22 * 997805;
|
||||
s14 += s22 * 136657;
|
||||
s15 -= s22 * 683901;
|
||||
s22 = 0;
|
||||
|
||||
s9 += s21 * 666643;
|
||||
s10 += s21 * 470296;
|
||||
s11 += s21 * 654183;
|
||||
s12 -= s21 * 997805;
|
||||
s13 += s21 * 136657;
|
||||
s14 -= s21 * 683901;
|
||||
s21 = 0;
|
||||
|
||||
s8 += s20 * 666643;
|
||||
s9 += s20 * 470296;
|
||||
s10 += s20 * 654183;
|
||||
s11 -= s20 * 997805;
|
||||
s12 += s20 * 136657;
|
||||
s13 -= s20 * 683901;
|
||||
s20 = 0;
|
||||
|
||||
s7 += s19 * 666643;
|
||||
s8 += s19 * 470296;
|
||||
s9 += s19 * 654183;
|
||||
s10 -= s19 * 997805;
|
||||
s11 += s19 * 136657;
|
||||
s12 -= s19 * 683901;
|
||||
s19 = 0;
|
||||
|
||||
s6 += s18 * 666643;
|
||||
s7 += s18 * 470296;
|
||||
s8 += s18 * 654183;
|
||||
s9 -= s18 * 997805;
|
||||
s10 += s18 * 136657;
|
||||
s11 -= s18 * 683901;
|
||||
s18 = 0;
|
||||
|
||||
carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
|
||||
carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
|
||||
carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
|
||||
carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
|
||||
carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
|
||||
carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
|
||||
|
||||
carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
|
||||
carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
|
||||
carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
|
||||
carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
|
||||
carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
|
||||
|
||||
s5 += s17 * 666643;
|
||||
s6 += s17 * 470296;
|
||||
s7 += s17 * 654183;
|
||||
s8 -= s17 * 997805;
|
||||
s9 += s17 * 136657;
|
||||
s10 -= s17 * 683901;
|
||||
s17 = 0;
|
||||
|
||||
s4 += s16 * 666643;
|
||||
s5 += s16 * 470296;
|
||||
s6 += s16 * 654183;
|
||||
s7 -= s16 * 997805;
|
||||
s8 += s16 * 136657;
|
||||
s9 -= s16 * 683901;
|
||||
s16 = 0;
|
||||
|
||||
s3 += s15 * 666643;
|
||||
s4 += s15 * 470296;
|
||||
s5 += s15 * 654183;
|
||||
s6 -= s15 * 997805;
|
||||
s7 += s15 * 136657;
|
||||
s8 -= s15 * 683901;
|
||||
s15 = 0;
|
||||
|
||||
s2 += s14 * 666643;
|
||||
s3 += s14 * 470296;
|
||||
s4 += s14 * 654183;
|
||||
s5 -= s14 * 997805;
|
||||
s6 += s14 * 136657;
|
||||
s7 -= s14 * 683901;
|
||||
s14 = 0;
|
||||
|
||||
s1 += s13 * 666643;
|
||||
s2 += s13 * 470296;
|
||||
s3 += s13 * 654183;
|
||||
s4 -= s13 * 997805;
|
||||
s5 += s13 * 136657;
|
||||
s6 -= s13 * 683901;
|
||||
s13 = 0;
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
|
||||
carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
|
||||
carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
|
||||
carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
|
||||
carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
|
||||
carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
|
||||
|
||||
carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
|
||||
carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
|
||||
carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
|
||||
carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
|
||||
carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
|
||||
carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
|
||||
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
|
||||
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
|
||||
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
|
||||
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
|
||||
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
|
||||
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
|
||||
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
|
||||
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
|
||||
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
|
||||
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
|
||||
carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
|
||||
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
|
||||
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
|
||||
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
|
||||
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
|
||||
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
|
||||
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
|
||||
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
|
||||
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
|
||||
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
|
||||
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
|
||||
|
||||
unchecked
|
||||
{
|
||||
s[0] = (byte)(s0 >> 0);
|
||||
s[1] = (byte)(s0 >> 8);
|
||||
s[2] = (byte)((s0 >> 16) | (s1 << 5));
|
||||
s[3] = (byte)(s1 >> 3);
|
||||
s[4] = (byte)(s1 >> 11);
|
||||
s[5] = (byte)((s1 >> 19) | (s2 << 2));
|
||||
s[6] = (byte)(s2 >> 6);
|
||||
s[7] = (byte)((s2 >> 14) | (s3 << 7));
|
||||
s[8] = (byte)(s3 >> 1);
|
||||
s[9] = (byte)(s3 >> 9);
|
||||
s[10] = (byte)((s3 >> 17) | (s4 << 4));
|
||||
s[11] = (byte)(s4 >> 4);
|
||||
s[12] = (byte)(s4 >> 12);
|
||||
s[13] = (byte)((s4 >> 20) | (s5 << 1));
|
||||
s[14] = (byte)(s5 >> 7);
|
||||
s[15] = (byte)((s5 >> 15) | (s6 << 6));
|
||||
s[16] = (byte)(s6 >> 2);
|
||||
s[17] = (byte)(s6 >> 10);
|
||||
s[18] = (byte)((s6 >> 18) | (s7 << 3));
|
||||
s[19] = (byte)(s7 >> 5);
|
||||
s[20] = (byte)(s7 >> 13);
|
||||
s[21] = (byte)(s8 >> 0);
|
||||
s[22] = (byte)(s8 >> 8);
|
||||
s[23] = (byte)((s8 >> 16) | (s9 << 5));
|
||||
s[24] = (byte)(s9 >> 3);
|
||||
s[25] = (byte)(s9 >> 11);
|
||||
s[26] = (byte)((s9 >> 19) | (s10 << 2));
|
||||
s[27] = (byte)(s10 >> 6);
|
||||
s[28] = (byte)((s10 >> 14) | (s11 << 7));
|
||||
s[29] = (byte)(s11 >> 1);
|
||||
s[30] = (byte)(s11 >> 9);
|
||||
s[31] = (byte)(s11 >> 17);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class ScalarOperations
|
||||
{
|
||||
/*
|
||||
Input:
|
||||
s[0]+256*s[1]+...+256^63*s[63] = s
|
||||
|
||||
Output:
|
||||
s[0]+256*s[1]+...+256^31*s[31] = s mod l
|
||||
where l = 2^252 + 27742317777372353535851937790883648493.
|
||||
Overwrites s in place.
|
||||
*/
|
||||
|
||||
public static void sc_reduce(byte[] s)
|
||||
{
|
||||
long s0 = 2097151 & load_3(s, 0);
|
||||
long s1 = 2097151 & (load_4(s, 2) >> 5);
|
||||
long s2 = 2097151 & (load_3(s, 5) >> 2);
|
||||
long s3 = 2097151 & (load_4(s, 7) >> 7);
|
||||
long s4 = 2097151 & (load_4(s, 10) >> 4);
|
||||
long s5 = 2097151 & (load_3(s, 13) >> 1);
|
||||
long s6 = 2097151 & (load_4(s, 15) >> 6);
|
||||
long s7 = 2097151 & (load_3(s, 18) >> 3);
|
||||
long s8 = 2097151 & load_3(s, 21);
|
||||
long s9 = 2097151 & (load_4(s, 23) >> 5);
|
||||
long s10 = 2097151 & (load_3(s, 26) >> 2);
|
||||
long s11 = 2097151 & (load_4(s, 28) >> 7);
|
||||
long s12 = 2097151 & (load_4(s, 31) >> 4);
|
||||
long s13 = 2097151 & (load_3(s, 34) >> 1);
|
||||
long s14 = 2097151 & (load_4(s, 36) >> 6);
|
||||
long s15 = 2097151 & (load_3(s, 39) >> 3);
|
||||
long s16 = 2097151 & load_3(s, 42);
|
||||
long s17 = 2097151 & (load_4(s, 44) >> 5);
|
||||
long s18 = 2097151 & (load_3(s, 47) >> 2);
|
||||
long s19 = 2097151 & (load_4(s, 49) >> 7);
|
||||
long s20 = 2097151 & (load_4(s, 52) >> 4);
|
||||
long s21 = 2097151 & (load_3(s, 55) >> 1);
|
||||
long s22 = 2097151 & (load_4(s, 57) >> 6);
|
||||
long s23 = (load_4(s, 60) >> 3);
|
||||
|
||||
long carry0;
|
||||
long carry1;
|
||||
long carry2;
|
||||
long carry3;
|
||||
long carry4;
|
||||
long carry5;
|
||||
long carry6;
|
||||
long carry7;
|
||||
long carry8;
|
||||
long carry9;
|
||||
long carry10;
|
||||
long carry11;
|
||||
long carry12;
|
||||
long carry13;
|
||||
long carry14;
|
||||
long carry15;
|
||||
long carry16;
|
||||
|
||||
s11 += s23 * 666643;
|
||||
s12 += s23 * 470296;
|
||||
s13 += s23 * 654183;
|
||||
s14 -= s23 * 997805;
|
||||
s15 += s23 * 136657;
|
||||
s16 -= s23 * 683901;
|
||||
s23 = 0;
|
||||
|
||||
s10 += s22 * 666643;
|
||||
s11 += s22 * 470296;
|
||||
s12 += s22 * 654183;
|
||||
s13 -= s22 * 997805;
|
||||
s14 += s22 * 136657;
|
||||
s15 -= s22 * 683901;
|
||||
s22 = 0;
|
||||
|
||||
s9 += s21 * 666643;
|
||||
s10 += s21 * 470296;
|
||||
s11 += s21 * 654183;
|
||||
s12 -= s21 * 997805;
|
||||
s13 += s21 * 136657;
|
||||
s14 -= s21 * 683901;
|
||||
s21 = 0;
|
||||
|
||||
s8 += s20 * 666643;
|
||||
s9 += s20 * 470296;
|
||||
s10 += s20 * 654183;
|
||||
s11 -= s20 * 997805;
|
||||
s12 += s20 * 136657;
|
||||
s13 -= s20 * 683901;
|
||||
s20 = 0;
|
||||
|
||||
s7 += s19 * 666643;
|
||||
s8 += s19 * 470296;
|
||||
s9 += s19 * 654183;
|
||||
s10 -= s19 * 997805;
|
||||
s11 += s19 * 136657;
|
||||
s12 -= s19 * 683901;
|
||||
s19 = 0;
|
||||
|
||||
s6 += s18 * 666643;
|
||||
s7 += s18 * 470296;
|
||||
s8 += s18 * 654183;
|
||||
s9 -= s18 * 997805;
|
||||
s10 += s18 * 136657;
|
||||
s11 -= s18 * 683901;
|
||||
s18 = 0;
|
||||
|
||||
carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
|
||||
carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
|
||||
carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
|
||||
carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
|
||||
carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
|
||||
carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
|
||||
|
||||
carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
|
||||
carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
|
||||
carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
|
||||
carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
|
||||
carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
|
||||
|
||||
s5 += s17 * 666643;
|
||||
s6 += s17 * 470296;
|
||||
s7 += s17 * 654183;
|
||||
s8 -= s17 * 997805;
|
||||
s9 += s17 * 136657;
|
||||
s10 -= s17 * 683901;
|
||||
s17 = 0;
|
||||
|
||||
s4 += s16 * 666643;
|
||||
s5 += s16 * 470296;
|
||||
s6 += s16 * 654183;
|
||||
s7 -= s16 * 997805;
|
||||
s8 += s16 * 136657;
|
||||
s9 -= s16 * 683901;
|
||||
s16 = 0;
|
||||
|
||||
s3 += s15 * 666643;
|
||||
s4 += s15 * 470296;
|
||||
s5 += s15 * 654183;
|
||||
s6 -= s15 * 997805;
|
||||
s7 += s15 * 136657;
|
||||
s8 -= s15 * 683901;
|
||||
s15 = 0;
|
||||
|
||||
s2 += s14 * 666643;
|
||||
s3 += s14 * 470296;
|
||||
s4 += s14 * 654183;
|
||||
s5 -= s14 * 997805;
|
||||
s6 += s14 * 136657;
|
||||
s7 -= s14 * 683901;
|
||||
s14 = 0;
|
||||
|
||||
s1 += s13 * 666643;
|
||||
s2 += s13 * 470296;
|
||||
s3 += s13 * 654183;
|
||||
s4 -= s13 * 997805;
|
||||
s5 += s13 * 136657;
|
||||
s6 -= s13 * 683901;
|
||||
s13 = 0;
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
|
||||
carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
|
||||
carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
|
||||
carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
|
||||
carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
|
||||
carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
|
||||
|
||||
carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
|
||||
carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
|
||||
carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
|
||||
carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
|
||||
carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
|
||||
carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
|
||||
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
|
||||
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
|
||||
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
|
||||
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
|
||||
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
|
||||
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
|
||||
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
|
||||
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
|
||||
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
|
||||
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
|
||||
carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
|
||||
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
|
||||
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
|
||||
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
|
||||
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
|
||||
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
|
||||
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
|
||||
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
|
||||
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
|
||||
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
|
||||
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
|
||||
|
||||
unchecked
|
||||
{
|
||||
s[0] = (byte)(s0 >> 0);
|
||||
s[1] = (byte)(s0 >> 8);
|
||||
s[2] = (byte)((s0 >> 16) | (s1 << 5));
|
||||
s[3] = (byte)(s1 >> 3);
|
||||
s[4] = (byte)(s1 >> 11);
|
||||
s[5] = (byte)((s1 >> 19) | (s2 << 2));
|
||||
s[6] = (byte)(s2 >> 6);
|
||||
s[7] = (byte)((s2 >> 14) | (s3 << 7));
|
||||
s[8] = (byte)(s3 >> 1);
|
||||
s[9] = (byte)(s3 >> 9);
|
||||
s[10] = (byte)((s3 >> 17) | (s4 << 4));
|
||||
s[11] = (byte)(s4 >> 4);
|
||||
s[12] = (byte)(s4 >> 12);
|
||||
s[13] = (byte)((s4 >> 20) | (s5 << 1));
|
||||
s[14] = (byte)(s5 >> 7);
|
||||
s[15] = (byte)((s5 >> 15) | (s6 << 6));
|
||||
s[16] = (byte)(s6 >> 2);
|
||||
s[17] = (byte)(s6 >> 10);
|
||||
s[18] = (byte)((s6 >> 18) | (s7 << 3));
|
||||
s[19] = (byte)(s7 >> 5);
|
||||
s[20] = (byte)(s7 >> 13);
|
||||
s[21] = (byte)(s8 >> 0);
|
||||
s[22] = (byte)(s8 >> 8);
|
||||
s[23] = (byte)((s8 >> 16) | (s9 << 5));
|
||||
s[24] = (byte)(s9 >> 3);
|
||||
s[25] = (byte)(s9 >> 11);
|
||||
s[26] = (byte)((s9 >> 19) | (s10 << 2));
|
||||
s[27] = (byte)(s10 >> 6);
|
||||
s[28] = (byte)((s10 >> 14) | (s11 << 7));
|
||||
s[29] = (byte)(s11 >> 1);
|
||||
s[30] = (byte)(s11 >> 9);
|
||||
s[31] = (byte)(s11 >> 17);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
public static class MontgomeryOperations
|
||||
{
|
||||
public static void scalarmult(
|
||||
byte[] q, int qoffset,
|
||||
byte[] n, int noffset,
|
||||
byte[] p, int poffset)
|
||||
{
|
||||
FieldElement p0, q0;
|
||||
FieldOperations.fe_frombytes2(out p0, p, poffset);
|
||||
scalarmult(out q0, n, noffset, ref p0);
|
||||
FieldOperations.fe_tobytes(q, qoffset, ref q0);
|
||||
}
|
||||
|
||||
internal static void scalarmult(
|
||||
out FieldElement q,
|
||||
byte[] n, int noffset,
|
||||
ref FieldElement p)
|
||||
{
|
||||
byte[] e = new byte[32];//ToDo: remove allocation
|
||||
FieldElement x1, x2, x3;
|
||||
FieldElement z2, z3;
|
||||
FieldElement tmp0, tmp1;
|
||||
|
||||
for (int i = 0; i < 32; ++i)
|
||||
e[i] = n[noffset + i];
|
||||
ScalarOperations.sc_clamp(e, 0);
|
||||
x1 = p;
|
||||
FieldOperations.fe_1(out x2);
|
||||
FieldOperations.fe_0(out z2);
|
||||
x3 = x1;
|
||||
FieldOperations.fe_1(out z3);
|
||||
|
||||
uint swap = 0;
|
||||
for (int pos = 254; pos >= 0; --pos)
|
||||
{
|
||||
uint b = (uint)(e[pos / 8] >> (pos & 7));
|
||||
b &= 1;
|
||||
swap ^= b;
|
||||
FieldOperations.fe_cswap(ref x2, ref x3, swap);
|
||||
FieldOperations.fe_cswap(ref z2, ref z3, swap);
|
||||
swap = b;
|
||||
|
||||
/* qhasm: enter ladder */
|
||||
|
||||
/* qhasm: D = X3-Z3 */
|
||||
/* asm 1: fe_sub(>D=fe#5,<X3=fe#3,<Z3=fe#4); */
|
||||
/* asm 2: fe_sub(>D=tmp0,<X3=x3,<Z3=z3); */
|
||||
FieldOperations.fe_sub(out tmp0, ref x3, ref z3);
|
||||
|
||||
/* qhasm: B = X2-Z2 */
|
||||
/* asm 1: fe_sub(>B=fe#6,<X2=fe#1,<Z2=fe#2); */
|
||||
/* asm 2: fe_sub(>B=tmp1,<X2=x2,<Z2=z2); */
|
||||
FieldOperations.fe_sub(out tmp1, ref x2, ref z2);
|
||||
|
||||
/* qhasm: A = X2+Z2 */
|
||||
/* asm 1: fe_add(>A=fe#1,<X2=fe#1,<Z2=fe#2); */
|
||||
/* asm 2: fe_add(>A=x2,<X2=x2,<Z2=z2); */
|
||||
FieldOperations.fe_add(out x2, ref x2, ref z2);
|
||||
|
||||
/* qhasm: C = X3+Z3 */
|
||||
/* asm 1: fe_add(>C=fe#2,<X3=fe#3,<Z3=fe#4); */
|
||||
/* asm 2: fe_add(>C=z2,<X3=x3,<Z3=z3); */
|
||||
FieldOperations.fe_add(out z2, ref x3, ref z3);
|
||||
|
||||
/* qhasm: DA = D*A */
|
||||
/* asm 1: fe_mul(>DA=fe#4,<D=fe#5,<A=fe#1); */
|
||||
/* asm 2: fe_mul(>DA=z3,<D=tmp0,<A=x2); */
|
||||
FieldOperations.fe_mul(out z3, ref tmp0, ref x2);
|
||||
|
||||
/* qhasm: CB = C*B */
|
||||
/* asm 1: fe_mul(>CB=fe#2,<C=fe#2,<B=fe#6); */
|
||||
/* asm 2: fe_mul(>CB=z2,<C=z2,<B=tmp1); */
|
||||
FieldOperations.fe_mul(out z2, ref z2, ref tmp1);
|
||||
|
||||
/* qhasm: BB = B^2 */
|
||||
/* asm 1: fe_sq(>BB=fe#5,<B=fe#6); */
|
||||
/* asm 2: fe_sq(>BB=tmp0,<B=tmp1); */
|
||||
FieldOperations.fe_sq(out tmp0, ref tmp1);
|
||||
|
||||
/* qhasm: AA = A^2 */
|
||||
/* asm 1: fe_sq(>AA=fe#6,<A=fe#1); */
|
||||
/* asm 2: fe_sq(>AA=tmp1,<A=x2); */
|
||||
FieldOperations.fe_sq(out tmp1, ref x2);
|
||||
|
||||
/* qhasm: t0 = DA+CB */
|
||||
/* asm 1: fe_add(>t0=fe#3,<DA=fe#4,<CB=fe#2); */
|
||||
/* asm 2: fe_add(>t0=x3,<DA=z3,<CB=z2); */
|
||||
FieldOperations.fe_add(out x3, ref z3, ref z2);
|
||||
|
||||
/* qhasm: assign x3 to t0 */
|
||||
|
||||
/* qhasm: t1 = DA-CB */
|
||||
/* asm 1: fe_sub(>t1=fe#2,<DA=fe#4,<CB=fe#2); */
|
||||
/* asm 2: fe_sub(>t1=z2,<DA=z3,<CB=z2); */
|
||||
FieldOperations.fe_sub(out z2, ref z3, ref z2);
|
||||
|
||||
/* qhasm: X4 = AA*BB */
|
||||
/* asm 1: fe_mul(>X4=fe#1,<AA=fe#6,<BB=fe#5); */
|
||||
/* asm 2: fe_mul(>X4=x2,<AA=tmp1,<BB=tmp0); */
|
||||
FieldOperations.fe_mul(out x2, ref tmp1, ref tmp0);
|
||||
|
||||
/* qhasm: E = AA-BB */
|
||||
/* asm 1: fe_sub(>E=fe#6,<AA=fe#6,<BB=fe#5); */
|
||||
/* asm 2: fe_sub(>E=tmp1,<AA=tmp1,<BB=tmp0); */
|
||||
FieldOperations.fe_sub(out tmp1, ref tmp1, ref tmp0);
|
||||
|
||||
/* qhasm: t2 = t1^2 */
|
||||
/* asm 1: fe_sq(>t2=fe#2,<t1=fe#2); */
|
||||
/* asm 2: fe_sq(>t2=z2,<t1=z2); */
|
||||
FieldOperations.fe_sq(out z2, ref z2);
|
||||
|
||||
/* qhasm: t3 = a24*E */
|
||||
/* asm 1: fe_mul121666(>t3=fe#4,<E=fe#6); */
|
||||
/* asm 2: fe_mul121666(>t3=z3,<E=tmp1); */
|
||||
FieldOperations.fe_mul121666(out z3, ref tmp1);
|
||||
|
||||
/* qhasm: X5 = t0^2 */
|
||||
/* asm 1: fe_sq(>X5=fe#3,<t0=fe#3); */
|
||||
/* asm 2: fe_sq(>X5=x3,<t0=x3); */
|
||||
FieldOperations.fe_sq(out x3, ref x3);
|
||||
|
||||
/* qhasm: t4 = BB+t3 */
|
||||
/* asm 1: fe_add(>t4=fe#5,<BB=fe#5,<t3=fe#4); */
|
||||
/* asm 2: fe_add(>t4=tmp0,<BB=tmp0,<t3=z3); */
|
||||
FieldOperations.fe_add(out tmp0, ref tmp0, ref z3);
|
||||
|
||||
/* qhasm: Z5 = X1*t2 */
|
||||
/* asm 1: fe_mul(>Z5=fe#4,x1,<t2=fe#2); */
|
||||
/* asm 2: fe_mul(>Z5=z3,x1,<t2=z2); */
|
||||
FieldOperations.fe_mul(out z3, ref x1, ref z2);
|
||||
|
||||
/* qhasm: Z4 = E*t4 */
|
||||
/* asm 1: fe_mul(>Z4=fe#2,<E=fe#6,<t4=fe#5); */
|
||||
/* asm 2: fe_mul(>Z4=z2,<E=tmp1,<t4=tmp0); */
|
||||
FieldOperations.fe_mul(out z2, ref tmp1, ref tmp0);
|
||||
|
||||
/* qhasm: return */
|
||||
|
||||
}
|
||||
FieldOperations.fe_cswap(ref x2, ref x3, swap);
|
||||
FieldOperations.fe_cswap(ref z2, ref z3, swap);
|
||||
|
||||
FieldOperations.fe_invert(out z2, ref z2);
|
||||
FieldOperations.fe_mul(out x2, ref x2, ref z2);
|
||||
q = x2;
|
||||
CryptoBytes.Wipe(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class Ed25519Operations
|
||||
{
|
||||
public static void crypto_sign(
|
||||
byte[] sig, int sigoffset,
|
||||
byte[] m, int moffset, int mlen,
|
||||
byte[] sk, int skoffset,
|
||||
int phflag,
|
||||
byte[] ctx = null)
|
||||
{
|
||||
byte[] az, r, hram;
|
||||
GroupElementP3 R;
|
||||
var hasher = new Sha512();
|
||||
{
|
||||
hasher.Update(sk, skoffset, 32);
|
||||
az = hasher.Finalize();
|
||||
ScalarOperations.sc_clamp(az, 0);
|
||||
|
||||
hasher.Init();
|
||||
|
||||
if (phflag == 0)
|
||||
{
|
||||
// Static ctx
|
||||
var ed25519Ctx = Encoding.ASCII.GetBytes("SigEd25519 no Ed25519 collisions");
|
||||
|
||||
hasher.Update(ed25519Ctx, 0, ed25519Ctx.Length);
|
||||
hasher.Update(new byte[1] { (byte)phflag }, 0, 1);
|
||||
hasher.Update(new byte[1] { ctx != null ? (byte)ctx.Length : (byte)0 }, 0, 1);
|
||||
|
||||
if (ctx != null)
|
||||
hasher.Update(ctx, 0, ctx.Length);
|
||||
}
|
||||
|
||||
hasher.Update(az, 32, 32);
|
||||
hasher.Update(m, moffset, mlen);
|
||||
r = hasher.Finalize();
|
||||
|
||||
ScalarOperations.sc_reduce(r);
|
||||
GroupOperations.ge_scalarmult_base(out R, r, 0);
|
||||
GroupOperations.ge_p3_tobytes(sig, sigoffset, ref R);
|
||||
|
||||
hasher.Init();
|
||||
|
||||
if (phflag == 0)
|
||||
{
|
||||
// Static ctx
|
||||
var ed25519Ctx = Encoding.ASCII.GetBytes("SigEd25519 no Ed25519 collisions");
|
||||
|
||||
hasher.Update(ed25519Ctx, 0, ed25519Ctx.Length);
|
||||
hasher.Update(new byte[1] { (byte)phflag }, 0, 1);
|
||||
hasher.Update(new byte[1] { ctx != null ? (byte)ctx.Length : (byte)0 }, 0, 1);
|
||||
|
||||
if (ctx != null)
|
||||
hasher.Update(ctx, 0, ctx.Length);
|
||||
}
|
||||
|
||||
hasher.Update(sig, sigoffset, 32);
|
||||
hasher.Update(sk, skoffset + 32, 32);
|
||||
hasher.Update(m, moffset, mlen);
|
||||
hram = hasher.Finalize();
|
||||
|
||||
ScalarOperations.sc_reduce(hram);
|
||||
var s = new byte[32];//todo: remove allocation
|
||||
Array.Copy(sig, sigoffset + 32, s, 0, 32);
|
||||
ScalarOperations.sc_muladd(s, hram, az, r);
|
||||
Array.Copy(s, 0, sig, sigoffset + 32, 32);
|
||||
CryptoBytes.Wipe(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal.Ed25519Ref10
|
||||
{
|
||||
internal static partial class LookupTables
|
||||
{
|
||||
internal static FieldElement sqrtm1 = new FieldElement(-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,447 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Framework.Cryptography.Ed25519.Internal
|
||||
{
|
||||
internal static class Sha512Internal
|
||||
{
|
||||
private static readonly ulong[] K = new ulong[]
|
||||
{
|
||||
0x428a2f98d728ae22,0x7137449123ef65cd,0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc,
|
||||
0x3956c25bf348b538,0x59f111f1b605d019,0x923f82a4af194f9b,0xab1c5ed5da6d8118,
|
||||
0xd807aa98a3030242,0x12835b0145706fbe,0x243185be4ee4b28c,0x550c7dc3d5ffb4e2,
|
||||
0x72be5d74f27b896f,0x80deb1fe3b1696b1,0x9bdc06a725c71235,0xc19bf174cf692694,
|
||||
0xe49b69c19ef14ad2,0xefbe4786384f25e3,0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65,
|
||||
0x2de92c6f592b0275,0x4a7484aa6ea6e483,0x5cb0a9dcbd41fbd4,0x76f988da831153b5,
|
||||
0x983e5152ee66dfab,0xa831c66d2db43210,0xb00327c898fb213f,0xbf597fc7beef0ee4,
|
||||
0xc6e00bf33da88fc2,0xd5a79147930aa725,0x06ca6351e003826f,0x142929670a0e6e70,
|
||||
0x27b70a8546d22ffc,0x2e1b21385c26c926,0x4d2c6dfc5ac42aed,0x53380d139d95b3df,
|
||||
0x650a73548baf63de,0x766a0abb3c77b2a8,0x81c2c92e47edaee6,0x92722c851482353b,
|
||||
0xa2bfe8a14cf10364,0xa81a664bbc423001,0xc24b8b70d0f89791,0xc76c51a30654be30,
|
||||
0xd192e819d6ef5218,0xd69906245565a910,0xf40e35855771202a,0x106aa07032bbd1b8,
|
||||
0x19a4c116b8d2d0c8,0x1e376c085141ab53,0x2748774cdf8eeb99,0x34b0bcb5e19b48a8,
|
||||
0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb,0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3,
|
||||
0x748f82ee5defb2fc,0x78a5636f43172f60,0x84c87814a1f0ab72,0x8cc702081a6439ec,
|
||||
0x90befffa23631e28,0xa4506cebde82bde9,0xbef9a3f7b2c67915,0xc67178f2e372532b,
|
||||
0xca273eceea26619c,0xd186b8c721c0c207,0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178,
|
||||
0x06f067aa72176fba,0x0a637dc5a2c898a6,0x113f9804bef90dae,0x1b710b35131c471b,
|
||||
0x28db77f523047d84,0x32caab7b40c72493,0x3c9ebe0a15c9bebc,0x431d67c49c100d4c,
|
||||
0x4cc5d4becb3e42b6,0x597f299cfc657e2a,0x5fcb6fab3ad6faec,0x6c44198c4a475817
|
||||
};
|
||||
|
||||
internal static void Sha512Init(out Array8<ulong> state)
|
||||
{
|
||||
state.x0 = 0x6a09e667f3bcc908;
|
||||
state.x1 = 0xbb67ae8584caa73b;
|
||||
state.x2 = 0x3c6ef372fe94f82b;
|
||||
state.x3 = 0xa54ff53a5f1d36f1;
|
||||
state.x4 = 0x510e527fade682d1;
|
||||
state.x5 = 0x9b05688c2b3e6c1f;
|
||||
state.x6 = 0x1f83d9abfb41bd6b;
|
||||
state.x7 = 0x5be0cd19137e2179;
|
||||
}
|
||||
|
||||
internal static void Core(out Array8<ulong> outputState, ref Array8<ulong> inputState, ref Array16<ulong> input)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var a = inputState.x0;
|
||||
var b = inputState.x1;
|
||||
var c = inputState.x2;
|
||||
var d = inputState.x3;
|
||||
var e = inputState.x4;
|
||||
var f = inputState.x5;
|
||||
var g = inputState.x6;
|
||||
var h = inputState.x7;
|
||||
|
||||
var w0 = input.x0;
|
||||
var w1 = input.x1;
|
||||
var w2 = input.x2;
|
||||
var w3 = input.x3;
|
||||
var w4 = input.x4;
|
||||
var w5 = input.x5;
|
||||
var w6 = input.x6;
|
||||
var w7 = input.x7;
|
||||
var w8 = input.x8;
|
||||
var w9 = input.x9;
|
||||
var w10 = input.x10;
|
||||
var w11 = input.x11;
|
||||
var w12 = input.x12;
|
||||
var w13 = input.x13;
|
||||
var w14 = input.x14;
|
||||
var w15 = input.x15;
|
||||
|
||||
int t = 0;
|
||||
while (true)
|
||||
{
|
||||
ulong t1, t2;
|
||||
|
||||
{//0
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w0;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//1
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w1;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//2
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w2;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//3
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w3;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//4
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w4;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//5
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w5;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//6
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w6;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//7
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w7;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//8
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w8;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//9
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w9;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//10
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w10;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//11
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w11;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//12
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w12;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//13
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w13;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//14
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w14;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
{//15
|
||||
t1 = h +
|
||||
((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) +
|
||||
//Sigma1(e)
|
||||
((e & f) ^ (~e & g)) + //Ch(e,f,g)
|
||||
K[t] + w15;
|
||||
t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) +
|
||||
//Sigma0(a)
|
||||
((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c)
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
t++;
|
||||
}
|
||||
if (t == 80)
|
||||
break;
|
||||
|
||||
w0 += ((w14 >> 19) ^ (w14 << (64 - 19)) ^ (w14 >> 61) ^ (w14 << (64 - 61)) ^ (w14 >> 6)) +
|
||||
w9 +
|
||||
((w1 >> 1) ^ (w1 << (64 - 1)) ^ (w1 >> 8) ^ (w1 << (64 - 8)) ^ (w1 >> 7));
|
||||
w1 += ((w15 >> 19) ^ (w15 << (64 - 19)) ^ (w15 >> 61) ^ (w15 << (64 - 61)) ^ (w15 >> 6)) +
|
||||
w10 +
|
||||
((w2 >> 1) ^ (w2 << (64 - 1)) ^ (w2 >> 8) ^ (w2 << (64 - 8)) ^ (w2 >> 7));
|
||||
w2 += ((w0 >> 19) ^ (w0 << (64 - 19)) ^ (w0 >> 61) ^ (w0 << (64 - 61)) ^ (w0 >> 6)) +
|
||||
w11 +
|
||||
((w3 >> 1) ^ (w3 << (64 - 1)) ^ (w3 >> 8) ^ (w3 << (64 - 8)) ^ (w3 >> 7));
|
||||
w3 += ((w1 >> 19) ^ (w1 << (64 - 19)) ^ (w1 >> 61) ^ (w1 << (64 - 61)) ^ (w1 >> 6)) +
|
||||
w12 +
|
||||
((w4 >> 1) ^ (w4 << (64 - 1)) ^ (w4 >> 8) ^ (w4 << (64 - 8)) ^ (w4 >> 7));
|
||||
w4 += ((w2 >> 19) ^ (w2 << (64 - 19)) ^ (w2 >> 61) ^ (w2 << (64 - 61)) ^ (w2 >> 6)) +
|
||||
w13 +
|
||||
((w5 >> 1) ^ (w5 << (64 - 1)) ^ (w5 >> 8) ^ (w5 << (64 - 8)) ^ (w5 >> 7));
|
||||
w5 += ((w3 >> 19) ^ (w3 << (64 - 19)) ^ (w3 >> 61) ^ (w3 << (64 - 61)) ^ (w3 >> 6)) +
|
||||
w14 +
|
||||
((w6 >> 1) ^ (w6 << (64 - 1)) ^ (w6 >> 8) ^ (w6 << (64 - 8)) ^ (w6 >> 7));
|
||||
w6 += ((w4 >> 19) ^ (w4 << (64 - 19)) ^ (w4 >> 61) ^ (w4 << (64 - 61)) ^ (w4 >> 6)) +
|
||||
w15 +
|
||||
((w7 >> 1) ^ (w7 << (64 - 1)) ^ (w7 >> 8) ^ (w7 << (64 - 8)) ^ (w7 >> 7));
|
||||
w7 += ((w5 >> 19) ^ (w5 << (64 - 19)) ^ (w5 >> 61) ^ (w5 << (64 - 61)) ^ (w5 >> 6)) +
|
||||
w0 +
|
||||
((w8 >> 1) ^ (w8 << (64 - 1)) ^ (w8 >> 8) ^ (w8 << (64 - 8)) ^ (w8 >> 7));
|
||||
w8 += ((w6 >> 19) ^ (w6 << (64 - 19)) ^ (w6 >> 61) ^ (w6 << (64 - 61)) ^ (w6 >> 6)) +
|
||||
w1 +
|
||||
((w9 >> 1) ^ (w9 << (64 - 1)) ^ (w9 >> 8) ^ (w9 << (64 - 8)) ^ (w9 >> 7));
|
||||
w9 += ((w7 >> 19) ^ (w7 << (64 - 19)) ^ (w7 >> 61) ^ (w7 << (64 - 61)) ^ (w7 >> 6)) +
|
||||
w2 +
|
||||
((w10 >> 1) ^ (w10 << (64 - 1)) ^ (w10 >> 8) ^ (w10 << (64 - 8)) ^ (w10 >> 7));
|
||||
w10 += ((w8 >> 19) ^ (w8 << (64 - 19)) ^ (w8 >> 61) ^ (w8 << (64 - 61)) ^ (w8 >> 6)) +
|
||||
w3 +
|
||||
((w11 >> 1) ^ (w11 << (64 - 1)) ^ (w11 >> 8) ^ (w11 << (64 - 8)) ^ (w11 >> 7));
|
||||
w11 += ((w9 >> 19) ^ (w9 << (64 - 19)) ^ (w9 >> 61) ^ (w9 << (64 - 61)) ^ (w9 >> 6)) +
|
||||
w4 +
|
||||
((w12 >> 1) ^ (w12 << (64 - 1)) ^ (w12 >> 8) ^ (w12 << (64 - 8)) ^ (w12 >> 7));
|
||||
w12 += ((w10 >> 19) ^ (w10 << (64 - 19)) ^ (w10 >> 61) ^ (w10 << (64 - 61)) ^ (w10 >> 6)) +
|
||||
w5 +
|
||||
((w13 >> 1) ^ (w13 << (64 - 1)) ^ (w13 >> 8) ^ (w13 << (64 - 8)) ^ (w13 >> 7));
|
||||
w13 += ((w11 >> 19) ^ (w11 << (64 - 19)) ^ (w11 >> 61) ^ (w11 << (64 - 61)) ^ (w11 >> 6)) +
|
||||
w6 +
|
||||
((w14 >> 1) ^ (w14 << (64 - 1)) ^ (w14 >> 8) ^ (w14 << (64 - 8)) ^ (w14 >> 7));
|
||||
w14 += ((w12 >> 19) ^ (w12 << (64 - 19)) ^ (w12 >> 61) ^ (w12 << (64 - 61)) ^ (w12 >> 6)) +
|
||||
w7 +
|
||||
((w15 >> 1) ^ (w15 << (64 - 1)) ^ (w15 >> 8) ^ (w15 << (64 - 8)) ^ (w15 >> 7));
|
||||
w15 += ((w13 >> 19) ^ (w13 << (64 - 19)) ^ (w13 >> 61) ^ (w13 << (64 - 61)) ^ (w13 >> 6)) +
|
||||
w8 +
|
||||
((w0 >> 1) ^ (w0 << (64 - 1)) ^ (w0 >> 8) ^ (w0 << (64 - 8)) ^ (w0 >> 7));
|
||||
}
|
||||
|
||||
outputState.x0 = inputState.x0 + a;
|
||||
outputState.x1 = inputState.x1 + b;
|
||||
outputState.x2 = inputState.x2 + c;
|
||||
outputState.x3 = inputState.x3 + d;
|
||||
outputState.x4 = inputState.x4 + e;
|
||||
outputState.x5 = inputState.x5 + f;
|
||||
outputState.x6 = inputState.x6 + g;
|
||||
outputState.x7 = inputState.x7 + h;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user