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)); }
static public EdDSAPoint448 Add(EdDSAPoint448 p1, EdDSAPoint448 p2) { BigInteger A = p1.Z.Multiply(p2.Z).Mod(p); BigInteger B = A.Square().Mod(p); BigInteger C = p1.X.Multiply(p2.X).Mod(p); BigInteger D = p1.Y.Multiply(p2.Y).Mod(p); BigInteger E = d.Multiply(C).Mod(p).Multiply(D).Mod(p); BigInteger F = B.Subtract(E).Mod(p); BigInteger G = B.Add(E).Mod(p); BigInteger H = (p1.X.Add(p1.Y)).Mod(p).Multiply(p2.X.Add(p2.Y).Mod(p)).Mod(p); BigInteger X3 = A.Multiply(F).Mod(p).Multiply(H.Subtract(C).Mod(p).Subtract(D).Mod(p)).Mod(p); BigInteger Y3 = A.Multiply(G).Mod(p).Multiply(D.Subtract(C).Mod(p)).Mod(p); BigInteger Z3 = F.Multiply(G).Mod(p); return(new EdDSAPoint448(X3, Y3, Z3)); }
public override EdDSAPoint MultipleByScalar(BigInteger k) { int i; EdDSAPoint448 result = new EdDSAPoint448(zero, one, one); EdDSAPoint448 pNext = this; for (i = 0; i < k.BitLength; i++) { if (k.TestBit(i)) { result = Add(pNext, result); } pNext = pNext.Double(); } return(result.Normalize()); }
EdDSAPoint448 Double() { EdDSAPoint tmp = new EdDSAPoint448(zero, one); BigInteger C = this.X.Square().Mod(p); BigInteger D = this.Y.Square().Mod(p); BigInteger H = this.Z.Square().Mod(p); BigInteger E = C.Add(D).Mod(p); BigInteger B = this.X.Add(this.Y).Mod(p).Square().Mod(p); BigInteger J = E.Subtract(H.Add(H).Mod(p)).Mod(p); BigInteger X = B.Subtract(E).Mod(p).Multiply(J).Mod(p); BigInteger Y = E.Multiply(C.Subtract(D).Mod(p)).Mod(p); BigInteger Z = E.Multiply(J).Mod(p); return(new EdDSAPoint448(X, Y, Z)); // return Add(this, this); }
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); }