public static bool DoVerifyEcDsa( IEnumerable <BufLen> bufs, I2PSigningPublicKey key, I2PSignature signed, IDigest digest, X9ECParameters ecparam) { if (!SupportedSignatureType(signed.Certificate.SignatureType)) { throw new NotImplementedException(); } foreach (var buf in bufs) { digest.BlockUpdate(buf.BaseArray, buf.BaseArrayOffset, buf.Length); } var hash = new byte[digest.GetDigestSize()]; digest.DoFinal(hash, 0); var param = new ECDomainParameters(ecparam.Curve, ecparam.G, ecparam.N, ecparam.H); var pk = new ECPublicKeyParameters(ecparam.Curve.DecodePoint(key.ToByteArray()), param); var dsa = new Org.BouncyCastle.Crypto.Signers.DsaSigner(); var sigsize = signed.Certificate.SignatureLength; var r = new BigInteger(1, signed.Sig.BaseArray, signed.Sig.BaseArrayOffset, sigsize / 2); var s = new BigInteger(1, signed.Sig.BaseArray, signed.Sig.BaseArrayOffset + sigsize / 2, sigsize / 2); dsa.Init(false, pk); var result = dsa.VerifySignature(hash, r, s); DebugUtils.LogDebug("DoVerifyEcDsa: " + result.ToString() + ": " + digest.ToString()); return(result); }
public static byte[] DoSignEcDsa( IEnumerable <BufLen> bufs, I2PSigningPrivateKey key, IDigest digest, X9ECParameters ecparam, int sigsize) { foreach (var buf in bufs) { digest.BlockUpdate(buf.BaseArray, buf.BaseArrayOffset, buf.Length); } var hash = new byte[digest.GetDigestSize()]; digest.DoFinal(hash, 0); var param = new ECDomainParameters(ecparam.Curve, ecparam.G, ecparam.N, ecparam.H); var pk = new ECPrivateKeyParameters(key.ToBigInteger(), param); var s = new Org.BouncyCastle.Crypto.Signers.ECDsaSigner(); s.Init(true, new ParametersWithRandom(pk)); var sig = s.GenerateSignature(hash); var result = new byte[sigsize]; var b1 = sig[0].ToByteArrayUnsigned(); var b2 = sig[1].ToByteArrayUnsigned(); // https://geti2p.net/en/docs/spec/common-structures#type_Signature // When a signature is composed of two elements (for example values R,S), // it is serialized by padding each element to length/2 with leading zeros if necessary. // All types are Big Endian, except for EdDSA, which is stored and transmitted in a Little Endian format. // Pad msb. Big endian. Array.Copy(b1, 0, result, sigsize / 2 - b1.Length, b1.Length); Array.Copy(b2, 0, result, sigsize - b2.Length, b2.Length); DebugUtils.LogDebug("DoSignEcDsa: " + digest.ToString() + ": Used."); return(result); }