summaryrefslogtreecommitdiffstats
path: root/challenge
diff options
context:
space:
mode:
authorsiddharth ravikumar <s@ricketyspace.net>2022-11-25 12:50:50 -0500
committersiddharth ravikumar <s@ricketyspace.net>2022-11-25 12:50:50 -0500
commit57dc4c21f4880e359fc3c85d7d85bdf3a8950220 (patch)
treeefa61764736dbb5ee5dfc02bae1937607cfd8963 /challenge
parent73b0bec6c8c2aaf0f8b4e22a60a925881b202a15 (diff)
challenge: do challenge 40v0.40.0
Diffstat (limited to 'challenge')
-rw-r--r--challenge/c40.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/challenge/c40.go b/challenge/c40.go
new file mode 100644
index 0000000..ec16059
--- /dev/null
+++ b/challenge/c40.go
@@ -0,0 +1,82 @@
+// Copyright © 2022 siddharth ravikumar <s@ricketyspace.net>
+// SPDX-License-Identifier: ISC
+
+package challenge
+
+import (
+ "fmt"
+ "math/big"
+
+ "ricketyspace.net/cryptopals/lib"
+)
+
+func C40() {
+ msg := []byte("42 is the answer.")
+
+ // Generate 3 rsa key pairs and capture the their public keys.
+ var rsaPubs []*lib.RSAPub
+ for i := 0; i < 3; i++ {
+ rsa, err := lib.RSAGenKey()
+ if err != nil {
+ fmt.Printf("gen key failed: %v", err)
+ return
+ }
+ rsaPubs = append(rsaPubs, rsa.Public)
+ }
+
+ // Encrypt message with the 3 rsa public keys.
+ var ciphers [][]byte
+ for i := 0; i < 3; i++ {
+ enc := rsaPubs[i].Encrypt(msg)
+ if len(enc) < 1 {
+ fmt.Printf("encrypt failed: %v", enc)
+ return
+ }
+ ciphers = append(ciphers, enc)
+ }
+
+ // Compute m_s_n
+ var msn []*big.Int
+ for i := 0; i < 3; i++ {
+ msn = append(msn, big.NewInt(0).Mul(
+ rsaPubs[(i+1)%3].N(), rsaPubs[(i+2)%3].N(),
+ ))
+ }
+
+ // Compute N_012
+ n012 := big.NewInt(1)
+ for _, rpub := range rsaPubs {
+ n012 = n012.Mul(n012, rpub.N())
+ }
+
+ // Compute combination of residues.
+ result := big.NewInt(0)
+ for i := 0; i < 3; i++ {
+ r := big.NewInt(0).Mul(
+ big.NewInt(0).SetBytes(ciphers[i]),
+ msn[i],
+ ) // c_i * m_s_i
+
+ // invmod(m_s_i, n_i)
+ im, err := lib.InvMod(msn[i], rsaPubs[i].N())
+ if err != nil {
+ fmt.Printf("invmod: invmod(m_s_%d, n_%d): %v",
+ i, i, err,
+ )
+ return
+ }
+
+ // c_i * m_s_i * invmod(m_s_i, n_i)
+ r = r.Mul(r, im)
+
+ // Add to result.
+ result.Add(result, r)
+ }
+
+ // result mod N_012
+ result = result.Mod(result, n012)
+
+ // Cube root the result.
+ deci := lib.BigIntCubeRoot(result)
+ fmt.Printf("Decrypted message: %s\n", deci.Bytes())
+}