diff --git a/go.mod b/go.mod
index 43bd23b51..858bea965 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/urfave/cli v1.22.16
github.com/xtaci/kcp-go/v5 v5.6.18
- github.com/xtaci/qpp v1.1.17
+ github.com/xtaci/qpp v1.1.18
github.com/xtaci/smux v1.5.32
github.com/xtaci/tcpraw v1.2.31
golang.org/x/crypto v0.31.0
diff --git a/go.sum b/go.sum
index 6724f71bc..52bcf4ffa 100644
--- a/go.sum
+++ b/go.sum
@@ -72,8 +72,8 @@ github.com/xtaci/kcp-go/v5 v5.6.18 h1:7oV4mc272pcnn39/13BB11Bx7hJM4ogMIEokJYVWn4
github.com/xtaci/kcp-go/v5 v5.6.18/go.mod h1:75S1AKYYzNUSXIv30h+jPKJYZUwqpfvLshu63nCNSOM=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
-github.com/xtaci/qpp v1.1.17 h1:w35NYqF3wOBoAMs+2qA2XFjkNQ12mugw51CUJ7OcTzo=
-github.com/xtaci/qpp v1.1.17/go.mod h1:dJS3usaXNMbWxZSWCAdxz01UgJcz9wXDkd4BccDY/V0=
+github.com/xtaci/qpp v1.1.18 h1:FyULigD8/msXdxj9AjOFQg3/Z/tGz4574n21shZ6SZo=
+github.com/xtaci/qpp v1.1.18/go.mod h1:DI0dcoZ+qu4ze5C0hkt8grLfTVqBiZ3hXTimGyg5TTI=
github.com/xtaci/smux v1.5.32 h1:IDdOaJDf8jk5NHKlTw05ge+0rdMjnXg3cwHkss5Pbcw=
github.com/xtaci/smux v1.5.32/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
github.com/xtaci/tcpraw v1.2.31 h1:i9mXzejnGJdGi0DpVKUn19Hq202/sHOJt0kObEwuE/U=
diff --git a/vendor/github.com/xtaci/qpp/.gitignore b/vendor/github.com/xtaci/qpp/.gitignore
index 6f6f5e6ad..e5c574253 100644
--- a/vendor/github.com/xtaci/qpp/.gitignore
+++ b/vendor/github.com/xtaci/qpp/.gitignore
@@ -13,6 +13,7 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
+chi-square.csv
# Dependency directories (remove the comment below to include it)
# vendor/
diff --git a/vendor/github.com/xtaci/qpp/README.md b/vendor/github.com/xtaci/qpp/README.md
index ef48dc99d..45b3f1e62 100644
--- a/vendor/github.com/xtaci/qpp/README.md
+++ b/vendor/github.com/xtaci/qpp/README.md
@@ -1,12 +1,13 @@
# Quantum Permutation Pad
-![image](https://github.com/xtaci/qpp/assets/2346725/7a05cc4b-b207-437e-a015-57918906b738)
-[![GoDoc][1]][2] [![Go Report Card][3]][4]
+[![GoDoc][1]][2] [![Go Report Card][3]][4] [![CreatedAt][5]][6]
[1]: https://godoc.org/github.com/xtaci/qpp?status.svg
[2]: https://pkg.go.dev/github.com/xtaci/qpp
[3]: https://goreportcard.com/badge/github.com/xtaci/qpp
[4]: https://goreportcard.com/report/github.com/xtaci/qpp
+[5]: https://img.shields.io/github/created-at/xtaci/qpp
+[6]: https://img.shields.io/github/created-at/xtaci/qpp
The [Quantum Permutation Pad](https://link.springer.com/content/pdf/10.1140/epjqt/s40507-023-00164-3.pdf) (QPP) is a cryptographic protocol designed to leverage the principles of quantum mechanics for secure communication. While the exact details of the QPP can vary based on the specific implementation and the theoretical model, the general concept involves using quantum properties such as superposition and entanglement to enhance the security of data transmission. Here’s an overview of the QPP and its relationship to quantum mechanics and cryptography:
@@ -16,21 +17,11 @@ The [Quantum Permutation Pad](https://link.springer.com/content/pdf/10.1140/epjq
2. **Quantum Bits (Qubits)**: Instead of classical bits (which are either 0 or 1), QPP uses qubits, which can be in a state of 0, 1, or any quantum superposition of these states.
-3. **Permutation Operations**: Permutations in the context of QPP refer to rearranging the ways to **transform/interpret** the plaintext comparing to rearranging the keys round and round in classical cryptography. These total permutations can be thought of as $P_n$. For a 8-bit byte, the permutations is $P_{256} = 256! = 857817775342842654119082271681232625157781520279485619859655650377269452553147589377440291360451408450375885342336584306157196834693696475322289288497426025679637332563368786442675207626794560187968867971521143307702077526646451464709187326100832876325702818980773671781454170250523018608495319068138257481070252817559459476987034665712738139286205234756808218860701203611083152093501947437109101726968262861606263662435022840944191408424615936000000000000000000000000000000000000000000000000000000000000000$
-
-## Functionality of Quantum Permutation Pad
+3. **Permutation Operations**: Permutations in the context of QPP refer to rearranging the ways to **transform/interpret** the plaintext comparing to rearranging the keys round and round in classical cryptography. These total permutations can be thought of as $P_n$. For a 8-bit byte, the overall permutations is $P_{256} =$
+```256! =857817775342842654119082271681232625157781520279485619859655650377269452553147589377440291360451408450375885342336584306157196834693696475322289288497426025679637332563368786442675207626794560187968867971521143307702077526646451464709187326100832876325702818980773671781454170250523018608495319068138257481070252817559459476987034665712738139286205234756808218860701203611083152093501947437109101726968262861606263662435022840944191408424615936000000000000000000000000000000000000000000000000000000000000000```
+4. Classical key space for 8-bit is 256 possible key (inters), then move qpp, the quantum key space become 256! possible permutation operators or gates!
+5. QPP can be implemented both classically with matrices and quantum mechanically with quantum gates .
-1. **Key Generation**: The QPP protocol involves generating a key based on quantum states. This key can be a set of quantum gates or permutation operations that will be applied to the qubits.
-
-2. **Encryption**:
- - **Prepare Qubits**: The sender prepares a set of qubits in a known quantum state.
- - **Apply Permutations**: Using the generated key, the sender applies a series of permutation operations to the qubits. These permutations act as the encryption process, transforming the quantum state into an encrypted form.
-
-3. **Transmission**: The encrypted quantum state (the qubits after permutation) is transmitted to the receiver.
-
-4. **Decryption**:
- - **Reverse Permutations**: The receiver, who has the same key, applies the inverse of the permutation operations to the received qubits. This step decrypts the quantum state, returning it to its original form.
- - **Measurement**: The receiver then measures the qubits to obtain the classical data.
## Applications and Benefits
@@ -38,21 +29,7 @@ The [Quantum Permutation Pad](https://link.springer.com/content/pdf/10.1140/epjq
- **Future-Proof**: As quantum computers become more powerful, classical cryptographic schemes (like RSA and ECC) are at risk. QPP provides a quantum-resistant alternative.
- **Secure Communication**: Useful for secure communications in quantum networks and for safeguarding highly sensitive data.
-## Security design in this implementatoin
-The overall security is equivalent to **1680-bit** symmetric encryption, with each **BYTE** possessing a cryptographic strength of 256 bits.
-
-The number of permutation matrices in an 8-qubit system is determined based on the provided seed and is selected randomly.
-
-
-Try directly from https://github.com/xtaci/kcptun/releases with the ```-QPP``` option enabled.
-
-The permutation pad could be written in [Cycle notation](https://en.wikipedia.org/wiki/Permutation#Cycle_notation) as: $\sigma =(1\ 2\ 255)(3\ 36)(4\ 82\ 125)(....)$, which the elements are not reversible by encrypting twice simply.
-
-## Performance
-![image](https://github.com/user-attachments/assets/4061d4a9-e7fa-43f5-89ef-f6ef6c00a2e7)
-
-
-## Usage
+## Example Usage
Internal PRNG(NOT RECOMMENDED)
```golang
func main() {
@@ -69,7 +46,7 @@ func main() {
}
```
-External PRNG(**RECOMMENDED**)
+External PRNG, with shared pads. (**RECOMMENDED**)
```golang
func main() {
seed := make([]byte, 32)
@@ -88,17 +65,55 @@ func main() {
}
```
+The NewQPP generates permutations like(in [cycle notation](https://en.wikipedia.org/wiki/Permutation#Cycle_notation)):
+```
+(0 4 60 108 242 196)(1 168 138 16 197 29 57 21 22 169 37 74 205 33 56 5 10 124 12 40 8 70 18 6 185 137 224)(2 64 216 178 88)(3 14 98 142 128 30 102 44 158 34 72 38 50 68 28 154 46 156 254 41 218 204 161 194 65)(7 157 101 181 141 121 77 228 105 206 193 155 240 47 54 78 110 90 174 52 207 233 248 167 245 199 79 144 162 149 97
+140 111 126 170 139 175 119 189 171 215 55 89 81 23 134 106 251 83 15 173 250 147 217 115 229 99 107 223 39 244 246
+ 225 252 226 203 235 236 253 43 188 209 145 184 91 31 49 84 210 117 59 133 129 75 150 127 200 130 132 247 159 241
+255 71 120 63 249 201 212 131 95 222 238 125 237 109 186 213 151 176 143 202 179 232 103 148 191 239)(9 20 113 73 69 160 114 122 164 17 208 58 116 36 26 96 24)(11 80 32 152 146 82 53 62 66 76 86 51 112 221 27 163 180 214 123 219 234)
+(13 42 166 25 165)(19 172 177 230 198 45 61 104 136 100 182 85 153 35 192 48 220 94 190 118 195)(67)(87 92 93 227 211)(135)(183 243)(187)(231)
+```
+![circular](https://github.com/user-attachments/assets/3fa50405-1b4e-4679-a495-548850c4315b)
+
+## Security design in this implementatoin
+The overall security is equivalent to **1683-bit** symmetric encryption.
+
+The number of permutation matrices in an 8-qubit system is determined based on the provided seed and is selected randomly.
+
+
+The permutation pad could be written in [Cycle notation](https://en.wikipedia.org/wiki/Permutation#Cycle_notation) as: $\sigma =(1\ 2\ 255)(3\ 36)(4\ 82\ 125)(....)$, which the elements are not reversible by **XORing** twice like in other [stream ciphers](https://en.wikipedia.org/wiki/Stream_cipher_attacks).
+
+#### Locality vs. Randomness
+Random permutation disrupts [locality](https://en.wikipedia.org/wiki/Principle_of_locality), which is crucial for performance. To achieve higher encryption speed, we need to maintain some level of locality. In this design, instead of switching pads for every byte, we switch to a new random pad every 8 bytes.
+
+![349804164-3f6da444-a9f4-4d0a-b190-d59f2dca9f00](https://github.com/user-attachments/assets/2358766e-a0d3-4c21-93cb-c221aa0cece0)
+
+The diagram clearly demonstrates that switching pads for every byte results in low performance, whereas switching pads every 8 bytes yields adequate performance.
+
+Try directly from https://github.com/xtaci/kcptun/releases with the ```-QPP``` option enabled.
+
+#### Performance
+In modern CPUs, the latest QPP optimization can easily achieve speeds exceeding 1GB/s.
+![348621244-4061d4a9-e7fa-43f5-89ef-f6ef6c00a2e7](https://github.com/user-attachments/assets/78952157-df39-4088-b423-01f45548b782)
+
## Security consideration in setting PADs
-The number of pads is best to be coprime with 8.
+The number of pads should ideally be coprime with 8(與8互素), as the results indicate a hidden structure in the PRNG related to the number 8.
+
+![88d8de919445147f5d44ee059cca371](https://github.com/user-attachments/assets/9e1a160d-5433-4e24-9782-2ae88d87453d)
+
+We demonstrate encrypting the Bible with 64 pads and 15 pads below with real data(The Bible encrypted).
+
+**For Pads(64)**, then $GCD(64,8) == 8, \chi^2 =3818 $
+
+![348794146-4f6d5904-2663-46d7-870d-9fd7435df4d0](https://github.com/user-attachments/assets/e2a67bad-7d10-46e4-8d23-9866918ef04b)
-**Pads(64) GCD(64,8) == 8**
+**For Pads(15)**, then $GCD(15,8) == 1,\chi^2 =230$, **COPRIME!!!**
-![1721063372345](https://github.com/user-attachments/assets/4f6d5904-2663-46d7-870d-9fd7435df4d0)
+![348794204-accd3992-a56e-4059-a472-39ba5ad75660](https://github.com/user-attachments/assets/a6fd2cb8-7517-4627-8fd6-0cf29711b09d)
-**Pads(15) GCD(15,8) == 1**
+> Click here to learn more about the chi-square results for pad count selection: https://github.com/xtaci/qpp/blob/main/misc/chi-square.csv
-![image](https://github.com/user-attachments/assets/accd3992-a56e-4059-a472-39ba5ad75660)
As you can tell the difference from the **[Chi square distribution](https://en.wikipedia.org/wiki/Chi-squared_distribution)**, randomness has been enhanced by setting to numbers that are coprimes to 8.
diff --git a/vendor/github.com/xtaci/qpp/pkg.go b/vendor/github.com/xtaci/qpp/pkg.go
new file mode 100644
index 000000000..5907159d2
--- /dev/null
+++ b/vendor/github.com/xtaci/qpp/pkg.go
@@ -0,0 +1,16 @@
+// Package qpp implements Quantum permutation pad
+//
+// Quantum permutation pad or QPP is a quantum-safe symmetric cryptographic
+// algorithm proposed by Kuang and Bettenburg in 2020. The theoretical
+// foundation of QPP leverages the linear algebraic representations of
+// quantum gates which makes QPP realizable in both, quantum and classical
+// systems. By applying the QPP with 64 of 8-bit permutation gates, holding
+// respective entropy of over 100,000 bits, they accomplished quantum random
+// number distributions digitally over today’s classical internet. The QPP has
+// also been used to create pseudo quantum random numbers and served as a
+// foundation for quantum-safe lightweight block and streaming ciphers.
+//
+// This file implements QPP in 8-qubits, which is compatible with the classical
+// architecture. In 8-qubits, the overall permutation matrix reaches 256!.
+
+package qpp
diff --git a/vendor/github.com/xtaci/qpp/prng.go b/vendor/github.com/xtaci/qpp/prng.go
index 507037134..7db243134 100644
--- a/vendor/github.com/xtaci/qpp/prng.go
+++ b/vendor/github.com/xtaci/qpp/prng.go
@@ -1,3 +1,18 @@
+// # Copyright (c) 2024 xtaci
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
package qpp
// xorshift64star is a pseudo-random number generator that is part of the xorshift family of PRNGs.
diff --git a/vendor/github.com/xtaci/qpp/qpp.go b/vendor/github.com/xtaci/qpp/qpp.go
index 6d3a46bdc..eedbcf6ef 100644
--- a/vendor/github.com/xtaci/qpp/qpp.go
+++ b/vendor/github.com/xtaci/qpp/qpp.go
@@ -1,17 +1,18 @@
-// Package qpp implements Quantum permutation pad
+// # Copyright (c) 2024 xtaci
//
-// Quantum permutation pad or QPP is a quantum-safe symmetric cryptographic
-// algorithm proposed by Kuang and Bettenburg in 2020. The theoretical
-// foundation of QPP leverages the linear algebraic representations of
-// quantum gates which makes QPP realizable in both, quantum and classical
-// systems. By applying the QPP with 64 of 8-bit permutation gates, holding
-// respective entropy of over 100,000 bits, they accomplished quantum random
-// number distributions digitally over today’s classical internet. The QPP has
-// also been used to create pseudo quantum random numbers and served as a
-// foundation for quantum-safe lightweight block and streaming ciphers.
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
//
-// This file implements QPP in 8-qubits, which is compatible with the classical
-// architecture. In 8-qubits, the overall permutation matrix reaches 256!.
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
package qpp
import (
@@ -38,16 +39,15 @@ const (
PBKDF2_LOOPS = 128 // Number of iterations for PBKDF2
CHUNK_DERIVE_SALT = "___QUANTUM_PERMUTATION_PAD_SEED_DERIVE___"
CHUNK_DERIVE_LOOPS = 1024
- MAGIC = 0x1A2B3C4D5E6F7890
PAD_SWITCH = 8 // switch pad for every PAD_SWITCH bytes
QUBITS = 8 // number of quantum bits of this implementation
)
// Rand is a stateful random number generator
type Rand struct {
- xoshiro [4]uint64
- seed64 uint64
- count uint8
+ xoshiro [4]uint64 // xoshiro state
+ seed64 uint64 // the latest random number
+ count uint8 // number of bytes encrypted, counted in modular arithmetic
}
// QuantumPermutationPad represents the encryption/decryption structure using quantum permutation pads
@@ -98,8 +98,8 @@ func NewQPP(seed []byte, numPads uint16) *QuantumPermutationPad {
reverse(pad, rpad)
}
- qpp.encRand = qpp.CreatePRNG(seed) // Create default PRNG for encryption
- qpp.decRand = qpp.CreatePRNG(seed) // Create default PRNG for decryption
+ qpp.encRand = CreatePRNG(seed) // Create default PRNG for encryption
+ qpp.decRand = CreatePRNG(seed) // Create default PRNG for decryption
return qpp
}
@@ -118,7 +118,7 @@ func (qpp *QuantumPermutationPad) Decrypt(data []byte) {
// CreatePRNG creates a deterministic pseudo-random number generator based on the provided seed
// It uses HMAC and PBKDF2 to derive a random seed for the PRNG
-func (qpp *QuantumPermutationPad) CreatePRNG(seed []byte) *Rand {
+func CreatePRNG(seed []byte) *Rand {
mac := hmac.New(sha256.New, seed)
mac.Write([]byte(PM_SELECTOR_IDENTIFIER))
sum := mac.Sum(nil)
@@ -135,6 +135,21 @@ func (qpp *QuantumPermutationPad) CreatePRNG(seed []byte) *Rand {
return rd
}
+// FastPRNG creates a deterministic pseudo-random number generator based on the provided seed
+func FastPRNG(seed []byte) *Rand {
+ sha := sha256.New()
+ sum := sha.Sum(seed)
+
+ // Create and return PRNG
+ rd := &Rand{}
+ rd.xoshiro[0] = binary.LittleEndian.Uint64(sum[0:8])
+ rd.xoshiro[1] = binary.LittleEndian.Uint64(sum[8:16])
+ rd.xoshiro[2] = binary.LittleEndian.Uint64(sum[16:24])
+ rd.xoshiro[3] = binary.LittleEndian.Uint64(sum[24:32])
+ rd.seed64 = xoshiro256ss(&rd.xoshiro)
+ return rd
+}
+
// EncryptWithPRNG encrypts the data using the Quantum Permutation Pad with a custom PRNG
// This function shares the same permutation matrices
func (qpp *QuantumPermutationPad) EncryptWithPRNG(data []byte, rand *Rand) {
@@ -167,7 +182,7 @@ func (qpp *QuantumPermutationPad) EncryptWithPRNG(data []byte, rand *Rand) {
data = data[offset:] // aligned bytes start from here
}
- // handle 8-bytes aligned
+ // handle 8-bytes aligned, loop unrolling to improve performance(to mitigate data-dependency)
repeat := len(data) / 8
for i := 0; i < repeat; i++ {
d := data[i*8 : i*8+8]
@@ -303,8 +318,9 @@ func QPPMinimumPads(qubits uint8) int {
// fill initializes the pad with sequential byte values
// This sets up a standard permutation matrix before it is shuffled
func fill(pad []byte) {
- for i := 0; i < len(pad); i++ {
- pad[i] = byte(i)
+ pad[0] = 0
+ for i := 1; i < len(pad); i++ {
+ pad[i] = pad[i-1] + 1
}
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index dedef8b87..5ec73a46c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -47,7 +47,7 @@ github.com/urfave/cli
# github.com/xtaci/kcp-go/v5 v5.6.18
## explicit; go 1.21
github.com/xtaci/kcp-go/v5
-# github.com/xtaci/qpp v1.1.17
+# github.com/xtaci/qpp v1.1.18
## explicit; go 1.22.3
github.com/xtaci/qpp
# github.com/xtaci/smux v1.5.32