private static void Dom4(IXof d, byte x, byte[] y) { d.BlockUpdate(Dom4Prefix, 0, Dom4Prefix.Length); d.Update(x); d.Update((byte)y.Length); d.BlockUpdate(y, 0, y.Length); }
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 Dom4(IXof d, byte phflag, byte[] ctx) { int n = Dom4Prefix.Length; byte[] t = new byte[n + 2 + ctx.Length]; Dom4Prefix.CopyTo(t, 0); t[n] = phflag; t[n + 1] = (byte)ctx.Length; ctx.CopyTo(t, n + 2); d.BlockUpdate(t, 0, t.Length); }
public static void GeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff) { 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); ScalarMultBaseEncoded(s, pk, pkOff); }
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) { Dom4(d, phflag, ctx); d.BlockUpdate(h, ScalarBytes, ScalarBytes); d.BlockUpdate(m, mOff, mLen); d.DoFinal(h, 0, h.Length); byte[] r = ReduceScalar(h); byte[] R = new byte[PointBytes]; ScalarMultBaseEncoded(r, R, 0); 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); byte[] S = CalculateS(r, k, s); Array.Copy(R, 0, sig, sigOff, PointBytes); Array.Copy(S, 0, sig, sigOff + PointBytes, ScalarBytes); }
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); }
public void TestEd448phConsistency() { byte[] sk = new byte[Ed448.SecretKeySize]; byte[] pk = new byte[Ed448.PublicKeySize]; byte[] ctx = new byte[Random.NextInt() & 7]; byte[] m = new byte[255]; byte[] ph = new byte[Ed448.PrehashSize]; byte[] sig1 = new byte[Ed448.SignatureSize]; byte[] sig2 = new byte[Ed448.SignatureSize]; Random.NextBytes(ctx); Random.NextBytes(m); for (int i = 0; i < 10; ++i) { Random.NextBytes(sk); Ed448.GeneratePublicKey(sk, 0, pk, 0); int mLen = Random.NextInt() & 255; IXof prehash = Ed448.CreatePrehash(); prehash.BlockUpdate(m, 0, mLen); prehash.DoFinal(ph, 0, ph.Length); Ed448.SignPrehash(sk, 0, ctx, ph, 0, sig1, 0); Ed448.SignPrehash(sk, 0, pk, 0, ctx, ph, 0, sig2, 0); Assert.IsTrue(Arrays.AreEqual(sig1, sig2), "Ed448ph consistent signatures #" + i); bool shouldVerify = Ed448.VerifyPrehash(sig1, 0, pk, 0, ctx, ph, 0); Assert.IsTrue(shouldVerify, "Ed448ph consistent sign/verify #" + i); sig1[Ed448.PublicKeySize - 1] ^= 0x80; bool shouldNotVerify = Ed448.VerifyPrehash(sig1, 0, pk, 0, ctx, ph, 0); Assert.IsFalse(shouldNotVerify, "Ed448ph consistent verification failure #" + i); } }
private static void CheckEd448phVector(string sSK, string sPK, string sM, string sCTX, string sSig, string text) { byte[] sk = Hex.Decode(sSK); byte[] pk = Hex.Decode(sPK); byte[] pkGen = new byte[Ed448.PublicKeySize]; Ed448.GeneratePublicKey(sk, 0, pkGen, 0); Assert.IsTrue(Arrays.AreEqual(pk, pkGen), text); byte[] m = Hex.Decode(sM); byte[] ctx = Hex.Decode(sCTX); byte[] sig = Hex.Decode(sSig); byte[] badsig = Arrays.Clone(sig); badsig[Ed448.SignatureSize - 1] ^= 0x80; byte[] sigGen = new byte[Ed448.SignatureSize]; { IXof prehash = Ed448.CreatePrehash(); prehash.BlockUpdate(m, 0, m.Length); byte[] ph = new byte[Ed448.PrehashSize]; prehash.DoFinal(ph, 0, ph.Length); Ed448.SignPrehash(sk, 0, ctx, ph, 0, sigGen, 0); Assert.IsTrue(Arrays.AreEqual(sig, sigGen), text); Ed448.SignPrehash(sk, 0, pk, 0, ctx, ph, 0, sigGen, 0); Assert.IsTrue(Arrays.AreEqual(sig, sigGen), text); bool shouldVerify = Ed448.VerifyPrehash(sig, 0, pk, 0, ctx, ph, 0); Assert.IsTrue(shouldVerify, text); bool shouldNotVerify = Ed448.VerifyPrehash(badsig, 0, pk, 0, ctx, ph, 0); Assert.IsFalse(shouldNotVerify, text); } { IXof ph = Ed448.CreatePrehash(); ph.BlockUpdate(m, 0, m.Length); Ed448.SignPrehash(sk, 0, ctx, ph, sigGen, 0); Assert.IsTrue(Arrays.AreEqual(sig, sigGen), text); } { IXof ph = Ed448.CreatePrehash(); ph.BlockUpdate(m, 0, m.Length); Ed448.SignPrehash(sk, 0, pk, 0, ctx, ph, sigGen, 0); Assert.IsTrue(Arrays.AreEqual(sig, sigGen), text); } { IXof ph = Ed448.CreatePrehash(); ph.BlockUpdate(m, 0, m.Length); bool shouldVerify = Ed448.VerifyPrehash(sig, 0, pk, 0, ctx, ph); Assert.IsTrue(shouldVerify, text); } { IXof ph = Ed448.CreatePrehash(); ph.BlockUpdate(m, 0, m.Length); bool shouldNotVerify = Ed448.VerifyPrehash(badsig, 0, pk, 0, ctx, ph); Assert.IsFalse(shouldNotVerify, text); } }
public virtual void BlockUpdate(byte[] buf, int off, int len) { prehash.BlockUpdate(buf, off, len); }