Guest User

Feederiken.sc

a guest
Jun 11th, 2020
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env amm
  2.  
  3. // This is free and unencumbered software released into the public domain.
  4. //
  5. // Anyone is free to copy, modify, publish, use, compile, sell, or
  6. // distribute this software, either in source code form or as a compiled
  7. // binary, for any purpose, commercial or non-commercial, and by any
  8. // means.
  9. //
  10. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  11. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  12. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  13. // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  14. // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  15. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  16. // OTHER DEALINGS IN THE SOFTWARE.
  17.  
  18.  
  19. import $ivy.`dev.zio::zio:1.0.0-RC20`
  20. import zio._
  21.  
  22.  
  23. import $ivy.`org.bouncycastle:bcpg-jdk15on:1.65`
  24. import java.io._
  25. import java.security._
  26. import java.util.Date
  27. import org.bouncycastle.bcpg._
  28. import org.bouncycastle.jce.provider._
  29. import org.bouncycastle.openpgp._
  30. import org.bouncycastle.openpgp.operator._
  31. import org.bouncycastle.openpgp.operator.jcajce._
  32.  
  33.  
  34. object PGP {
  35.   def bouncyCastleProvider: TaskLayer[Has[Provider]] =
  36.     ZLayer.fromEffect(IO(new BouncyCastleProvider))
  37.  
  38.   def keyPairGenerator: RManaged[Has[Provider], KeyPairGenerator] = for {
  39.     provider <- Managed.service[Provider]
  40.     gen <- Managed.effect(KeyPairGenerator.getInstance("ed25519", provider))
  41.   } yield gen
  42.   def genKeyPair(kpg: KeyPairGenerator)(creationTime: Date): Task[PGPKeyPair] = for {
  43.     rawkp <- IO(kpg.generateKeyPair())
  44.     jcakp <- IO(new JcaPGPKeyPair(PublicKeyAlgorithmTags.EDDSA, rawkp, creationTime))
  45.   } yield jcakp
  46.  
  47.   def makeRing(kp: PGPKeyPair, userId: String): RIO[Has[Provider], PGPKeyRing] = for {
  48.     provider <- ZIO.service[Provider]
  49.     certificationLevel = PGPSignature.POSITIVE_CERTIFICATION
  50.     hashAlgorithmTag = HashAlgorithmTags.SHA256
  51.     checksumCalculator <- IO(new JcaPGPDigestCalculatorProviderBuilder().setProvider(provider).build().get(hashAlgorithmTag))
  52.     hashedPcks = null: PGPSignatureSubpacketVector
  53.     unhashedPcks = null: PGPSignatureSubpacketVector
  54.     keySignerBuilder = new JcaPGPContentSignerBuilder(kp.getPublicKey.getAlgorithm, hashAlgorithmTag).setProvider(provider)
  55.     keyEncryptor = null: PBESecretKeyEncryptor
  56.     ring <- IO(new PGPKeyRingGenerator(
  57.         certificationLevel, kp, userId, checksumCalculator, hashedPcks, unhashedPcks, keySignerBuilder, keyEncryptor
  58.       ).generateSecretKeyRing())
  59.   } yield ring
  60.  
  61.   def loadRing(in: InputStream): Task[PGPKeyRing] =
  62.     IO(new PGPPublicKeyRing(PGPUtil.getDecoderStream(in), new JcaKeyFingerprintCalculator))
  63.  
  64.   def saveRing(kr: PGPKeyRing, out: OutputStream): Task[Unit] =
  65.     Managed.fromAutoCloseable(IO(new ArmoredOutputStream(out))).use { out =>
  66.       IO(kr.encode(out))
  67.     }
  68. }
  69.  
  70.  
  71. object Feederiken extends App {
  72.   val ThreadCount = 8  // Adapt to your hardware
  73.   // Beware: the computation times goes up with the exponential of the length
  74.   val Prefix = Array[Byte](0xFE.toByte, 0xED.toByte)
  75.   // Author name. Can be changed afterwards. Put an e-mail address in square brackets if desired.
  76.   val UserId = "Anonymous"
  77.  
  78.   import PGP._
  79.   def bruteForceKey(prefix: Array[Byte], creationTime: Date) =
  80.     keyPairGenerator.use {
  81.       genKeyPair(_)(creationTime).doUntil(_.getPublicKey.getFingerprint.startsWith(prefix))
  82.     }
  83.  
  84.   def putBenchmark(n: Int, creationTime: Date) = {
  85.     val program = keyPairGenerator.use { kpg =>
  86.       def rec(n: Int): Task[Unit] =
  87.         if (n <= 0) IO.unit
  88.         else genKeyPair(kpg)(creationTime) *> rec(n - 1)
  89.       rec(n)
  90.     }
  91.     for {
  92.       (t, _) <- program.timed
  93.       freq = 1e9 / t.toNanos * n
  94.       _ <- console.putStrLn(s"Single-threaded hashrate: $freq Hz")
  95.     } yield ()
  96.   }
  97.  
  98.   def program = for {
  99.     creationTime <- IO(new Date)
  100.  
  101.     // quick benchmark
  102.     _ <- putBenchmark(10000, creationTime)
  103.  
  104.     // bruteforce in parallel
  105.     tasks = List.fill(ThreadCount)(bruteForceKey(Prefix, creationTime))
  106.  
  107.     // append result to results.asc
  108.     result <- tasks.head.raceAll(tasks.tail)
  109.     resultRing <- makeRing(result, UserId)
  110.     _ <- Managed.fromAutoCloseable(IO(new FileOutputStream("results.asc", true))).use(saveRing(resultRing, _))
  111.   } yield ()
  112.   def run(args: List[String]): zio.ZIO[zio.ZEnv, Nothing, zio.ExitCode] =
  113.     program.provideCustomLayer(bouncyCastleProvider).exitCode
  114. }
  115.  
  116. // Ammonite glue
  117. Feederiken.main(Array.empty)
Add Comment
Please, Sign In to add comment