public override Boolean Verify(byte[] publicKey, byte[] message, byte[] signature, byte[] rgbContext = null) { EdDSAPoint A = DecodePoint(publicKey); byte[] r = new byte[signature.Length / 2]; Array.Copy(signature, r, r.Length); EdDSAPoint R = DecodePoint(r); byte[] s = new byte[signature.Length / 2]; Array.Copy(signature, r.Length, s, 0, r.Length); Array.Reverse(s); BigInteger S = new BigInteger(1, s); message = PreHash(message); ShakeDigest sha256 = new ShakeDigest(256); byte[] rgbDom = Dom(rgbContext); sha256.BlockUpdate(rgbDom, 0, rgbDom.Length); sha256.BlockUpdate(r, 0, r.Length); sha256.BlockUpdate(publicKey, 0, publicKey.Length); sha256.BlockUpdate(message, 0, message.Length); byte[] h = new byte[114]; sha256.DoFinal(h, 0, 114); Array.Reverse(h); BigInteger k = new BigInteger(1, h).Mod(EdDSAPoint448.L); EdDSAPoint left = EdDSAPoint448.B.MultipleByScalar(S).Normalize(); EdDSAPoint right = EdDSAPoint448.Add((EdDSAPoint448)R, (EdDSAPoint448)A.MultipleByScalar(k)).Normalize(); return(left.equal(right)); }
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) { byte phflag = 0x00; 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 Dom4(ShakeDigest 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); }
public override byte[] PreHash(byte[] Message) { ShakeDigest digest = new ShakeDigest(256); digest.BlockUpdate(Message, 0, Message.Length); byte[] result = new byte[64]; digest.DoFinal(result, 0, 64); return(result); }
public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, 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); } 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); 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)); }
public override byte[] Sign(byte[] publicKey, byte[] privateKey, byte[] M, byte[] context = null) { ShakeDigest sha512 = new ShakeDigest(256); sha512.BlockUpdate(privateKey, 0, privateKey.Length); byte[] h = new byte[114]; sha512.DoFinal(h, 0, 114); byte[] x = new byte[57]; Array.Copy(h, x, 57); x[0] &= 0xfc; // Clear lowest 2 bits x[56] = 0; // Clear the highest byte x[55] |= 0x80; // Set the highest bit Array.Reverse(x); BigInteger a = new BigInteger(1, x); byte[] A = publicKey; byte[] prefix = new byte[57]; Array.Copy(h, 57, prefix, 0, 57); M = PreHash(M); sha512.Reset(); byte[] domBytes = Dom(context); sha512.BlockUpdate(domBytes, 0, domBytes.Length); sha512.BlockUpdate(prefix, 0, prefix.Length); sha512.BlockUpdate(M, 0, M.Length); byte[] r1 = new byte[114]; sha512.DoFinal(r1, 0, 114); Array.Reverse(r1); BigInteger r = new BigInteger(1, r1).Mod(EdDSAPoint448.L); EdDSAPoint rB = EdDSAPoint448.B.MultipleByScalar(r); byte[] R = rB.Encode(); sha512.Reset(); sha512.BlockUpdate(domBytes, 0, domBytes.Length); sha512.BlockUpdate(R, 0, R.Length); sha512.BlockUpdate(A, 0, A.Length); sha512.BlockUpdate(M, 0, M.Length); byte[] kBytes = new byte[114]; sha512.DoFinal(kBytes, 0, 114); Array.Reverse(kBytes); BigInteger k = new BigInteger(1, kBytes).Mod(EdDSAPoint448.L); BigInteger S = r.Add(k.Multiply(a)).Mod(EdDSAPoint448.L); byte[] hash = new byte[57 * 2]; byte[] rgbS = S.ToByteArrayUnsigned(); Array.Copy(rgbS, 0, hash, 57 - rgbS.Length, rgbS.Length); Array.Reverse(hash); Array.Copy(R, hash, 57); return(hash); }
public static void GeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff) { ShakeDigest d = new ShakeDigest(256); 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 void checkSHAKE(int bitSize, CShakeDigest cshake, byte[] msg) { ShakeDigest ref_ = new ShakeDigest(bitSize); ref_.BlockUpdate(msg, 0, msg.Length); cshake.BlockUpdate(msg, 0, msg.Length); byte[] res1 = new byte[32]; byte[] res2 = new byte[32]; ref_.DoFinal(res1, 0, res1.Length); cshake.DoFinal(res2, 0, res2.Length); Assert.IsTrue(Arrays.AreEqual(res1, res2)); }
public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) { if (!CheckContextVar(ctx)) { throw new ArgumentException("ctx"); } ShakeDigest d = new ShakeDigest(256); 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, m, mOff, mLen, sig, sigOff); }
public override EdDSAPoint GetPublic(byte[] privateKey) { if (privateKey.Length != 57) { throw new CoseException("Invalid private key"); } ShakeDigest shake = new ShakeDigest(256); byte[] h = new byte[114]; shake.BlockUpdate(privateKey, 0, privateKey.Length); shake.DoFinal(h, 0, 114); Array.Resize(ref h, 57); h[0] &= 0xfc; // Clear lowest 2 bits h[56] = 0; // Clear the highest byte h[55] |= 0x80; // Set the highest bit Array.Reverse(h); BigInteger a = new BigInteger(1, h); EdDSAPoint448 publicKey = (EdDSAPoint448)EdDSAPoint448.B.MultipleByScalar(a); return(publicKey); }
public ShakeDigest(ShakeDigest source) : base(source) { }