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); Sha512Digest sha256 = new Sha512Digest(); byte[] dom = Dom(rgbContext); sha256.BlockUpdate(dom, 0, dom.Length); sha256.BlockUpdate(r, 0, r.Length); sha256.BlockUpdate(publicKey, 0, publicKey.Length); sha256.BlockUpdate(message, 0, message.Length); byte[] h = new byte[64]; sha256.DoFinal(h, 0); Array.Reverse(h); BigInteger k = new BigInteger(1, h).Mod(L); EdDSAPoint left = EdDSAPoint25517.B.MultipleByScalar(S).Normalize(); EdDSAPoint right = EdDSAPoint25517.Add((EdDSAPoint25517)R, (EdDSAPoint25517)A.MultipleByScalar(k)).Normalize(); return(left.equal(right)); }
override public byte[] Encode() { EdDSAPoint25517 point = (EdDSAPoint25517)this.Normalize(); byte[] rgbY = new byte[32]; Array.Copy(point.Y.ToByteArrayUnsigned(), rgbY, rgbY.Length); rgbY[0] |= (byte)(point.X.TestBit(0) ? 0x80 : 0); Array.Reverse(rgbY); return(rgbY); }
public override byte[] Sign(byte[] publicKey, byte[] privateKey, byte[] M, byte[] rgbContext = null) { Sha512Digest sha512 = new Sha512Digest(); sha512.BlockUpdate(privateKey, 0, privateKey.Length); byte[] h = new byte[sha512.GetDigestSize()]; sha512.DoFinal(h, 0); byte[] x = new byte[32]; Array.Copy(h, x, 32); x[0] &= 0xf8; // Clear lowest 3 bits x[31] |= 0x40; // Set the highest bit x[31] &= 0x7f; // Clear the highest bit Array.Reverse(x); byte[] prefix = new byte[32]; Array.Copy(h, 32, prefix, 0, 32); BigInteger a = new BigInteger(1, x); byte[] A = publicKey; M = PreHash(M); sha512.Reset(); byte[] dom = Dom(rgbContext); sha512.BlockUpdate(dom, 0, dom.Length); sha512.BlockUpdate(prefix, 0, prefix.Length); sha512.BlockUpdate(M, 0, M.Length); byte[] r1 = new byte[64]; sha512.DoFinal(r1, 0); Array.Reverse(r1); BigInteger r = new BigInteger(1, r1).Mod(L); EdDSAPoint25517 rB = (EdDSAPoint25517)EdDSAPoint25517.B.MultipleByScalar(r); byte[] R = rB.Encode(); sha512.Reset(); sha512.BlockUpdate(dom, 0, dom.Length); sha512.BlockUpdate(R, 0, R.Length); sha512.BlockUpdate(A, 0, A.Length); sha512.BlockUpdate(M, 0, M.Length); byte[] kBytes = new byte[64]; sha512.DoFinal(kBytes, 0); Array.Reverse(kBytes); BigInteger k = new BigInteger(1, kBytes).Mod(L); BigInteger S = r.Add(k.Multiply(a)).Mod(L); byte[] hash = new byte[64]; byte[] s = S.ToByteArrayUnsigned(); Array.Copy(s, 0, hash, 32 - s.Length, s.Length); Array.Reverse(hash); Array.Copy(R, hash, 32); return(hash); }
public override EdDSAPoint GetPublic(byte[] privateKey) { Sha512Digest sha512 = new Sha512Digest(); byte[] h = new byte[64]; sha512.BlockUpdate(privateKey, 0, 32); sha512.DoFinal(h, 0); Array.Resize(ref h, 32); h[0] &= 0xf8; // Clear lowest 3 bits h[31] |= 0x40; // Set the highest bit h[31] &= 0x7f; // Clear the highest bit Array.Reverse(h); BigInteger a = new BigInteger(1, h); EdDSAPoint25517 publicKey = (EdDSAPoint25517)EdDSAPoint25517.B.MultipleByScalar(a); return(publicKey); }
public override EdDSAPoint MultipleByScalar(BigInteger k) { int i; EdDSAPoint25517 result = new EdDSAPoint25517(zero, one, one, zero); EdDSAPoint25517 pNext = this; for (i = 0; i < k.BitLength; i++) { if (k.TestBit(i)) { result = Add(pNext, result); } pNext = pNext.Double(); } return(result.Normalize()); }
static public EdDSAPoint25517 Add(EdDSAPoint25517 p1, EdDSAPoint25517 p2) { BigInteger A = p1.Y.Subtract(p1.X).Multiply(p2.Y.Subtract(p2.X)).Mod(p); BigInteger B = p1.Y.Add(p1.X).Multiply(p2.Y.Add(p2.X)).Mod(p); BigInteger C = p1.T.Multiply(Two).Multiply(d).Multiply(p2.T).Mod(p); BigInteger D = p1.Z.Multiply(Two).Multiply(p2.Z).Mod(p); BigInteger E = B.Subtract(A).Mod(p); BigInteger F = D.Subtract(C).Mod(p); BigInteger G = D.Add(C).Mod(p); BigInteger H = B.Add(A).Mod(p); BigInteger X3 = E.Multiply(F).Mod(p); BigInteger Y3 = G.Multiply(H).Mod(p); BigInteger T3 = E.Multiply(H).Mod(p); BigInteger Z3 = F.Multiply(G).Mod(p); return(new EdDSAPoint25517(X3, Y3, Z3, T3)); }