more docs
This commit is contained in:
parent
165cd07353
commit
f08653715b
@ -12,12 +12,48 @@ import net.sergeych.crypto2.Container.Companion.createWith
|
||||
* Multi-key encrypted container with simple adding new keys function that does not need to
|
||||
* know all existing keys, e.g., you can add recipients to the container data if you can
|
||||
* decrypt it. This is sometimes very important to be able to add recipients to the message
|
||||
* keeping existing recipients you know no keys of.
|
||||
* keeping existing recipients you know no keys of, or update the message when only one of the
|
||||
* keys is known.
|
||||
*
|
||||
* See:
|
||||
* - [createWith] for more on create a new container
|
||||
* - [addRecipients] and various [plus] operators to add recipients
|
||||
* - [decryptWith] to decrypt
|
||||
* - [addRecipients] and various [plus] operators to add recipients
|
||||
* - [updateData] to change decrypted content for the same recipient keys
|
||||
*
|
||||
* Some rules:
|
||||
*
|
||||
* When adding public key recipient, it is faster to use your known [Asymmetric.SecretKey], but you
|
||||
* can stay anonymous by just adding [Asymmetric.PublicKey] only.
|
||||
*
|
||||
* Put your data in [SealedBox] if you need to authenticate message origin and timestamp, then put
|
||||
* the sealed box in the [Container], this will conceal signers from attack. In the case you need to
|
||||
* prove message origin without disclosing its content, put the [Container] in the [SealedBox].
|
||||
* Everybody will see who and when have it signed, but only intended recipients could read it.
|
||||
*
|
||||
* Sample:
|
||||
* ```kotlin
|
||||
* // create container fpr p3.public key destination using our secret key (for speed)
|
||||
* var c = Container.createWith(data, p1.secretKey to p3.publicKey)
|
||||
*
|
||||
* // imitation of receiving an encrypted container in binary form
|
||||
* // so it is not decrypted
|
||||
* c = Container.decode(c.encoded)
|
||||
*
|
||||
* // decrypt it with the right key
|
||||
* c.decryptWith(p3.secretKey)
|
||||
*
|
||||
*
|
||||
* // add more keys to it: 2 symmetric, public anonymous, and secret-to-public pair (faster)
|
||||
* c = c + symmetricKey1 + symmetricKey2 + herPublicKey + (MySecretKey to hisPublicKey)
|
||||
*
|
||||
* // and update data in it (it will be encrypted too), adding random bytes, at least 100 and no
|
||||
* // more than 200, to make size analysis attack almost impossible
|
||||
* // in the 100 to 200
|
||||
* c = c..updateData(data2, 100..22)
|
||||
*
|
||||
* // now we can send it over the network
|
||||
* sendOVerTheNetwork(c.encoded)
|
||||
*```
|
||||
*/
|
||||
@Serializable
|
||||
sealed class Container {
|
||||
@ -83,6 +119,10 @@ sealed class Container {
|
||||
*/
|
||||
operator fun plus(pair: Pair<Asymmetric.SecretKey, Asymmetric.PublicKey>) = addRecipients { key(pair) }
|
||||
|
||||
/**
|
||||
* Update the data in the decrypted container. It keeps the same set of keys and update
|
||||
* the data only.
|
||||
*/
|
||||
abstract fun updateData(newPlainData: UByteArray,randomFill: IntRange?=null): Container
|
||||
|
||||
/**
|
||||
@ -241,17 +281,17 @@ sealed class Container {
|
||||
*
|
||||
* ```kotlin
|
||||
* Container.create(plainData) {
|
||||
* // optional: add a random filling from 10 to 20 bytes
|
||||
* fill( 10 .. 20 )
|
||||
* // optional: add a random filling from 10 to 20 bytes
|
||||
* fill( 10 .. 20 )
|
||||
*
|
||||
* key(symmetricKey1, symmetricKey2) // add two SymmetricKey recipients
|
||||
* key(symmetricKey1, symmetricKey2) // add two SymmetricKey recipients
|
||||
*
|
||||
* key(publicKey1) // add a Asymmetric.PublicKey recipient anonymously
|
||||
* key(publicKey1) // add a Asymmetric.PublicKey recipient anonymously
|
||||
*
|
||||
* // More interesting: add publicKey2 and publicKey3 recipients using my
|
||||
* // secret key as authority. IT is faster and allow to owner of the listed public keys
|
||||
* // to know it was me who added them to this container.
|
||||
* key(mySecretKey to publicKey2,mySecretKey to publicKey3)
|
||||
* // More interesting: add publicKey2 and publicKey3 recipients using my
|
||||
* // secret key as authority. IT is faster and allow to owner of the listed public keys
|
||||
* // to know it was me who added them to this container.
|
||||
* key(mySecretKey to publicKey2,mySecretKey to publicKey3)
|
||||
* }
|
||||
* ```
|
||||
|
||||
@ -380,17 +420,17 @@ sealed class Container {
|
||||
* Usage sample:
|
||||
* ```kotlin
|
||||
* Container.create(plainData) {
|
||||
* // optional: add a random filling from 10 to 20 bytes
|
||||
* fill( 10 .. 20 )
|
||||
* // optional: add a random filling from 10 to 20 bytes
|
||||
* fill( 10 .. 20 )
|
||||
*
|
||||
* key(symmetricKey1, symmetricKey2) // add two SymmetricKey recipients
|
||||
* key(symmetricKey1, symmetricKey2) // add two SymmetricKey recipients
|
||||
*
|
||||
* key(publicKey1) // add a Asymmetric.PublicKey recipient anonymously
|
||||
* key(publicKey1) // add a Asymmetric.PublicKey recipient anonymously
|
||||
*
|
||||
* // More interesting: add publicKey2 and publicKey3 recipients using my
|
||||
* // secret key as authority. IT is faster and allow to owner of the listed public keys
|
||||
* // to know it was me who added them to this container.
|
||||
* key(mySecretKey to publicKey2,mySecretKey to publicKey3)
|
||||
* // More interesting: add publicKey2 and publicKey3 recipients using my
|
||||
* // secret key as authority. IT is faster and allow to owner of the listed public keys
|
||||
* // to know it was me who added them to this container.
|
||||
* key(mySecretKey to publicKey2,mySecretKey to publicKey3)
|
||||
* }
|
||||
* ```
|
||||
* At least one key should be provided.
|
||||
|
@ -195,11 +195,8 @@ class ContainerTest {
|
||||
initCrypto()
|
||||
val syk1 = SymmetricKey.random()
|
||||
val syk2 = SymmetricKey.random()
|
||||
val syk3 = SymmetricKey.random()
|
||||
val p1 = Asymmetric.generateKeys()
|
||||
val p2 = Asymmetric.generateKeys()
|
||||
val p3 = Asymmetric.generateKeys()
|
||||
val p4 = Asymmetric.generateKeys()
|
||||
val data = "Translating the name 'Sergey Chernov' from Russian to archaic Sanskrit would be 'Ramo Krishna'"
|
||||
.encodeToUByteArray()
|
||||
|
||||
@ -273,6 +270,7 @@ class ContainerTest {
|
||||
val p2 = Asymmetric.generateKeys()
|
||||
val p3 = Asymmetric.generateKeys()
|
||||
val p4 = Asymmetric.generateKeys()
|
||||
val p5 = Asymmetric.generateKeys()
|
||||
val data = "Translating the name 'Sergey Chernov' from Russian to archaic Sanskrit would be 'Ramo Krishna'"
|
||||
.encodeToUByteArray()
|
||||
|
||||
@ -296,7 +294,7 @@ class ContainerTest {
|
||||
c.decryptWith(p3.secretKey)
|
||||
|
||||
val data2 = "Cocktails have a delicious, complex taste".encodeToUByteArray()
|
||||
c = (c + syk3 + (p1.secretKey to p4.publicKey)).updateData(data2)
|
||||
c = (c + syk3 + p5.publicKey + (p1.secretKey to p4.publicKey)).updateData(data2)
|
||||
expectNotOpen(syk2, syk1, p1.secretKey, p2.secretKey )
|
||||
expectOpen(data2, syk3, p3.secretKey, p4.secretKey)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user