<commit_before>﻿using Newtonsoft.Json.Linq;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Math;
using System;
using System.Collections.Generic;
using System.Text;

namespace HiddenWallet.Crypto
{
    public class BlindingRsaPubKey : IEquatable<BlindingRsaPubKey>
	{
		public RsaKeyParameters KeyParameters { get; private set; }
		public BigInteger Modulus => KeyParameters.Modulus;
		public BigInteger Exponent => KeyParameters.Exponent;

		public BlindingRsaPubKey(RsaKeyParameters keyParameters)
		{
			KeyParameters = keyParameters ?? throw new ArgumentNullException(nameof(keyParameters));
		}

		public BlindingRsaPubKey(BigInteger modulus, BigInteger exponent)
		{
			if (modulus == null) throw new ArgumentNullException(nameof(modulus));
			if (exponent == null) throw new ArgumentNullException(nameof(exponent));

			KeyParameters = new RsaKeyParameters(false, modulus, exponent);
		}

		public (BigInteger BlindingFactor, byte[] BlindedData) Blind(byte[] data)
		{
			// generate blinding factor with pubkey
			var blindingFactorGenerator = new RsaBlindingFactorGenerator();
			blindingFactorGenerator.Init(KeyParameters);
			BigInteger blindingFactor = blindingFactorGenerator.GenerateBlindingFactor();
			
			// blind data
			var blindingParams = new RsaBlindingParameters(KeyParameters, blindingFactor);
			var blinder = new PssSigner(
				cipher: new RsaBlindingEngine(),
				digest: new Sha1Digest(),
				saltLen: 20);
			blinder.Init(forSigning: true, parameters: blindingParams);
			blinder.BlockUpdate(data, 0, data.Length);
			byte[] blindedData = blinder.GenerateSignature();

			return (blindingFactor, blindedData);
		}

		/// <returns>unblinded signature</returns>
		public byte[] UnblindSignature(byte[] blindedSignature, BigInteger blindingFactor)
		{
			var blindingEngine = new RsaBlindingEngine();
			var blindingParams = new RsaBlindingParameters(KeyParameters, blindingFactor);
			blindingEngine.Init(forEncryption: false, param: blindingParams);
			return blindingEngine.ProcessBlock(blindedSignature, 0, blindedSignature.Length);
		}

		public bool Verify(byte[] signature, byte[] data)
		{
			var verifier = new PssSigner(
				cipher: new RsaEngine(),
				digest: new Sha1Digest(),
				saltLen: 20);
			verifier.Init(forSigning: false, parameters: KeyParameters);
			verifier.BlockUpdate(data, 0, data.Length);
			return verifier.VerifySignature(signature);
		}

		public string ToJson()
		{
			dynamic json = new JObject();
			json.Modulus = Modulus.ToString();
			json.Exponent = Exponent.ToString();

			return json.ToString();<commit_msg>Use Sha256Digest, instead of Sha1Digest<commit_after>﻿using Newtonsoft.Json.Linq;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Math;
using System;
using System.Collections.Generic;
using System.Text;

namespace HiddenWallet.Crypto
{
    public class BlindingRsaPubKey : IEquatable<BlindingRsaPubKey>
	{
		public RsaKeyParameters KeyParameters { get; private set; }
		public BigInteger Modulus => KeyParameters.Modulus;
		public BigInteger Exponent => KeyParameters.Exponent;

		public BlindingRsaPubKey(RsaKeyParameters keyParameters)
		{
			KeyParameters = keyParameters ?? throw new ArgumentNullException(nameof(keyParameters));
		}

		public BlindingRsaPubKey(BigInteger modulus, BigInteger exponent)
		{
			if (modulus == null) throw new ArgumentNullException(nameof(modulus));
			if (exponent == null) throw new ArgumentNullException(nameof(exponent));

			KeyParameters = new RsaKeyParameters(false, modulus, exponent);
		}

		public (BigInteger BlindingFactor, byte[] BlindedData) Blind(byte[] data)
		{
			// generate blinding factor with pubkey
			var blindingFactorGenerator = new RsaBlindingFactorGenerator();
			blindingFactorGenerator.Init(KeyParameters);
			BigInteger blindingFactor = blindingFactorGenerator.GenerateBlindingFactor();
			
			// blind data
			var blindingParams = new RsaBlindingParameters(KeyParameters, blindingFactor);
			var blinder = new PssSigner(
				cipher: new RsaBlindingEngine(),
				digest: new Sha256Digest(),
				saltLen: 20);
			blinder.Init(forSigning: true, parameters: blindingParams);
			blinder.BlockUpdate(data, 0, data.Length);
			byte[] blindedData = blinder.GenerateSignature();

			return (blindingFactor, blindedData);
		}

		/// <returns>unblinded signature</returns>
		public byte[] UnblindSignature(byte[] blindedSignature, BigInteger blindingFactor)
		{
			var blindingEngine = new RsaBlindingEngine();
			var blindingParams = new RsaBlindingParameters(KeyParameters, blindingFactor);
			blindingEngine.Init(forEncryption: false, param: blindingParams);
			return blindingEngine.ProcessBlock(blindedSignature, 0, blindedSignature.Length);
		}

		public bool Verify(byte[] signature, byte[] data)
		{
			var verifier = new PssSigner(
				cipher: new RsaEngine(),
				digest: new Sha256Digest(),
				saltLen: 20);
			verifier.Init(forSigning: false, parameters: KeyParameters);
			verifier.BlockUpdate(data, 0, data.Length);
			return verifier.VerifySignature(signature);
		}

		public string ToJson()
		{
			dynamic json = new JObject();
			json.Modulus = Modulus.ToString();
			json.Exponent = Exponent.ToString();

			return json.ToString();
{'fraction_non_alphanumeric': 0.09739790386700398, 'fraction_numerical': 0.0046982291290206, 'mean_word_length': 5.254237288135593, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1872554', 'n_tokens_mistral': 1908, 'n_tokens_neox': 1623, 'n_words': 377}