diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs
index ff4587cb2..adb56ca9b 100644
--- a/crypto/src/math/ec/rfc8032/Ed25519.cs
+++ b/crypto/src/math/ec/rfc8032/Ed25519.cs
@@ -2,6 +2,7 @@
using System.Diagnostics;
using System.Runtime.CompilerServices;
+using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Math.EC.Rfc7748;
using Org.BouncyCastle.Math.Raw;
@@ -18,11 +19,12 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
private const int ScalarUints = 8;
private const int ScalarBytes = ScalarUints * 4;
+ public static readonly int PrehashSize = 64;
public static readonly int PublicKeySize = PointBytes;
public static readonly int SecretKeySize = 32;
public static readonly int SignatureSize = PointBytes + ScalarBytes;
- //private static readonly byte[] Dom2Prefix = Strings.ToByteArray("SigEd25519 no Ed25519 collisions");
+ private static readonly byte[] Dom2Prefix = Strings.ToByteArray("SigEd25519 no Ed25519 collisions");
private static readonly uint[] P = { 0xFFFFFFEDU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFFFFFFU };
private static readonly uint[] L = { 0x5CF5D3EDU, 0x5812631AU, 0xA2F79CD6U, 0x14DEF9DEU, 0x00000000U, 0x00000000U, 0x00000000U, 0x10000000U };
@@ -96,6 +98,12 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
return ReduceScalar(result);
}
+ private static bool CheckContextVar(byte[] ctx, byte phflag)
+ {
+ return ctx == null && phflag == 0x00
+ || ctx != null && ctx.Length < 256;
+ }
+
private static bool CheckPointVar(byte[] p)
{
uint[] t = new uint[8];
@@ -111,6 +119,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
return !Nat256.Gte(n, L);
}
+ private static IDigest CreateDigest()
+ {
+ return new Sha512Digest();
+ }
+
+ public static IDigest CreatePrehash()
+ {
+ return CreateDigest();
+ }
+
private static uint Decode24(byte[] bs, int off)
{
uint n = bs[off];
@@ -140,9 +158,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
{
byte[] py = Arrays.CopyOfRange(p, pOff, pOff + PointBytes);
if (!CheckPointVar(py))
- {
return false;
- }
int x_0 = (py[PointBytes - 1] & 0x80) >> 7;
py[PointBytes - 1] &= 0x7F;
@@ -158,15 +174,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
X25519Field.AddOne(v);
if (!X25519Field.SqrtRatioVar(u, v, r.x))
- {
return false;
- }
X25519Field.Normalize(r.x);
if (x_0 == 1 && X25519Field.IsZeroVar(r.x))
- {
return false;
- }
if (negate ^ (x_0 != (r.x[0] & 1)))
{
@@ -182,6 +194,17 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
Decode32(k, kOff, n, 0, ScalarUints);
}
+ private static void Dom2(IDigest d, byte phflag, byte[] ctx)
+ {
+ if (ctx != null)
+ {
+ d.BlockUpdate(Dom2Prefix, 0, Dom2Prefix.Length);
+ d.Update(phflag);
+ d.Update((byte)ctx.Length);
+ d.BlockUpdate(ctx, 0, ctx.Length);
+ }
+ }
+
private static void Encode24(uint n, byte[] bs, int off)
{
bs[off] = (byte)(n);
@@ -220,7 +243,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
public static void GeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff)
{
- Sha512Digest d = new Sha512Digest();
+ IDigest d = CreateDigest();
byte[] h = new byte[d.GetDigestSize()];
d.BlockUpdate(sk, skOff, SecretKeySize);
@@ -286,8 +309,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
return ws;
}
- private static void ImplSign(Sha512Digest d, byte[] h, byte[] s, byte[] pk, int pkOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
+ private static void ImplSign(IDigest d, byte[] h, byte[] s, byte[] pk, int pkOff, byte[] ctx, byte phflag,
+ byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
{
+ Dom2(d, phflag, ctx);
d.BlockUpdate(h, ScalarBytes, ScalarBytes);
d.BlockUpdate(m, mOff, mLen);
d.DoFinal(h, 0);
@@ -296,6 +321,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
byte[] R = new byte[PointBytes];
ScalarMultBaseEncoded(r, R, 0);
+ Dom2(d, phflag, ctx);
d.BlockUpdate(R, 0, PointBytes);
d.BlockUpdate(pk, 0, PointBytes);
d.BlockUpdate(m, mOff, mLen);
@@ -308,6 +334,90 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
Array.Copy(S, 0, sig, sigOff + PointBytes, ScalarBytes);
}
+ private static void ImplSign(byte[] sk, int skOff, byte[] ctx, byte phflag, byte[] m, int mOff, int mLen,
+ byte[] sig, int sigOff)
+ {
+ if (!CheckContextVar(ctx, phflag))
+ throw new ArgumentException("ctx");
+
+ IDigest d = CreateDigest();
+ byte[] h = new byte[d.GetDigestSize()];
+
+ d.BlockUpdate(sk, skOff, SecretKeySize);
+ d.DoFinal(h, 0);
+
+ byte[] s = new byte[ScalarBytes];
+ PruneScalar(h, 0, s);
+
+ byte[] pk = new byte[PointBytes];
+ ScalarMultBaseEncoded(s, pk, 0);
+
+ ImplSign(d, h, s, pk, 0, ctx, phflag, m, mOff, mLen, sig, sigOff);
+ }
+
+ private static void ImplSign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte phflag,
+ byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
+ {
+ if (!CheckContextVar(ctx, phflag))
+ throw new ArgumentException("ctx");
+
+ IDigest d = CreateDigest();
+ byte[] h = new byte[d.GetDigestSize()];
+
+ d.BlockUpdate(sk, skOff, SecretKeySize);
+ d.DoFinal(h, 0);
+
+ byte[] s = new byte[ScalarBytes];
+ PruneScalar(h, 0, s);
+
+ ImplSign(d, h, s, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff);
+ }
+
+ private static bool ImplVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte phflag,
+ byte[] m, int mOff, int mLen)
+ {
+ if (!CheckContextVar(ctx, phflag))
+ throw new ArgumentException("ctx");
+
+ byte[] R = Arrays.CopyOfRange(sig, sigOff, sigOff + PointBytes);
+ byte[] S = Arrays.CopyOfRange(sig, sigOff + PointBytes, sigOff + SignatureSize);
+
+ if (!CheckPointVar(R))
+ return false;
+
+ if (!CheckScalarVar(S))
+ return false;
+
+ PointExt pA = new PointExt();
+ if (!DecodePointVar(pk, pkOff, true, pA))
+ return false;
+
+ IDigest d = CreateDigest();
+ byte[] h = new byte[d.GetDigestSize()];
+
+ Dom2(d, phflag, ctx);
+ d.BlockUpdate(R, 0, PointBytes);
+ d.BlockUpdate(pk, pkOff, PointBytes);
+ d.BlockUpdate(m, mOff, mLen);
+ d.DoFinal(h, 0);
+
+ byte[] k = ReduceScalar(h);
+
+ uint[] nS = new uint[ScalarUints];
+ DecodeScalar(S, 0, nS);
+
+ uint[] nA = new uint[ScalarUints];
+ DecodeScalar(k, 0, nA);
+
+ PointAccum pR = new PointAccum();
+ ScalarMultStraussVar(nS, nA, pA, pR);
+
+ byte[] check = new byte[PointBytes];
+ EncodePoint(pR, check, 0);
+
+ return Arrays.AreEqual(check, R);
+ }
+
private static void PointAddVar(bool negate, PointExt p, PointAccum r)
{
int[] A = X25519Field.Create();
@@ -518,9 +628,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
public static void Precompute()
{
if (precompBase != null)
- {
return;
- }
// Precomputed table for the base point in verification ladder
{
@@ -795,9 +903,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
}
if ((cOff -= PrecompTeeth) < 0)
- {
break;
- }
PointDouble(r);
}
@@ -850,9 +956,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
}
if (--bit < 0)
- {
break;
- }
PointDouble(r);
}
@@ -860,78 +964,101 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
public static void Sign(byte[] sk, int skOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
{
- Sha512Digest d = new Sha512Digest();
- byte[] h = new byte[d.GetDigestSize()];
+ byte[] ctx = null;
+ byte phflag = 0x00;
- d.BlockUpdate(sk, skOff, SecretKeySize);
- d.DoFinal(h, 0);
+ ImplSign(sk, skOff, ctx, phflag, m, mOff, mLen, sig, sigOff);
+ }
- byte[] s = new byte[ScalarBytes];
- PruneScalar(h, 0, s);
+ public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
+ {
+ byte[] ctx = null;
+ byte phflag = 0x00;
- byte[] pk = new byte[PointBytes];
- ScalarMultBaseEncoded(s, pk, 0);
+ ImplSign(sk, skOff, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff);
+ }
- ImplSign(d, h, s, pk, 0, m, mOff, mLen, sig, sigOff);
+ public static void Sign(byte[] sk, int skOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
+ {
+ byte phflag = 0x00;
+
+ ImplSign(sk, skOff, ctx, phflag, m, mOff, mLen, sig, sigOff);
}
- public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
+ public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
{
- Sha512Digest d = new Sha512Digest();
- byte[] h = new byte[d.GetDigestSize()];
+ byte phflag = 0x00;
- d.BlockUpdate(sk, skOff, SecretKeySize);
- d.DoFinal(h, 0);
+ ImplSign(sk, skOff, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff);
+ }
- byte[] s = new byte[ScalarBytes];
- PruneScalar(h, 0, s);
+ public static void SignPrehash(byte[] sk, int skOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff)
+ {
+ byte phflag = 0x01;
- ImplSign(d, h, s, pk, pkOff, m, mOff, mLen, sig, sigOff);
+ ImplSign(sk, skOff, ctx, phflag, ph, phOff, PrehashSize, sig, sigOff);
}
- public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen)
+ public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff)
{
- byte[] R = Arrays.CopyOfRange(sig, sigOff, sigOff + PointBytes);
- byte[] S = Arrays.CopyOfRange(sig, sigOff + PointBytes, sigOff + SignatureSize);
+ byte phflag = 0x01;
- if (!CheckPointVar(R))
- {
- return false;
- }
- if (!CheckScalarVar(S))
- {
- return false;
- }
+ ImplSign(sk, skOff, pk, pkOff, ctx, phflag, ph, phOff, PrehashSize, sig, sigOff);
+ }
- PointExt pA = new PointExt();
- if (!DecodePointVar(pk, pkOff, true, pA))
- {
- return false;
- }
+ public static void SignPrehash(byte[] sk, int skOff, byte[] ctx, IDigest ph, byte[] sig, int sigOff)
+ {
+ byte[] m = new byte[PrehashSize];
+ if (PrehashSize != ph.DoFinal(m, 0))
+ throw new ArgumentException("ph");
- Sha512Digest d = new Sha512Digest();
- byte[] h = new byte[d.GetDigestSize()];
+ byte phflag = 0x01;
- d.BlockUpdate(R, 0, PointBytes);
- d.BlockUpdate(pk, pkOff, PointBytes);
- d.BlockUpdate(m, mOff, mLen);
- d.DoFinal(h, 0);
+ ImplSign(sk, skOff, ctx, phflag, m, 0, m.Length, sig, sigOff);
+ }
- byte[] k = ReduceScalar(h);
+ public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, IDigest ph, byte[] sig, int sigOff)
+ {
+ byte[] m = new byte[PrehashSize];
+ if (PrehashSize != ph.DoFinal(m, 0))
+ throw new ArgumentException("ph");
- uint[] nS = new uint[ScalarUints];
- DecodeScalar(S, 0, nS);
+ byte phflag = 0x01;
- uint[] nA = new uint[ScalarUints];
- DecodeScalar(k, 0, nA);
+ ImplSign(sk, skOff, pk, pkOff, ctx, phflag, m, 0, m.Length, sig, sigOff);
+ }
- PointAccum pR = new PointAccum();
- ScalarMultStraussVar(nS, nA, pA, pR);
+ public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen)
+ {
+ byte[] ctx = null;
+ byte phflag = 0x00;
- byte[] check = new byte[PointBytes];
- EncodePoint(pR, check, 0);
+ return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, mOff, mLen);
+ }
- return Arrays.AreEqual(check, R);
+ public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen)
+ {
+ byte phflag = 0x00;
+
+ return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, mOff, mLen);
+ }
+
+ public static bool VerifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff)
+ {
+ byte phflag = 0x01;
+
+ return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, ph, phOff, PrehashSize);
+ }
+
+ public static bool VerifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, IDigest ph)
+ {
+ byte[] m = new byte[PrehashSize];
+ if (PrehashSize != ph.DoFinal(m, 0))
+ throw new ArgumentException("ph");
+
+ byte phflag = 0x01;
+
+ return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, 0, m.Length);
}
}
}
diff --git a/crypto/src/math/ec/rfc8032/Ed448.cs b/crypto/src/math/ec/rfc8032/Ed448.cs
index 52c215160..0e56b12a8 100644
--- a/crypto/src/math/ec/rfc8032/Ed448.cs
+++ b/crypto/src/math/ec/rfc8032/Ed448.cs
@@ -2,6 +2,7 @@
using System.Diagnostics;
using System.Runtime.CompilerServices;
+using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Math.EC.Rfc7748;
using Org.BouncyCastle.Math.Raw;
@@ -18,6 +19,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
private const int ScalarUints = 14;
private const int ScalarBytes = ScalarUints * 4 + 1;
+ public static readonly int PrehashSize = 64;
public static readonly int PublicKeySize = PointBytes;
public static readonly int SecretKeySize = 57;
public static readonly int SignatureSize = PointBytes + ScalarBytes;
@@ -103,9 +105,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
private static bool CheckPointVar(byte[] p)
{
if ((p[PointBytes - 1] & 0x7F) != 0x00)
- {
return false;
- }
uint[] t = new uint[14];
Decode32(p, 0, t, 0, 14);
@@ -115,15 +115,23 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
private static bool CheckScalarVar(byte[] s)
{
if (s[ScalarBytes - 1] != 0x00)
- {
return false;
- }
uint[] n = new uint[ScalarUints];
DecodeScalar(s, 0, n);
return !Nat.Gte(ScalarUints, n, L);
}
+ public static IXof CreatePrehash()
+ {
+ return CreateXof();
+ }
+
+ private static IXof CreateXof()
+ {
+ return new ShakeDigest(256);
+ }
+
private static uint Decode16(byte[] bs, int off)
{
uint n = bs[off];
@@ -160,9 +168,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
{
byte[] py = Arrays.CopyOfRange(p, pOff, pOff + PointBytes);
if (!CheckPointVar(py))
- {
return false;
- }
int x_0 = (py[PointBytes - 1] & 0x80) >> 7;
py[PointBytes - 1] &= 0x7F;
@@ -179,15 +185,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
X448Field.AddOne(v);
if (!X448Field.SqrtRatioVar(u, v, r.x))
- {
return false;
- }
X448Field.Normalize(r.x);
if (x_0 == 1 && X448Field.IsZeroVar(r.x))
- {
return false;
- }
if (negate ^ (x_0 != (r.x[0] & 1)))
{
@@ -205,7 +207,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
Decode32(k, kOff, n, 0, ScalarUints);
}
- private static void Dom4(ShakeDigest d, byte x, byte[] y)
+ private static void Dom4(IXof d, byte x, byte[] y)
{
d.BlockUpdate(Dom4Prefix, 0, Dom4Prefix.Length);
d.Update(x);
@@ -251,7 +253,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
public static void GeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff)
{
- ShakeDigest d = new ShakeDigest(256);
+ IXof d = CreateXof();
byte[] h = new byte[ScalarBytes * 2];
d.BlockUpdate(sk, skOff, SecretKeySize);
@@ -317,10 +319,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
return ws;
}
- private static void ImplSign(ShakeDigest d, byte[] h, byte[] s, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
+ private static void ImplSign(IXof d, byte[] h, byte[] s, byte[] pk, int pkOff, byte[] ctx, byte phflag,
+ byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
{
- byte phflag = 0x00;
-
Dom4(d, phflag, ctx);
d.BlockUpdate(h, ScalarBytes, ScalarBytes);
d.BlockUpdate(m, mOff, mLen);
@@ -343,6 +344,90 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
Array.Copy(S, 0, sig, sigOff + PointBytes, ScalarBytes);
}
+ private static void ImplSign(byte[] sk, int skOff, byte[] ctx, byte phflag, byte[] m, int mOff, int mLen,
+ byte[] sig, int sigOff)
+ {
+ if (!CheckContextVar(ctx))
+ throw new ArgumentException("ctx");
+
+ IXof d = CreateXof();
+ byte[] h = new byte[ScalarBytes * 2];
+
+ d.BlockUpdate(sk, skOff, SecretKeySize);
+ d.DoFinal(h, 0, h.Length);
+
+ byte[] s = new byte[ScalarBytes];
+ PruneScalar(h, 0, s);
+
+ byte[] pk = new byte[PointBytes];
+ ScalarMultBaseEncoded(s, pk, 0);
+
+ ImplSign(d, h, s, pk, 0, ctx, phflag, m, mOff, mLen, sig, sigOff);
+ }
+
+ private static void ImplSign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte phflag,
+ byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
+ {
+ if (!CheckContextVar(ctx))
+ throw new ArgumentException("ctx");
+
+ IXof d = CreateXof();
+ byte[] h = new byte[ScalarBytes * 2];
+
+ d.BlockUpdate(sk, skOff, SecretKeySize);
+ d.DoFinal(h, 0, h.Length);
+
+ byte[] s = new byte[ScalarBytes];
+ PruneScalar(h, 0, s);
+
+ ImplSign(d, h, s, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff);
+ }
+
+ private static bool ImplVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte phflag,
+ byte[] m, int mOff, int mLen)
+ {
+ if (!CheckContextVar(ctx))
+ throw new ArgumentException("ctx");
+
+ byte[] R = Arrays.CopyOfRange(sig, sigOff, sigOff + PointBytes);
+ byte[] S = Arrays.CopyOfRange(sig, sigOff + PointBytes, sigOff + SignatureSize);
+
+ if (!CheckPointVar(R))
+ return false;
+
+ if (!CheckScalarVar(S))
+ return false;
+
+ PointExt pA = new PointExt();
+ if (!DecodePointVar(pk, pkOff, true, pA))
+ return false;
+
+ IXof d = CreateXof();
+ byte[] h = new byte[ScalarBytes * 2];
+
+ Dom4(d, phflag, ctx);
+ d.BlockUpdate(R, 0, PointBytes);
+ d.BlockUpdate(pk, pkOff, PointBytes);
+ d.BlockUpdate(m, mOff, mLen);
+ d.DoFinal(h, 0, h.Length);
+
+ byte[] k = ReduceScalar(h);
+
+ uint[] nS = new uint[ScalarUints];
+ DecodeScalar(S, 0, nS);
+
+ uint[] nA = new uint[ScalarUints];
+ DecodeScalar(k, 0, nA);
+
+ PointExt pR = new PointExt();
+ ScalarMultStraussVar(nS, nA, pA, pR);
+
+ byte[] check = new byte[PointBytes];
+ EncodePoint(pR, check, 0);
+
+ return Arrays.AreEqual(check, R);
+ }
+
private static void PointAddVar(bool negate, PointExt p, PointExt r)
{
uint[] A = X448Field.Create();
@@ -505,9 +590,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
public static void Precompute()
{
if (precompBase != null)
- {
return;
- }
PointExt p = new PointExt();
X448Field.Copy(B_x, 0, p.x, 0);
@@ -907,9 +990,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
}
if (--cOff < 0)
- {
break;
- }
PointDouble(r);
}
@@ -962,9 +1043,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
}
if (--bit < 0)
- {
break;
- }
PointDouble(r);
}
@@ -972,96 +1051,77 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
public static void Sign(byte[] sk, int skOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
{
- if (!CheckContextVar(ctx))
- {
- throw new ArgumentException("ctx");
- }
+ byte phflag = 0x00;
- ShakeDigest d = new ShakeDigest(256);
- byte[] h = new byte[ScalarBytes * 2];
+ ImplSign(sk, skOff, ctx, phflag, m, mOff, mLen, sig, sigOff);
+ }
- d.BlockUpdate(sk, skOff, SecretKeySize);
- d.DoFinal(h, 0, h.Length);
+ public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
+ {
+ byte phflag = 0x00;
- byte[] s = new byte[ScalarBytes];
- PruneScalar(h, 0, s);
+ ImplSign(sk, skOff, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff);
+ }
- byte[] pk = new byte[PointBytes];
- ScalarMultBaseEncoded(s, pk, 0);
+ public static void SignPrehash(byte[] sk, int skOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff)
+ {
+ byte phflag = 0x01;
- ImplSign(d, h, s, pk, 0, ctx, m, mOff, mLen, sig, sigOff);
+ ImplSign(sk, skOff, ctx, phflag, ph, phOff, PrehashSize, sig, sigOff);
}
- public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)
+ public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff)
{
- if (!CheckContextVar(ctx))
- {
- throw new ArgumentException("ctx");
- }
+ byte phflag = 0x01;
- ShakeDigest d = new ShakeDigest(256);
- byte[] h = new byte[ScalarBytes * 2];
+ ImplSign(sk, skOff, pk, pkOff, ctx, phflag, ph, phOff, PrehashSize, sig, sigOff);
+ }
- d.BlockUpdate(sk, skOff, SecretKeySize);
- d.DoFinal(h, 0, h.Length);
+ public static void SignPrehash(byte[] sk, int skOff, byte[] ctx, IXof ph, byte[] sig, int sigOff)
+ {
+ byte[] m = new byte[PrehashSize];
+ if (PrehashSize != ph.DoFinal(m, 0, PrehashSize))
+ throw new ArgumentException("ph");
- byte[] s = new byte[ScalarBytes];
- PruneScalar(h, 0, s);
+ byte phflag = 0x01;
- ImplSign(d, h, s, pk, pkOff, ctx, m, mOff, mLen, sig, sigOff);
+ ImplSign(sk, skOff, ctx, phflag, m, 0, m.Length, sig, sigOff);
}
- public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen)
+ public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, IXof ph, byte[] sig, int sigOff)
{
- if (!CheckContextVar(ctx))
- {
- throw new ArgumentException("ctx");
- }
-
- byte[] R = Arrays.CopyOfRange(sig, sigOff, sigOff + PointBytes);
- byte[] S = Arrays.CopyOfRange(sig, sigOff + PointBytes, sigOff + SignatureSize);
+ byte[] m = new byte[PrehashSize];
+ if (PrehashSize != ph.DoFinal(m, 0, PrehashSize))
+ throw new ArgumentException("ph");
- if (!CheckPointVar(R))
- {
- return false;
- }
- if (!CheckScalarVar(S))
- {
- return false;
- }
+ byte phflag = 0x01;
- PointExt pA = new PointExt();
- if (!DecodePointVar(pk, pkOff, true, pA))
- {
- return false;
- }
+ ImplSign(sk, skOff, pk, pkOff, ctx, phflag, m, 0, m.Length, sig, sigOff);
+ }
+ public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen)
+ {
byte phflag = 0x00;
- ShakeDigest d = new ShakeDigest(256);
- byte[] h = new byte[ScalarBytes * 2];
-
- Dom4(d, phflag, ctx);
- d.BlockUpdate(R, 0, PointBytes);
- d.BlockUpdate(pk, pkOff, PointBytes);
- d.BlockUpdate(m, mOff, mLen);
- d.DoFinal(h, 0, h.Length);
-
- byte[] k = ReduceScalar(h);
+ return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, mOff, mLen);
+ }
- uint[] nS = new uint[ScalarUints];
- DecodeScalar(S, 0, nS);
+ public static bool VerifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff)
+ {
+ byte phflag = 0x01;
- uint[] nA = new uint[ScalarUints];
- DecodeScalar(k, 0, nA);
+ return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, ph, phOff, PrehashSize);
+ }
- PointExt pR = new PointExt();
- ScalarMultStraussVar(nS, nA, pA, pR);
+ public static bool VerifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, IXof ph)
+ {
+ byte[] m = new byte[PrehashSize];
+ if (PrehashSize != ph.DoFinal(m, 0, PrehashSize))
+ throw new ArgumentException("ph");
- byte[] check = new byte[PointBytes];
- EncodePoint(pR, check, 0);
+ byte phflag = 0x01;
- return Arrays.AreEqual(check, R);
+ return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, 0, m.Length);
}
}
}
|