} //end generate_captcha_pack_file method public static bool check_captcha_answer_for_index(int index, string captcha_answer) { byte[] publicKey = new byte[32]; byte[] encryptedSeed = new byte[32]; // byte[] image = new byte[125]; System.Buffer.BlockCopy(captchas_block_to_write, (index % block_length_to_write * CaptchaBlockLength), publicKey, 0, 32); //get public key from block System.Buffer.BlockCopy(captchas_block_to_write, (index % block_length_to_write * CaptchaBlockLength) + 32, encryptedSeed, 0, 32); //get encrypted_seed from block // System.Buffer.BlockCopy(captchas_block_to_write, (index%block_length_to_write * CaptchaBlockLength) + 32 + 32, image, 0, 125 ); //get bits of compressed captcha-image byte[] new_pubkey = new byte[32]; byte[] new_privkey = new byte[32]; Ed25519.KeyPairFromSeed(out new_pubkey, out new_privkey, ByteEncryptionUtil.WrappedXor(encryptedSeed, captcha_answer + publicKey.Stringify())); if (CompareTwoArrays(new_pubkey, publicKey)) { show_progress_and_write_data(index); //write blocks in file or show progress. //Console.WriteLine("Captcha_generator index = "+index+" is solved!"); return(true); } else { return(false); } }
public static bool save_the_captcha_answers = false; //if need to write the generated anwsers (optionally value, and disabled, false, by default). //method to generate captcha-pack-file public static void generate_captcha_pack_file(bool save_captcha_images_as_files = false, bool verify_captcha_answer_before_writting = true, bool logging = false, int set_number_of_captchas_for_one_dot = 1024, int set_block_length_to_write = 16384) { one_dot = set_number_of_captchas_for_one_dot; block_length_to_write = set_block_length_to_write; byte[] ed25519_seed = new byte[32]; //define the ed25519_seed array with length 32 bytes to store randomly generated Ed25519-seed. System.Security.Cryptography.RNGCryptoServiceProvider rand = new System.Security.Cryptography.RNGCryptoServiceProvider(); //initialize object once, to take crypto-strength random there on each iteration. Console.WriteLine("Starting to generate captchas..."); Console.WriteLine("save_captcha_images_as_files = " + save_captcha_images_as_files + ", verify_captcha_answer_before_writting = " + verify_captcha_answer_before_writting + ", logging = " + logging + ", set_number_of_captchas_for_one_dot = " + set_number_of_captchas_for_one_dot + ", set_block_length_to_write = " + set_block_length_to_write); Console.WriteLine("Each dot means already was been generated " + one_dot + " captchas,\nand this is contains in bytearray-buffer with size: " + block_length_to_write); //Start to generate 1024*1024 different captchas: for (int i = 0; i < 1048576; i++) { //create new captcha with public static Randomizer, which was been already defined once. Don't create this Randomizer again and again for each object. Captcha_generator captcha_image = new Captcha_generator(Randomizer); // generate in the cycle the many bitmaps 1000 bits = 1000 pixels, black or white, 20x50 with captchas, and save this with answer filename. if (save_captcha_images_as_files == true) //as optional param. { save_captchas_as_images(i, captcha_image); // Save image in file // test stop if (i > 10) { break; } //generate no more than 10 captcha images, and stop. } //Good working, and ok. // Now, don't save captcha images as PNG-files, and pack it in captcha-pack.nbc // Each block of captcha-pack-file contains ed25519_public_key(32 bytes) + encrypted_seed(32 bytes) + 1000 bits captcha image(125 bytes * 8 = 1000 bits). // To to this, need to gererate random seed, // thien get Ed25519 pubkey from this (privkey is seed + pub) // encrypt this pubkey by WrappedXOR with captcha_answer, // and save, then: // public key (32 bytes) // encrypted seed (32 bytes) // captcha image 1000 bits (189 bytes) // Save this all in the each block of captcha-pack file. rand.GetBytes(ed25519_seed); //generate ed25519_seed randomly byte[] ed25519_seed_and_publicKey = Ed25519.ExpandedPrivateKeyFromSeed(ed25519_seed); //private key = ed25519_seed + public key byte[] publicKey = new byte[32]; //define 32-bytes bytearray, to extract public key, as 32 last bytes. System.Buffer.BlockCopy(ed25519_seed_and_publicKey, 32, publicKey, 0, 32); //do extract the public key //Encrypt seed by captcha answer // seed is the generated random in "ed25519_seed", captcha_image.Text = answer, // Public Key - public-key (32 bytes, will be writted in block of captcha-pack-file), // not private key (seed + pub) byte[] encrypted_ed25519_seed = ByteEncryptionUtil.WrappedXor(ed25519_seed, (captcha_image.Text) + publicKey.Stringify()); //encrypt ed25519_seed as previous seed. //build the block with one captcha (32 bytes + 32 bytes + 1000 bits) byte[] captcha_block = new byte[32 + 32 + 125]; System.Buffer.BlockCopy(publicKey, 0, captcha_block, 0, 32); //write there the pub System.Buffer.BlockCopy(encrypted_ed25519_seed, 0, captcha_block, 32, 32); //encrypted seed // System.Buffer.BlockCopy( Captcha_generator.imageBits, 0, captcha_block, 32 + 32, 125 ); //and 1000 bits of captcha image. System.Buffer.BlockCopy(captcha_image._imageBits, 0, captcha_block, 32 + 32, 125); //and 1000 bits of captcha image. System.Buffer.BlockCopy( captcha_block, //the current captcha block 0, //from 0 offset captchas_block_to_write, //write here (i % block_length_to_write) * CaptchaBlockLength, //in this offset CaptchaBlockLength //all the current byte-block ); //and... System.Buffer.BlockCopy( System.Text.Encoding.UTF8.GetBytes(captcha_image.Text), //the captcha answer, as bytes 0, //from 0 offset captcha_answers_block_to_write, //write here (i % block_length_to_write) * CaptchaAnswerLength, //in this offset CaptchaAnswerLength //all the current byte-block ); byte[] decrypted_ed25519_seed = new byte[32]; //define bytearray to save decrypted_ed25519_seed //define two test bytearrays with length 32 bytes byte[] test_ed25519_seed_and_publicKey = new byte[64]; //define bytearray to save privkey (seed and pubkey) - 64 bytes byte[] test_new_pubkey = new byte[32]; //define bytearray extract pubkey - 32 bytes bool verified = false; //define this variable as false. This will be true, if captcha-answer is valid. if (verify_captcha_answer_before_writting == true) //as optional param //test code to check all values, before writting this in captcha-pack-file: //decrypt this, just for test. { decrypted_ed25519_seed = ByteEncryptionUtil.WrappedXor(encrypted_ed25519_seed, (captcha_image.Text) + publicKey.Stringify()); //compare decrypted seed with original ed25519_seed: // if(CompareTwoArrays(decrypted_ed25519_seed, ed25519_seed)){ // Console.WriteLine("decrypted_ed25519_seed and ed25519_seed arrays are equals!"); // } // extract privkey and pubkey from decrypted seed test_ed25519_seed_and_publicKey = Ed25519.ExpandedPrivateKeyFromSeed(decrypted_ed25519_seed); System.Buffer.BlockCopy(test_ed25519_seed_and_publicKey, 32, test_new_pubkey, 0, 32); //do extract the public key // or do this by one command: //Ed25519.KeyPairFromSeed(out test_new_pubkey, out test_ed25519_seed_and_publicKey, ByteEncryptionUtil.WrappedXor(encrypted_ed25519_seed, (captcha_image.Text) + publicKey.Stringify())); //compare pubkey with previous extracted pubkey. if (CompareTwoArrays(test_new_pubkey, publicKey)) { verified = true; } //update verified value by checking the captcha-answer using method to do this. verified = check_captcha_answer_for_index(i, (captcha_image.Text)); //write data or/and show progress will be if captcha is solved if (verified == false) { //fill both previous blocks with null-bytes System.Buffer.BlockCopy( new byte[CaptchaBlockLength], //null bytes block with the current captcha block length 0, //from 0 offset captchas_block_to_write, //write here (i % block_length_to_write) * CaptchaBlockLength, //in this offset CaptchaBlockLength //all the current byte-block ); //and System.Buffer.BlockCopy( new byte[CaptchaAnswerLength], //null bytes block with the current captcha answer length 0, //from 0 offset captcha_answers_block_to_write, //write here (i % block_length_to_write) * CaptchaAnswerLength, //in this offset CaptchaAnswerLength //all the current byte-block ); i -= 1; //back to previous captcha index continue; //and continue the cycle of generation the captchas } } else { show_progress_and_write_data(i); //just write block in data or/and show progress without verification of captcha_answer } if (logging == true) //as optional param. //Just for test - do logging the values of all variables: { FileUtil.Append( @"generation.log", "index: i = " + i + "\n(captcha_image.Text): " + (captcha_image.Text) + "\ned25519_seed(seed): " + ed25519_seed.Stringify() + "\nseed_and_publicKey: " + ed25519_seed_and_publicKey.Stringify() + "\npublicKey: " + publicKey.Stringify() + "\nencrypted_ed25519_seed: " + encrypted_ed25519_seed.Stringify() + ( (verify_captcha_answer_before_writting) ? "\ndecrypted_ed25519_seed: " + decrypted_ed25519_seed.Stringify() + "\nCompareTwoArrays(decrypted_ed25519_seed, ed25519_seed): " + CompareTwoArrays(decrypted_ed25519_seed, ed25519_seed) + "\ntest_new_pubkey: " + test_new_pubkey.Stringify() + "\ntest_ed25519_seed_and_publicKey: " + test_ed25519_seed_and_publicKey.Stringify() + "\nCompareTwoArrays(test_new_pubkey, publicKey): " + CompareTwoArrays(test_new_pubkey, publicKey) + "\nverified: " + verified : "" ) + "\ncaptcha_block: " + captcha_block.Stringify() + "\ncaptcha_image.ImageAsByteArray: " + captcha_image.ImageAsByteArray.Stringify() //not compressed image, as bytearray + "\nCaptcha_generator.imageBits: " + Captcha_generator.imageBits.Stringify() //get compressed b/w bit-image from static field of current created captcha-object + "\ncaptcha_image._imageBits: " + captcha_image._imageBits.Stringify() //get compressed b/w bit-image from specified captcha-object + "\ncaptcha_image._imageBits_dataURI:\n" + captcha_image._imageBits_dataURI //this can be opened in browser tab to see captcha. + "\n\n\n\n\n\n" ); } //end if logging } //end brute-force cycle } //end generate_captcha_pack_file method